69#include "llvm/IR/IntrinsicsPowerPC.h"
103#define DEBUG_TYPE "ppc-lowering"
106 "disable-p10-store-forward",
130 cl::desc(
"disable vector permute decomposition"),
134 "disable-auto-paired-vec-st",
135 cl::desc(
"disable automatically generated 32byte paired vector stores"),
140 cl::desc(
"Set minimum number of entries to use a jump table on PPC"));
144 cl::desc(
"max depth when checking alias info in GatherAllAliases()"));
148 cl::desc(
"Set inclusive limit count of TLS local-dynamic access(es) in a "
149 "function to use initial-exec"));
154 "Number of shuffles lowered to a VPERM or XXPERM");
155STATISTIC(NumDynamicAllocaProbed,
"Number of dynamic stack allocation probed");
178 initializeAddrModeMap();
181 bool isPPC64 = Subtarget.
isPPC64();
191 if (!Subtarget.hasEFPU2())
203 if (!Subtarget.hasP10Vector()) {
226 if (Subtarget.isISA3_0()) {
256 if (!Subtarget.hasSPE()) {
264 const MVT ScalarIntVTs[] = { MVT::i32, MVT::i64 };
265 for (
MVT VT : ScalarIntVTs) {
272 if (Subtarget.useCRBits()) {
275 if (isPPC64 || Subtarget.hasFPCVT()) {
341 if (Subtarget.isISA3_0()) {
376 if (!Subtarget.hasSPE()) {
381 if (Subtarget.hasVSX()) {
386 if (Subtarget.hasFSQRT()) {
391 if (Subtarget.hasFPRND()) {
432 if (Subtarget.hasSPE()) {
442 if (Subtarget.hasSPE())
446 if (!Subtarget.hasFSQRT() &&
447 !(TM.Options.UnsafeFPMath && Subtarget.hasFRSQRTE() &&
451 if (!Subtarget.hasFSQRT() &&
452 !(TM.Options.UnsafeFPMath && Subtarget.hasFRSQRTES() &&
453 Subtarget.hasFRES()))
456 if (Subtarget.hasFCPSGN()) {
464 if (Subtarget.hasFPRND()) {
478 if (Subtarget.isISA3_1()) {
484 (Subtarget.hasP9Vector() && isPPC64) ?
Custom :
Expand);
488 if (Subtarget.isISA3_0()) {
508 if (!Subtarget.useCRBits()) {
521 if (!Subtarget.useCRBits())
524 if (Subtarget.hasFPU()) {
535 if (!Subtarget.useCRBits())
540 if (Subtarget.hasSPE()) {
564 if (Subtarget.hasDirectMove() && isPPC64) {
569 if (TM.Options.UnsafeFPMath) {
672 if (Subtarget.hasSPE()) {
694 if (Subtarget.has64BitSupport()) {
709 if (Subtarget.hasLFIWAX() || isPPC64) {
715 if (Subtarget.hasSPE()) {
725 if (Subtarget.hasFPCVT()) {
726 if (Subtarget.has64BitSupport()) {
747 if (Subtarget.use64BitRegs()) {
765 if (Subtarget.has64BitSupport()) {
772 if (Subtarget.hasVSX()) {
779 if (Subtarget.hasAltivec()) {
780 for (
MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
795 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
808 if (Subtarget.hasVSX()) {
814 if (Subtarget.hasP8Altivec() && (VT.SimpleTy != MVT::v1i128)) {
824 if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
898 if (!Subtarget.hasP8Vector()) {
940 if (Subtarget.hasAltivec())
941 for (
auto VT : {MVT::v4i32, MVT::v8i16, MVT::v16i8})
944 if (Subtarget.hasP8Altivec())
955 if (Subtarget.hasVSX()) {
961 if (Subtarget.hasP8Altivec())
966 if (Subtarget.isISA3_1()) {
1012 if (Subtarget.hasVSX()) {
1015 if (Subtarget.hasP8Vector()) {
1019 if (Subtarget.hasDirectMove() && isPPC64) {
1033 if (TM.Options.UnsafeFPMath) {
1070 if (Subtarget.hasP8Vector())
1079 if (Subtarget.hasP8Altivec()) {
1106 if (Subtarget.isISA3_1())
1209 if (Subtarget.hasP8Altivec()) {
1214 if (Subtarget.hasP9Vector()) {
1219 if (Subtarget.useCRBits()) {
1279 }
else if (Subtarget.hasVSX()) {
1304 for (
MVT VT : {MVT::f32, MVT::f64}) {
1323 if (Subtarget.hasP9Altivec()) {
1324 if (Subtarget.isISA3_1()) {
1347 if (Subtarget.hasP10Vector()) {
1352 if (Subtarget.pairedVectorMemops()) {
1357 if (Subtarget.hasMMA()) {
1358 if (Subtarget.isISAFuture())
1367 if (Subtarget.has64BitSupport())
1370 if (Subtarget.isISA3_1())
1388 if (Subtarget.hasAltivec()) {
1405 if (Subtarget.hasFPCVT())
1408 if (Subtarget.useCRBits())
1417 if (Subtarget.useCRBits()) {
1448 setLibcallName(RTLIB::MEMCPY, isPPC64 ?
"___memmove64" :
"___memmove");
1449 setLibcallName(RTLIB::MEMMOVE, isPPC64 ?
"___memmove64" :
"___memmove");
1450 setLibcallName(RTLIB::MEMSET, isPPC64 ?
"___memset64" :
"___memset");
1451 setLibcallName(RTLIB::BZERO, isPPC64 ?
"___bzero64" :
"___bzero");
1456 if (Subtarget.useCRBits()) {
1562void PPCTargetLowering::initializeAddrModeMap() {
1613 if (MaxAlign == MaxMaxAlign)
1615 if (
VectorType *VTy = dyn_cast<VectorType>(Ty)) {
1616 if (MaxMaxAlign >= 32 &&
1617 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1618 MaxAlign =
Align(32);
1619 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1621 MaxAlign =
Align(16);
1622 }
else if (
ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
1625 if (EltAlign > MaxAlign)
1626 MaxAlign = EltAlign;
1627 }
else if (
StructType *STy = dyn_cast<StructType>(Ty)) {
1628 for (
auto *EltTy : STy->elements()) {
1631 if (EltAlign > MaxAlign)
1632 MaxAlign = EltAlign;
1633 if (MaxAlign == MaxMaxAlign)
1646 if (Subtarget.hasAltivec())
1656 return Subtarget.hasSPE();
1664 Type *VectorTy,
unsigned ElemSizeInBits,
unsigned &Index)
const {
1665 if (!Subtarget.
isPPC64() || !Subtarget.hasVSX())
1668 if (
auto *VTy = dyn_cast<VectorType>(VectorTy)) {
1669 if (VTy->getScalarType()->isIntegerTy()) {
1671 if (ElemSizeInBits == 32) {
1675 if (ElemSizeInBits == 64) {
1701 return "PPCISD::FTSQRT";
1703 return "PPCISD::FSQRT";
1708 return "PPCISD::XXSPLTI_SP_TO_DP";
1710 return "PPCISD::XXSPLTI32DX";
1714 return "PPCISD::XXPERM";
1734 return "PPCISD::CALL_RM";
1736 return "PPCISD::CALL_NOP_RM";
1738 return "PPCISD::CALL_NOTOC_RM";
1743 return "PPCISD::BCTRL_RM";
1745 return "PPCISD::BCTRL_LOAD_TOC_RM";
1757 return "PPCISD::SCALAR_TO_VECTOR_PERMUTED";
1759 return "PPCISD::ANDI_rec_1_EQ_BIT";
1761 return "PPCISD::ANDI_rec_1_GT_BIT";
1776 return "PPCISD::ST_VSR_SCAL_INT";
1805 return "PPCISD::PADDI_DTPREL";
1821 return "PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR";
1823 return "PPCISD::TLS_LOCAL_EXEC_MAT_ADDR";
1833 return "PPCISD::STRICT_FADDRTZ";
1835 return "PPCISD::STRICT_FCTIDZ";
1837 return "PPCISD::STRICT_FCTIWZ";
1839 return "PPCISD::STRICT_FCTIDUZ";
1841 return "PPCISD::STRICT_FCTIWUZ";
1843 return "PPCISD::STRICT_FCFID";
1845 return "PPCISD::STRICT_FCFIDU";
1847 return "PPCISD::STRICT_FCFIDS";
1849 return "PPCISD::STRICT_FCFIDUS";
1852 return "PPCISD::STORE_COND";
1854 return "PPCISD::SETBC";
1856 return "PPCISD::SETBCR";
1864 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1881 return CFP->getValueAPF().isZero();
1885 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
1886 return CFP->getValueAPF().isZero();
1894 return Op < 0 ||
Op == Val;
1906 if (ShuffleKind == 0) {
1909 for (
unsigned i = 0; i != 16; ++i)
1912 }
else if (ShuffleKind == 2) {
1915 for (
unsigned i = 0; i != 16; ++i)
1918 }
else if (ShuffleKind == 1) {
1919 unsigned j = IsLE ? 0 : 1;
1920 for (
unsigned i = 0; i != 8; ++i)
1937 if (ShuffleKind == 0) {
1940 for (
unsigned i = 0; i != 16; i += 2)
1944 }
else if (ShuffleKind == 2) {
1947 for (
unsigned i = 0; i != 16; i += 2)
1951 }
else if (ShuffleKind == 1) {
1952 unsigned j = IsLE ? 0 : 2;
1953 for (
unsigned i = 0; i != 8; i += 2)
1974 if (!Subtarget.hasP8Vector())
1978 if (ShuffleKind == 0) {
1981 for (
unsigned i = 0; i != 16; i += 4)
1987 }
else if (ShuffleKind == 2) {
1990 for (
unsigned i = 0; i != 16; i += 4)
1996 }
else if (ShuffleKind == 1) {
1997 unsigned j = IsLE ? 0 : 4;
1998 for (
unsigned i = 0; i != 8; i += 4)
2015 unsigned LHSStart,
unsigned RHSStart) {
2016 if (
N->getValueType(0) != MVT::v16i8)
2018 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
2019 "Unsupported merge size!");
2021 for (
unsigned i = 0; i != 8/UnitSize; ++i)
2022 for (
unsigned j = 0; j != UnitSize; ++j) {
2024 LHSStart+j+i*UnitSize) ||
2026 RHSStart+j+i*UnitSize))
2041 if (ShuffleKind == 1)
2043 else if (ShuffleKind == 2)
2048 if (ShuffleKind == 1)
2050 else if (ShuffleKind == 0)
2066 if (ShuffleKind == 1)
2068 else if (ShuffleKind == 2)
2073 if (ShuffleKind == 1)
2075 else if (ShuffleKind == 0)
2125 unsigned RHSStartValue) {
2126 if (
N->getValueType(0) != MVT::v16i8)
2129 for (
unsigned i = 0; i < 2; ++i)
2130 for (
unsigned j = 0; j < 4; ++j)
2132 i*RHSStartValue+j+IndexOffset) ||
2134 i*RHSStartValue+j+IndexOffset+8))
2156 unsigned indexOffset = CheckEven ? 4 : 0;
2157 if (ShuffleKind == 1)
2159 else if (ShuffleKind == 2)
2165 unsigned indexOffset = CheckEven ? 0 : 4;
2166 if (ShuffleKind == 1)
2168 else if (ShuffleKind == 0)
2184 if (
N->getValueType(0) != MVT::v16i8)
2191 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2194 if (i == 16)
return -1;
2199 if (ShiftAmt < i)
return -1;
2204 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2206 for (++i; i != 16; ++i)
2209 }
else if (ShuffleKind == 1) {
2211 for (++i; i != 16; ++i)
2218 ShiftAmt = 16 - ShiftAmt;
2227 EVT VT =
N->getValueType(0);
2228 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2229 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2232 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2236 if (
N->getMaskElt(0) % EltSize != 0)
2241 unsigned ElementBase =
N->getMaskElt(0);
2244 if (ElementBase >= 16)
2249 for (
unsigned i = 1; i != EltSize; ++i)
2250 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2253 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2254 if (
N->getMaskElt(i) < 0)
continue;
2255 for (
unsigned j = 0; j != EltSize; ++j)
2256 if (
N->getMaskElt(i+j) !=
N->getMaskElt(j))
2273 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2274 "Unexpected element width.");
2275 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2277 unsigned NumOfElem = 16 / Width;
2278 unsigned MaskVal[16];
2279 for (
unsigned i = 0; i < NumOfElem; ++i) {
2280 MaskVal[0] =
N->getMaskElt(i * Width);
2281 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2283 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2287 for (
unsigned int j = 1; j < Width; ++j) {
2288 MaskVal[j] =
N->getMaskElt(i * Width + j);
2289 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2299 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2304 unsigned M0 =
N->getMaskElt(0) / 4;
2305 unsigned M1 =
N->getMaskElt(4) / 4;
2306 unsigned M2 =
N->getMaskElt(8) / 4;
2307 unsigned M3 =
N->getMaskElt(12) / 4;
2308 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2309 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2314 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2315 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2316 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2317 InsertAtByte = IsLE ? 12 : 0;
2322 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2323 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2324 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2325 InsertAtByte = IsLE ? 8 : 4;
2330 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2331 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2332 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2333 InsertAtByte = IsLE ? 4 : 8;
2338 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2339 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2340 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2341 InsertAtByte = IsLE ? 0 : 12;
2348 if (
N->getOperand(1).isUndef()) {
2351 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2352 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2353 InsertAtByte = IsLE ? 12 : 0;
2356 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2357 InsertAtByte = IsLE ? 8 : 4;
2360 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2361 InsertAtByte = IsLE ? 4 : 8;
2364 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2365 InsertAtByte = IsLE ? 0 : 12;
2374 bool &Swap,
bool IsLE) {
2375 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2381 unsigned M0 =
N->getMaskElt(0) / 4;
2382 unsigned M1 =
N->getMaskElt(4) / 4;
2383 unsigned M2 =
N->getMaskElt(8) / 4;
2384 unsigned M3 =
N->getMaskElt(12) / 4;
2388 if (
N->getOperand(1).isUndef()) {
2389 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2390 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2393 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2399 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2403 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2408 ShiftElts = (8 -
M0) % 8;
2409 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2414 ShiftElts = (4 -
M0) % 4;
2419 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2424 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2436 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2441 for (
int i = 0; i < 16; i += Width)
2442 if (
N->getMaskElt(i) != i + Width - 1)
2473 bool &Swap,
bool IsLE) {
2474 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2480 unsigned M0 =
N->getMaskElt(0) / 8;
2481 unsigned M1 =
N->getMaskElt(8) / 8;
2482 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2486 if (
N->getOperand(1).isUndef()) {
2487 if ((
M0 |
M1) < 2) {
2488 DM = IsLE ? (((~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2496 if (
M0 > 1 &&
M1 < 2) {
2498 }
else if (M0 < 2 && M1 > 1) {
2506 DM = (((~M1) & 1) << 1) + ((~
M0) & 1);
2509 if (M0 < 2 && M1 > 1) {
2511 }
else if (
M0 > 1 &&
M1 < 2) {
2519 DM = (
M0 << 1) + (
M1 & 1);
2534 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2539 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2555 unsigned EltSize = 16/
N->getNumOperands();
2556 if (EltSize < ByteSize) {
2557 unsigned Multiple = ByteSize/EltSize;
2559 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2562 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2563 if (
N->getOperand(i).isUndef())
continue;
2565 if (!isa<ConstantSDNode>(
N->getOperand(i)))
return SDValue();
2567 if (!UniquedVals[i&(Multiple-1)].
getNode())
2568 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2569 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2579 bool LeadingZero =
true;
2580 bool LeadingOnes =
true;
2581 for (
unsigned i = 0; i != Multiple-1; ++i) {
2582 if (!UniquedVals[i].
getNode())
continue;
2589 if (!UniquedVals[Multiple-1].
getNode())
2596 if (!UniquedVals[Multiple-1].
getNode())
2598 int Val =cast<ConstantSDNode>(UniquedVals[Multiple-1])->getSExtValue();
2607 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2608 if (
N->getOperand(i).isUndef())
continue;
2610 OpVal =
N->getOperand(i);
2611 else if (OpVal !=
N->getOperand(i))
2617 unsigned ValSizeInBytes = EltSize;
2620 Value = CN->getZExtValue();
2622 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2623 Value = llvm::bit_cast<uint32_t>(CN->getValueAPF().convertToFloat());
2629 if (ValSizeInBytes < ByteSize)
return SDValue();
2640 if (MaskVal == 0)
return SDValue();
2643 if (SignExtend32<5>(MaskVal) == MaskVal)
2657 if (!isa<ConstantSDNode>(
N))
2660 Imm = (int16_t)
N->getAsZExtVal();
2661 if (
N->getValueType(0) == MVT::i32)
2662 return Imm == (int32_t)
N->getAsZExtVal();
2664 return Imm == (int64_t)
N->getAsZExtVal();
2682 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2690 for (
SDNode *U :
N->users()) {
2691 if (
MemSDNode *Memop = dyn_cast<MemSDNode>(U)) {
2692 if (Memop->getMemoryVT() == MVT::f64) {
2693 Base =
N.getOperand(0);
2694 Index =
N.getOperand(1);
2706 if (!isa<ConstantSDNode>(
N))
2709 Imm = (int64_t)cast<ConstantSDNode>(
N)->getSExtValue();
2710 return isInt<34>(Imm);
2737 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2742 Base =
N.getOperand(0);
2743 Index =
N.getOperand(1);
2745 }
else if (
N.getOpcode() ==
ISD::OR) {
2747 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2759 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2760 Base =
N.getOperand(0);
2761 Index =
N.getOperand(1);
2831 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2837 Base =
N.getOperand(0);
2840 }
else if (
N.getOperand(1).getOpcode() ==
PPCISD::Lo) {
2842 assert(!
N.getOperand(1).getConstantOperandVal(1) &&
2843 "Cannot handle constant offsets yet!");
2844 Disp =
N.getOperand(1).getOperand(0);
2849 Base =
N.getOperand(0);
2852 }
else if (
N.getOpcode() ==
ISD::OR) {
2855 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2865 dyn_cast<FrameIndexSDNode>(
N.getOperand(0))) {
2869 Base =
N.getOperand(0);
2882 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm))) {
2885 CN->getValueType(0));
2890 if ((CN->getValueType(0) == MVT::i32 ||
2891 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2892 (!EncodingAlignment ||
2893 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2894 int Addr = (int)CN->getZExtValue();
2901 unsigned Opc = CN->
getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2922 if (
N.getValueType() != MVT::i64)
2935 Base =
N.getOperand(0);
2951 Base =
N.getOperand(0);
2984 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2985 Base =
N.getOperand(0);
2986 Index =
N.getOperand(1);
2998 Ty *PCRelCand = dyn_cast<Ty>(
N);
3010 if (isValidPCRelNode<ConstantPoolSDNode>(
N) ||
3011 isValidPCRelNode<GlobalAddressSDNode>(
N) ||
3012 isValidPCRelNode<JumpTableSDNode>(
N) ||
3013 isValidPCRelNode<BlockAddressSDNode>(
N))
3029 EVT MemVT = LD->getMemoryVT();
3036 if (!ST.hasP8Vector())
3041 if (!ST.hasP9Vector())
3053 if (
Use.getResNo() == 0 &&
3075 Ptr = LD->getBasePtr();
3076 VT = LD->getMemoryVT();
3077 Alignment = LD->getAlign();
3078 }
else if (
StoreSDNode *ST = dyn_cast<StoreSDNode>(
N)) {
3079 Ptr = ST->getBasePtr();
3080 VT = ST->getMemoryVT();
3081 Alignment = ST->getAlign();
3104 if (isa<FrameIndexSDNode>(
Base) || isa<RegisterSDNode>(
Base))
3107 SDValue Val = cast<StoreSDNode>(
N)->getValue();
3120 if (VT != MVT::i64) {
3125 if (Alignment <
Align(4))
3135 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
3137 isa<ConstantSDNode>(
Offset))
3152 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3208 EVT PtrVT =
Op.getValueType();
3224 return getTOCEntry(DAG,
SDLoc(CP), GA);
3227 unsigned MOHiFlag, MOLoFlag;
3234 return getTOCEntry(DAG,
SDLoc(CP), GA);
3294 EVT PtrVT =
Op.getValueType();
3312 return getTOCEntry(DAG,
SDLoc(JT), GA);
3315 unsigned MOHiFlag, MOLoFlag;
3322 return getTOCEntry(DAG,
SDLoc(GA), GA);
3332 EVT PtrVT =
Op.getValueType();
3351 return getTOCEntry(DAG,
SDLoc(BASDN), GA);
3360 unsigned MOHiFlag, MOLoFlag;
3371 return LowerGlobalTLSAddressAIX(
Op, DAG);
3373 return LowerGlobalTLSAddressLinux(
Op, DAG);
3395 if (
I.getOpcode() == Instruction::Call)
3396 if (
const CallInst *CI = dyn_cast<const CallInst>(&
I))
3397 if (
Function *CF = CI->getCalledFunction())
3398 if (CF->isDeclaration() &&
3399 CF->getIntrinsicID() == Intrinsic::threadlocal_address)
3401 dyn_cast<GlobalValue>(
I.getOperand(0))) {
3407 unsigned TLSGVCnt = TLSGV.
size();
3417 <<
" function is using the TLS-IE model for TLS-LD access.\n");
3432 bool Is64Bit = Subtarget.
isPPC64();
3436 if (Subtarget.hasAIXShLibTLSModelOpt())
3446 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3447 bool HasAIXSmallTLSGlobalAttr =
false;
3450 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3454 if (GVar->hasAttribute(
"aix-small-tls"))
3455 HasAIXSmallTLSGlobalAttr =
true;
3474 if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) &&
3475 IsTLSLocalExecModel) {
3495 if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr)
3497 "currently only supported on AIX (64-bit mode).");
3503 bool HasAIXSmallLocalDynamicTLS = Subtarget.hasAIXSmallLocalDynamicTLS();
3507 if (!Is64Bit && HasAIXSmallLocalDynamicTLS)
3509 "currently only supported on AIX (64-bit mode).");
3517 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3521 dyn_cast_or_null<GlobalVariable>(
M->getOrInsertGlobal(
3524 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3527 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3538 if (HasAIXSmallLocalDynamicTLS) {
3547 return DAG.
getNode(
ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
3560 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3561 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3579 bool is64bit = Subtarget.
isPPC64();
3626 if (!
TM.isPositionIndependent())
3685 PtrVT, GOTPtr, TGA, TGA);
3687 PtrVT, TLSAddr, TGA);
3696 EVT PtrVT =
Op.getValueType();
3721 return getTOCEntry(DAG,
DL, GA);
3724 unsigned MOHiFlag, MOLoFlag;
3732 return getTOCEntry(DAG,
DL, GA);
3744 bool IsStrict =
Op->isStrictFPOpcode();
3746 cast<CondCodeSDNode>(
Op.getOperand(IsStrict ? 3 : 2))->get();
3750 EVT LHSVT =
LHS.getValueType();
3754 if (LHSVT == MVT::f128) {
3755 assert(!Subtarget.hasP9Vector() &&
3756 "SETCC for f128 is already legal under Power9!");
3767 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3769 if (
Op.getValueType() == MVT::v2i64) {
3772 if (
LHS.getValueType() == MVT::v2i64) {
3780 int ShuffV[] = {1, 0, 3, 2};
3785 dl, MVT::v4i32, Shuff, SetCC32));
3802 if (
C->isAllOnes() ||
C->isZero())
3812 EVT VT =
Op.getValueType();
3821 EVT VT =
Node->getValueType(0);
3825 const Value *SV = cast<SrcValueSDNode>(
Node->getOperand(2))->getValue();
3835 if (VT == MVT::i64) {
3866 InChain = OverflowArea.
getValue(1);
3912 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3919 assert(!Subtarget.
isPPC64() &&
"LowerVACOPY is PPC32 only");
3925 false,
true,
nullptr, std::nullopt,
3934 return Op.getOperand(0);
3943 "Expecting Inline ASM node.");
3953 if (
Op.getOperand(NumOps - 1).getValueType() == MVT::Glue)
3959 unsigned NumVals =
Flags.getNumOperandRegisters();
3962 switch (
Flags.getKind()) {
3973 for (; NumVals; --NumVals, ++i) {
3974 Register Reg = cast<RegisterSDNode>(
Op.getOperand(i))->getReg();
3975 if (Reg != PPC::LR && Reg != PPC::LR8)
4000 bool isPPC64 = (PtrVT == MVT::i64);
4006 Entry.Ty = IntPtrTy;
4007 Entry.Node = Trmp;
Args.push_back(Entry);
4012 Args.push_back(Entry);
4014 Entry.Node = FPtr;
Args.push_back(Entry);
4015 Entry.Node = Nest;
Args.push_back(Entry);
4019 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
4023 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
4024 return CallResult.second;
4038 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
4039 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
4074 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
4083 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
4098 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
4101 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
4103 nextOffset += FrameOffset;
4104 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
4107 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
4113static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
4114 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
4115 PPC::F11, PPC::F12, PPC::F13};
4120 unsigned PtrByteSize) {
4122 if (Flags.isByVal())
4123 ArgSize = Flags.getByValSize();
4127 if (!Flags.isInConsecutiveRegs())
4128 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4137 unsigned PtrByteSize) {
4138 Align Alignment(PtrByteSize);
4141 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4142 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4143 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4144 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4145 Alignment =
Align(16);
4148 if (Flags.isByVal()) {
4149 auto BVAlign = Flags.getNonZeroByValAlign();
4150 if (BVAlign > PtrByteSize) {
4151 if (BVAlign.value() % PtrByteSize != 0)
4153 "ByVal alignment is not a multiple of the pointer size");
4155 Alignment = BVAlign;
4160 if (Flags.isInConsecutiveRegs()) {
4164 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4178 unsigned PtrByteSize,
unsigned LinkageSize,
4179 unsigned ParamAreaSize,
unsigned &ArgOffset,
4180 unsigned &AvailableFPRs,
4181 unsigned &AvailableVRs) {
4182 bool UseMemory =
false;
4187 ArgOffset =
alignTo(ArgOffset, Alignment);
4190 if (ArgOffset >= LinkageSize + ParamAreaSize)
4195 if (Flags.isInConsecutiveRegsLast())
4196 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4199 if (ArgOffset > LinkageSize + ParamAreaSize)
4204 if (!Flags.isByVal()) {
4205 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4206 if (AvailableFPRs > 0) {
4210 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4211 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4212 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4213 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4214 if (AvailableVRs > 0) {
4226 unsigned NumBytes) {
4230SDValue PPCTargetLowering::LowerFormalArguments(
4235 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4238 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4241 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4245SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4287 const Align PtrAlign(4);
4296 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4298 CCInfo.PreAnalyzeFormalArguments(Ins);
4301 CCInfo.clearWasPPCF128();
4303 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4316 RC = &PPC::GPRCRegClass;
4319 if (Subtarget.hasP8Vector())
4320 RC = &PPC::VSSRCRegClass;
4321 else if (Subtarget.hasSPE())
4322 RC = &PPC::GPRCRegClass;
4324 RC = &PPC::F4RCRegClass;
4327 if (Subtarget.hasVSX())
4328 RC = &PPC::VSFRCRegClass;
4329 else if (Subtarget.hasSPE())
4331 RC = &PPC::GPRCRegClass;
4333 RC = &PPC::F8RCRegClass;
4338 RC = &PPC::VRRCRegClass;
4341 RC = &PPC::VRRCRegClass;
4345 RC = &PPC::VRRCRegClass;
4352 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4353 assert(i + 1 < e &&
"No second half of double precision argument");
4365 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4366 if (ValVT == MVT::i1)
4381 ArgOffset += ArgSize - ObjSize;
4399 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4404 unsigned MinReservedArea = CCByValInfo.getStackSize();
4405 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4421 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4422 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4424 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4427 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4430 unsigned NumFPArgRegs = std::size(FPArgRegs);
4439 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4443 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4452 for (
unsigned GPRIndex = 0; GPRIndex != NumGPArgRegs; ++GPRIndex) {
4456 VReg = MF.
addLiveIn(GPArgRegs[GPRIndex], &PPC::GPRCRegClass);
4471 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4475 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4488 if (!MemOps.
empty())
4499 const SDLoc &dl)
const {
4503 else if (
Flags.isZExt())
4510SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4523 "fastcc not supported on varargs functions");
4529 unsigned PtrByteSize = 8;
4533 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4534 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4537 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4538 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4541 const unsigned Num_GPR_Regs = std::size(GPR);
4543 const unsigned Num_VR_Regs = std::size(VR);
4551 bool HasParameterArea = !isELFv2ABI || isVarArg;
4552 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4553 unsigned NumBytes = LinkageSize;
4554 unsigned AvailableFPRs = Num_FPR_Regs;
4555 unsigned AvailableVRs = Num_VR_Regs;
4556 for (
unsigned i = 0, e =
Ins.size(); i != e; ++i) {
4557 if (Ins[i].
Flags.isNest())
4561 PtrByteSize, LinkageSize, ParamAreaSize,
4562 NumBytes, AvailableFPRs, AvailableVRs))
4563 HasParameterArea =
true;
4570 unsigned ArgOffset = LinkageSize;
4571 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4574 unsigned CurArgIdx = 0;
4575 for (
unsigned ArgNo = 0, e =
Ins.size(); ArgNo != e; ++ArgNo) {
4577 bool needsLoad =
false;
4578 EVT ObjectVT =
Ins[ArgNo].VT;
4579 EVT OrigVT =
Ins[ArgNo].ArgVT;
4581 unsigned ArgSize = ObjSize;
4583 if (Ins[ArgNo].isOrigArg()) {
4584 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4585 CurArgIdx =
Ins[ArgNo].getOrigArgIndex();
4590 unsigned CurArgOffset;
4592 auto ComputeArgOffset = [&]() {
4596 ArgOffset =
alignTo(ArgOffset, Alignment);
4597 CurArgOffset = ArgOffset;
4604 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4605 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4610 if (
Flags.isByVal()) {
4611 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4617 ObjSize =
Flags.getByValSize();
4618 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4640 if (HasParameterArea ||
4641 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4648 if (ObjSize < PtrByteSize) {
4652 if (!isLittleEndian) {
4658 if (GPR_idx != Num_GPR_Regs) {
4670 ArgOffset += PtrByteSize;
4679 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4680 if (GPR_idx == Num_GPR_Regs)
4691 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4699 ArgOffset += ArgSize;
4708 if (
Flags.isNest()) {
4713 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4714 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4722 if (GPR_idx != Num_GPR_Regs) {
4727 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4730 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4736 ArgSize = PtrByteSize;
4747 if (FPR_idx != Num_FPR_Regs) {
4750 if (ObjectVT == MVT::f32)
4752 Subtarget.hasP8Vector()
4753 ? &PPC::VSSRCRegClass
4754 : &PPC::F4RCRegClass);
4757 ? &PPC::VSFRCRegClass
4758 : &PPC::F8RCRegClass);
4773 if (ObjectVT == MVT::f32) {
4774 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4792 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4793 ArgOffset += ArgSize;
4794 if (
Flags.isInConsecutiveRegsLast())
4795 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4809 if (VR_idx != Num_VR_Regs) {
4826 if (ObjSize < ArgSize && !isLittleEndian)
4827 CurArgOffset += ArgSize - ObjSize;
4837 unsigned MinReservedArea;
4838 if (HasParameterArea)
4839 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4841 MinReservedArea = LinkageSize;
4858 int Depth = ArgOffset;
4867 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4868 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4880 if (!MemOps.
empty())
4889 unsigned ParamSize) {
4891 if (!isTailCall)
return 0;
4895 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4897 if (SPDiff < FI->getTailCallSPDelta())
4913 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4926 if (!TM.shouldAssumeDSOLocal(CalleeGV))
4932 const Function *
F = dyn_cast<Function>(CalleeGV);
4933 const GlobalAlias *Alias = dyn_cast<GlobalAlias>(CalleeGV);
4938 F = dyn_cast<Function>(GlobalObj);
4971 if (TM.getFunctionSections() || CalleeGV->
hasComdat() ||
4972 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
4974 if (
const auto *
F = dyn_cast<Function>(CalleeGV)) {
4975 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4987 const unsigned PtrByteSize = 8;
4991 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4992 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4995 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4996 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4999 const unsigned NumGPRs = std::size(GPR);
5000 const unsigned NumFPRs = 13;
5001 const unsigned NumVRs = std::size(VR);
5002 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
5004 unsigned NumBytes = LinkageSize;
5005 unsigned AvailableFPRs = NumFPRs;
5006 unsigned AvailableVRs = NumVRs;
5009 if (Param.Flags.isNest())
continue;
5012 LinkageSize, ParamAreaSize, NumBytes,
5013 AvailableFPRs, AvailableVRs))
5024 auto CalleeArgEnd = CB.
arg_end();
5027 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
5028 const Value* CalleeArg = *CalleeArgIter;
5029 const Value* CallerArg = &(*CallerArgIter);
5030 if (CalleeArg == CallerArg)
5038 isa<UndefValue>(CalleeArg))
5056 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
5066bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
5071 bool isCalleeExternalSymbol)
const {
5074 if (
DisableSCO && !TailCallOpt)
return false;
5077 if (isVarArg)
return false;
5153bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5187 if (!
C)
return nullptr;
5189 int Addr =
C->getZExtValue();
5190 if ((
Addr & 3) != 0 ||
5196 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5203struct TailCallArgumentInfo {
5208 TailCallArgumentInfo() =
default;
5218 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5219 SDValue Arg = TailCallArgs[i].Arg;
5220 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5221 int FI = TailCallArgs[i].FrameIdx;
5224 Chain, dl, Arg, FIN,
5233 int SPDiff,
const SDLoc &dl) {
5239 int SlotSize = Subtarget.
isPPC64() ? 8 : 4;
5240 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5242 NewRetAddrLoc,
true);
5245 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5255 int SPDiff,
unsigned ArgOffset,
5257 int Offset = ArgOffset + SPDiff;
5260 EVT VT = IsPPC64 ? MVT::i64 : MVT::i32;
5262 TailCallArgumentInfo
Info;
5264 Info.FrameIdxOp = FIN;
5272SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5277 LROpOut = getReturnAddrFrameIndex(DAG);
5296 Chain, dl, Dst, Src, SizeNode, Flags.getNonZeroByValAlign(),
false,
false,
5304 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5328 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5338 if (!MemOpChains2.
empty())
5362SDValue PPCTargetLowering::LowerCallResult(
5370 CCRetInfo.AnalyzeCallResult(
5376 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5382 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5385 Chain =
Lo.getValue(1);
5386 InGlue =
Lo.getValue(2);
5390 Chain =
Hi.getValue(1);
5391 InGlue =
Hi.getValue(2);
5428 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5460 bool IsStrictFPCall =
false) {
5464 unsigned RetOpc = 0;
5489 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5495 if (IsStrictFPCall) {
5526 auto isLocalCallee = [&]() {
5531 !isa_and_nonnull<GlobalIFunc>(GV);
5542 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5552 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5555 const GlobalValue *GV = cast<GlobalAddressSDNode>(Callee)->getGlobal();
5558 assert(!isa<GlobalIFunc>(GV) &&
"IFunc is not supported on AIX.");
5559 return getAIXFuncEntryPointSymbolSDNode(GV);
5566 const char *SymName = S->getSymbol();
5572 dyn_cast_or_null<Function>(
Mod->getNamedValue(SymName)))
5573 return getAIXFuncEntryPointSymbolSDNode(
F);
5579 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5587 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5594 assert(Callee.getNode() &&
"What no callee?");
5600 "Expected a CALLSEQ_STARTSDNode.");
5617 SDValue MTCTROps[] = {Chain, Callee, Glue};
5618 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5659 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5678 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5679 Alignment, MMOFlags);
5686 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5693 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5705 "Nest parameter is not supported on AIX.");
5721 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5724 const bool IsPPC64 = Subtarget.
isPPC64();
5773 for (
unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
5775 RegsToPass[i].second.getValueType()));
5792 assert(Mask &&
"Missing call preserved mask for calling convention");
5800SDValue PPCTargetLowering::FinishCall(
5815 if (!CFlags.IsIndirect)
5819 dl, CFlags.HasNest, Subtarget);
5829 if (CFlags.IsTailCall) {
5833 cast<RegisterSDNode>(Callee)->getReg() == PPC::CTR) ||
5836 isa<ConstantSDNode>(Callee) ||
5838 "Expecting a global address, external symbol, absolute value, "
5839 "register or an indirect tail call when PC Relative calls are "
5843 "Unexpected call opcode for a tail call.");
5850 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5851 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes, Ops);
5863 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5866 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5877 const GlobalValue *CalleeGV = dyn_cast<GlobalValue>(CalleeFunc);
5886 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5887 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5891bool PPCTargetLowering::isEligibleForTCO(
5896 bool isCalleeExternalSymbol)
const {
5901 return IsEligibleForTailCallOptimization_64SVR4(
5902 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5903 isCalleeExternalSymbol);
5905 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5928 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5930 bool IsCalleeExternalSymbol = isa<ExternalSymbolSDNode>(Callee);
5933 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5947 isa<GlobalAddressSDNode>(Callee)) &&
5948 "Callee should be an llvm::Function object.");
5951 <<
"\nTCO callee: ");
5958 "site marked musttail");
5963 if (Subtarget.useLongCalls() && isa<GlobalAddressSDNode>(Callee) &&
5965 Callee = LowerGlobalAddress(Callee, DAG);
5968 CallConv, isTailCall, isVarArg, isPatchPoint,
5976 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5981 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5983 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5987SDValue PPCTargetLowering::LowerCall_32SVR4(
5998 const bool IsVarArg = CFlags.IsVarArg;
5999 const bool IsTailCall = CFlags.IsTailCall;
6005 const Align PtrAlign(4);
6030 CCInfo.PreAnalyzeCallOperands(Outs);
6036 unsigned NumArgs = Outs.
size();
6038 for (
unsigned i = 0; i != NumArgs; ++i) {
6039 MVT ArgVT = Outs[i].VT;
6043 if (Outs[i].IsFixed) {
6053 errs() <<
"Call operand #" << i <<
" has unhandled type "
6063 CCInfo.clearWasPPCF128();
6070 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
6077 unsigned NumBytes = CCByValInfo.getStackSize();
6091 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6102 bool seenFloatArg =
false;
6107 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
6109 ++i, ++RealArgIdx) {
6111 SDValue Arg = OutVals[RealArgIdx];
6114 if (
Flags.isByVal()) {
6119 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
6142 Chain = CallSeqStart = NewCallSeqStart;
6161 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6168 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6192 if (!MemOpChains.
empty())
6198 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
6199 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
6200 RegsToPass[i].second, InGlue);
6208 SDValue Ops[] = { Chain, InGlue };
6220 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6221 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6226SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6238 return NewCallSeqStart;
6241SDValue PPCTargetLowering::LowerCall_64SVR4(
6250 unsigned NumOps = Outs.
size();
6251 bool IsSibCall =
false;
6255 unsigned PtrByteSize = 8;
6270 assert(!(IsFastCall && CFlags.IsVarArg) &&
6271 "fastcc not supported on varargs functions");
6278 unsigned NumBytes = LinkageSize;
6279 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6282 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6283 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6286 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6287 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6290 const unsigned NumGPRs = std::size(GPR);
6292 const unsigned NumVRs = std::size(VR);
6298 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6299 if (!HasParameterArea) {
6300 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6301 unsigned AvailableFPRs = NumFPRs;
6302 unsigned AvailableVRs = NumVRs;
6303 unsigned NumBytesTmp = NumBytes;
6304 for (
unsigned i = 0; i != NumOps; ++i) {
6305 if (Outs[i].
Flags.isNest())
continue;
6307 PtrByteSize, LinkageSize, ParamAreaSize,
6308 NumBytesTmp, AvailableFPRs, AvailableVRs))
6309 HasParameterArea =
true;
6315 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6320 HasParameterArea =
false;
6323 for (
unsigned i = 0; i != NumOps; ++i) {
6325 EVT ArgVT = Outs[i].VT;
6326 EVT OrigVT = Outs[i].ArgVT;
6332 if (
Flags.isByVal()) {
6333 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6334 if (NumGPRsUsed > NumGPRs)
6335 HasParameterArea =
true;
6342 if (++NumGPRsUsed <= NumGPRs)
6352 if (++NumVRsUsed <= NumVRs)
6356 if (++NumVRsUsed <= NumVRs)
6361 if (++NumFPRsUsed <= NumFPRs)
6365 HasParameterArea =
true;
6372 NumBytes =
alignTo(NumBytes, Alignement);
6375 if (
Flags.isInConsecutiveRegsLast())
6376 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6379 unsigned NumBytesActuallyUsed = NumBytes;
6389 if (HasParameterArea)
6390 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6392 NumBytes = LinkageSize;
6407 if (CFlags.IsTailCall)
6419 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6430 unsigned ArgOffset = LinkageSize;
6436 for (
unsigned i = 0; i != NumOps; ++i) {
6439 EVT ArgVT = Outs[i].VT;
6440 EVT OrigVT = Outs[i].ArgVT;
6449 auto ComputePtrOff = [&]() {
6453 ArgOffset =
alignTo(ArgOffset, Alignment);
6464 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6465 GPR_idx = std::min(GPR_idx, NumGPRs);
6472 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6478 if (
Flags.isByVal()) {
6496 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6497 if (GPR_idx != NumGPRs) {
6501 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6503 ArgOffset += PtrByteSize;
6508 if (GPR_idx == NumGPRs &&
Size < 8) {
6510 if (!isLittleEndian) {
6515 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6518 ArgOffset += PtrByteSize;
6527 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6528 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6533 if (
Size < 8 && GPR_idx != NumGPRs) {
6543 if (!isLittleEndian) {
6547 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6555 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6558 ArgOffset += PtrByteSize;
6564 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6567 if (GPR_idx != NumGPRs) {
6568 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6574 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6575 ArgOffset += PtrByteSize;
6577 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6589 if (
Flags.isNest()) {
6591 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6598 if (GPR_idx != NumGPRs) {
6599 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6604 assert(HasParameterArea &&
6605 "Parameter area must exist to pass an argument in memory.");
6607 true, CFlags.IsTailCall,
false, MemOpChains,
6608 TailCallArguments, dl);
6610 ArgOffset += PtrByteSize;
6613 ArgOffset += PtrByteSize;
6626 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6627 bool NeededLoad =
false;
6630 if (FPR_idx != NumFPRs)
6631 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6634 if (!NeedGPROrStack)
6636 else if (GPR_idx != NumGPRs && !IsFastCall) {
6650 }
else if (!
Flags.isInConsecutiveRegs()) {
6656 }
else if (ArgOffset % PtrByteSize != 0) {
6660 if (!isLittleEndian)
6665 }
else if (
Flags.isInConsecutiveRegsLast()) {
6668 if (!isLittleEndian)
6678 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6686 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6691 assert(HasParameterArea &&
6692 "Parameter area must exist to pass an argument in memory.");
6694 true, CFlags.IsTailCall,
false, MemOpChains,
6695 TailCallArguments, dl);
6702 if (!IsFastCall || NeededLoad) {
6704 Flags.isInConsecutiveRegs()) ? 4 : 8;
6705 if (
Flags.isInConsecutiveRegsLast())
6706 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6726 if (CFlags.IsVarArg) {
6727 assert(HasParameterArea &&
6728 "Parameter area must exist if we have a varargs call.");
6734 if (VR_idx != NumVRs) {
6738 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6741 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6742 if (GPR_idx == NumGPRs)
6749 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6755 if (VR_idx != NumVRs) {
6756 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6761 assert(HasParameterArea &&
6762 "Parameter area must exist to pass an argument in memory.");
6764 true, CFlags.IsTailCall,
true, MemOpChains,
6765 TailCallArguments, dl);
6776 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6777 "mismatch in size of parameter area");
6778 (void)NumBytesActuallyUsed;
6780 if (!MemOpChains.
empty())
6786 if (CFlags.IsIndirect) {
6790 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6805 if (isELFv2ABI && !CFlags.IsPatchPoint)
6806 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6812 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
6813 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
6814 RegsToPass[i].second, InGlue);
6818 if (CFlags.IsTailCall && !IsSibCall)
6822 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6823 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6830 "Required alignment greater than stack alignment.");
6850 return RequiredAlign <= 8;
6855 return RequiredAlign <= 4;
6865 const bool IsPPC64 = Subtarget.
isPPC64();
6866 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6867 const Align PtrAlign(PtrSize);
6868 const Align StackAlign(16);
6871 if (ValVT == MVT::f128)
6878 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6879 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6881 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6882 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6885 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6886 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6887 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6893 if (ByValAlign > StackAlign)
6895 "16 are not supported.");
6898 const Align ObjAlign = ByValAlign > PtrAlign ? ByValAlign : PtrAlign;
6902 if (ByValSize == 0) {
6910 while (NextReg != GPRs.
size() &&
6916 assert(Reg &&
"Alocating register unexpectedly failed.");
6921 const unsigned StackSize =
alignTo(ByValSize, ObjAlign);
6942 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6971 for (
unsigned I = 0;
I < StoreSize;
I += PtrSize) {
6973 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
7006 const unsigned VecSize = 16;
7007 const Align VecAlign(VecSize);
7027 while (NextRegIndex != GPRs.
size() &&
7032 assert(Reg &&
"Allocating register unexpectedly failed.");
7045 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
7057 if (NextRegIndex == GPRs.
size()) {
7066 if (GPRs[NextRegIndex] == PPC::R9) {
7073 assert(FirstReg && SecondReg &&
7074 "Allocating R9 or R10 unexpectedly failed.");
7088 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
7090 assert(Reg &&
"Failed to allocated register for vararg vector argument");
7105 assert((IsPPC64 || SVT != MVT::i64) &&
7106 "i64 should have been split for 32-bit codegen.");
7114 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7116 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
7118 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
7126 return &PPC::VRRCRegClass;
7139 else if (Flags.isZExt())
7149 if (PPC::GPRCRegClass.
contains(Reg)) {
7150 assert(Reg >= PPC::R3 && Reg <= PPC::R10 &&
7151 "Reg must be a valid argument register!");
7152 return LASize + 4 * (Reg - PPC::R3);
7155 if (PPC::G8RCRegClass.
contains(Reg)) {
7156 assert(Reg >= PPC::X3 && Reg <= PPC::X10 &&
7157 "Reg must be a valid argument register!");
7158 return LASize + 8 * (Reg - PPC::X3);
7204SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7211 "Unexpected calling convention!");
7221 const bool IsPPC64 = Subtarget.
isPPC64();
7222 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7234 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7235 uint64_t SaveStackPos = CCInfo.getStackSize();
7237 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7248 bool ArgSignExt =
Ins[VA.
getValNo()].Flags.isSExt();
7260 LocVT.
SimpleTy, IsPPC64, Subtarget.hasP8Vector(), Subtarget.hasVSX());
7262 MVT SaveVT = RegClass == &PPC::G8RCRegClass ? MVT::i64 : LocVT;
7274 unsigned StoreSize =
7276 SaveStackPos =
alignTo(SaveStackPos + StoreSize, PtrByteSize);
7279 auto HandleMemLoc = [&]() {
7282 assert((ValSize <= LocSize) &&
7283 "Object size is larger than size of MemLoc");
7286 if (LocSize > ValSize)
7287 CurArgOffset += LocSize - ValSize;
7289 const bool IsImmutable =
7321 assert(isVarArg &&
"Only use custom memloc for vararg.");
7324 const unsigned OriginalValNo = VA.
getValNo();
7325 (void)OriginalValNo;
7327 auto HandleCustomVecRegLoc = [&]() {
7328 assert(
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7329 "Missing custom RegLoc.");
7332 "Unexpected Val type for custom RegLoc.");
7334 "ValNo mismatch between custom MemLoc and RegLoc.");
7338 Subtarget.hasVSX()));
7345 HandleCustomVecRegLoc();
7346 HandleCustomVecRegLoc();
7350 if (
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7352 "Only 2 custom RegLocs expected for 64-bit codegen.");
7353 HandleCustomVecRegLoc();
7354 HandleCustomVecRegLoc();
7398 const unsigned Size =
7410 if (
Flags.isByVal()) {
7416 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7425 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7427 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7440 CopyFrom.
getValue(1), dl, CopyFrom,
7450 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7453 "RegLocs should be for ByVal argument.");
7460 if (
Offset != StackSize) {
7462 "Expected MemLoc for remaining bytes.");
7463 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7477 Subtarget.hasVSX()));
7494 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7496 unsigned CallerReservedArea = std::max<unsigned>(
7497 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7503 CallerReservedArea =
7512 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7513 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7515 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7516 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7517 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7522 for (
unsigned GPRIndex =
7523 (CCInfo.getStackSize() - LinkageSize) / PtrByteSize;
7524 GPRIndex < NumGPArgRegs; ++GPRIndex) {
7527 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7528 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7540 if (!MemOps.
empty())
7546SDValue PPCTargetLowering::LowerCall_AIX(
7559 "Unexpected calling convention!");
7561 if (CFlags.IsPatchPoint)
7568 AIXCCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7576 const bool IsPPC64 = Subtarget.
isPPC64();
7578 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7579 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7580 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7588 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7589 const unsigned NumBytes = std::max<unsigned>(
7590 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7606 for (
unsigned I = 0, E = ArgLocs.
size();
I != E;) {
7607 const unsigned ValNo = ArgLocs[
I].getValNo();
7611 if (
Flags.isByVal()) {
7612 const unsigned ByValSize =
Flags.getByValSize();
7620 auto GetLoad = [&](
EVT VT,
unsigned LoadOffset) {
7629 unsigned LoadOffset = 0;
7632 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7635 LoadOffset += PtrByteSize;
7638 "Unexpected location for pass-by-value argument.");
7642 if (LoadOffset == ByValSize)
7646 assert(ArgLocs[
I].getValNo() == ValNo &&
7647 "Expected additional location for by-value argument.");
7649 if (ArgLocs[
I].isMemLoc()) {
7650 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7655 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7661 CallSeqStart, MemcpyFlags, DAG, dl);
7670 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7671 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7672 "Unexpected register residue for by-value argument.");
7674 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7678 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7688 "Unexpected load emitted during handling of pass-by-value "
7696 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7731 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7739 const unsigned OriginalValNo = VA.
getValNo();
7741 unsigned LoadOffset = 0;
7742 auto HandleCustomVecRegLoc = [&]() {
7743 assert(
I != E &&
"Unexpected end of CCvalAssigns.");
7744 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7745 "Expected custom RegLoc.");
7748 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7754 LoadOffset += PtrByteSize;
7760 HandleCustomVecRegLoc();
7761 HandleCustomVecRegLoc();
7763 if (
I != E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7764 ArgLocs[
I].getValNo() == OriginalValNo) {
7766 "Only 2 custom RegLocs expected for 64-bit codegen.");
7767 HandleCustomVecRegLoc();
7768 HandleCustomVecRegLoc();
7786 "Unexpected register handling for calling convention.");
7792 "Custom register handling only expected for VarArg.");
7810 "Unexpected custom register for argument!");
7831 if (!MemOpChains.
empty())
7836 if (CFlags.IsIndirect) {
7837 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7841 const unsigned TOCSaveOffset =
7857 for (
auto Reg : RegsToPass) {
7862 const int SPDiff = 0;
7863 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7864 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7874 CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
7875 return CCInfo.CheckReturn(
7890 CCInfo.AnalyzeReturn(Outs,
7899 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7903 SDValue Arg = OutVals[RealResIdx];
7918 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7941 RetOps.push_back(Glue);
7947PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7952 EVT IntVT =
Op.getValueType();
7956 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7958 SDValue Ops[2] = {Chain, FPSIdx};
7972 bool isPPC64 = Subtarget.
isPPC64();
7973 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7993 bool isPPC64 = Subtarget.
isPPC64();
8014PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
8016 bool isPPC64 = Subtarget.
isPPC64();
8050 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
8051 SDValue Ops[3] = { Chain, NegSize, FPSIdx };
8062 bool isPPC64 = Subtarget.
isPPC64();
8074 Op.getOperand(0),
Op.getOperand(1));
8081 Op.getOperand(0),
Op.getOperand(1));
8085 if (
Op.getValueType().isVector())
8086 return LowerVectorLoad(
Op, DAG);
8088 assert(
Op.getValueType() == MVT::i1 &&
8089 "Custom lowering only for i1 loads");
8102 BasePtr, MVT::i8, MMO);
8110 if (
Op.getOperand(1).getValueType().isVector())
8111 return LowerVectorStore(
Op, DAG);
8113 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
8114 "Custom lowering only for i1 stores");
8133 assert(
Op.getValueType() == MVT::i1 &&
8134 "Custom lowering only for i1 results");
8162 EVT TrgVT =
Op.getValueType();
8175 !llvm::has_single_bit<uint32_t>(
8186 if (SrcSize == 256) {
8197 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8205 for (
unsigned i = 0; i < TrgNumElts; ++i)
8208 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8212 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8225 EVT ResVT =
Op.getValueType();
8226 EVT CmpVT =
Op.getOperand(0).getValueType();
8228 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8234 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8251 if (Subtarget.hasP9Vector() && LHS == TV && RHS == FV) {
8283 if (
LHS.getValueType() == MVT::f32)
8296 if (
LHS.getValueType() == MVT::f32)
8305 if (
LHS.getValueType() == MVT::f32)
8319 if (
Cmp.getValueType() == MVT::f32)
8329 if (
Cmp.getValueType() == MVT::f32)
8335 if (
Cmp.getValueType() == MVT::f32)
8341 if (
Cmp.getValueType() == MVT::f32)
8347 if (
Cmp.getValueType() == MVT::f32)
8380 bool IsStrict =
Op->isStrictFPOpcode();
8386 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8389 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8391 MVT DestTy =
Op.getSimpleValueType();
8392 assert(Src.getValueType().isFloatingPoint() &&
8393 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8394 DestTy == MVT::i64) &&
8395 "Invalid FP_TO_INT types");
8396 if (Src.getValueType() == MVT::f32) {
8400 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8401 Chain = Src.getValue(1);
8405 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8415 assert((IsSigned || Subtarget.hasFPCVT()) &&
8416 "i64 FP_TO_UINT is supported only with FPCVT");
8419 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8423 Conv = DAG.
getNode(Opc, dl, DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src},
8426 Conv = DAG.
getNode(Opc, dl, ConvTy, Src);
8431void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8433 const SDLoc &dl)
const {
8437 bool IsStrict =
Op->isStrictFPOpcode();
8440 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8441 (IsSigned || Subtarget.hasFPCVT());
8443 int FI = cast<FrameIndexSDNode>(FIPtr)->getIndex();
8452 Alignment =
Align(4);
8455 SDValue Ops[] = { Chain, Tmp, FIPtr };
8457 DAG.
getVTList(MVT::Other), Ops, MVT::i32, MMO);
8459 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8463 if (
Op.getValueType() == MVT::i32 && !i32Stack) {
8472 RLI.Alignment = Alignment;
8480 const SDLoc &dl)
const {
8483 if (
Op->isStrictFPOpcode())
8490 const SDLoc &dl)
const {
8491 bool IsStrict =
Op->isStrictFPOpcode();
8494 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8495 EVT SrcVT = Src.getValueType();
8496 EVT DstVT =
Op.getValueType();
8499 if (SrcVT == MVT::f128)
8500 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8504 if (SrcVT == MVT::ppcf128) {
8505 if (DstVT == MVT::i32) {
8510 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8521 {Op.getOperand(0), Lo, Hi}, Flags);
8524 {Res.getValue(1), Res}, Flags);
8530 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8554 {Chain, Src, FltOfs}, Flags);
8558 {Chain, Val}, Flags);
8561 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8579 if (Subtarget.hasDirectMove() && Subtarget.
isPPC64())
8580 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8583 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8585 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8586 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8597bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8602 if (
Op->isStrictFPOpcode())
8607 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8611 Op.getOperand(0).getValueType())) {
8613 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8618 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8619 LD->isNonTemporal())
8621 if (
LD->getMemoryVT() != MemVT)
8631 RLI.Ptr =
LD->getBasePtr();
8632 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8634 "Non-pre-inc AM on PPC?");
8639 RLI.Chain =
LD->getChain();
8640 RLI.MPI =
LD->getPointerInfo();
8641 RLI.IsDereferenceable =
LD->isDereferenceable();
8642 RLI.IsInvariant =
LD->isInvariant();
8643 RLI.Alignment =
LD->getAlign();
8644 RLI.AAInfo =
LD->getAAInfo();
8645 RLI.Ranges =
LD->getRanges();
8647 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8654bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8655 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8662 if (!Subtarget.hasP9Vector() &&
8669 if (
Use.getResNo() != 0)
8692 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8696 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8699 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8700 if (
Op->isStrictFPOpcode()) {
8702 Chain =
Op.getOperand(0);
8704 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8706 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8714 const SDLoc &dl)
const {
8715 assert((
Op.getValueType() == MVT::f32 ||
8716 Op.getValueType() == MVT::f64) &&
8717 "Invalid floating point type as target of conversion");
8718 assert(Subtarget.hasFPCVT() &&
8719 "Int to FP conversions with direct moves require FPCVT");
8720 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8721 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8743 for (
unsigned i = 1; i < NumConcat; ++i)
8750 const SDLoc &dl)
const {
8751 bool IsStrict =
Op->isStrictFPOpcode();
8752 unsigned Opc =
Op.getOpcode();
8753 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8756 "Unexpected conversion type");
8757 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8758 "Supports conversions to v2f64/v4f32 only.");
8762 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8765 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8770 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8773 for (
unsigned i = 0; i < WideNumElts; ++i)
8776 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8777 int SaveElts = FourEltRes ? 4 : 2;
8779 for (
int i = 0; i < SaveElts; i++)
8780 ShuffV[i * Stride] = i;
8782 for (
int i = 1; i <= SaveElts; i++)
8783 ShuffV[i * Stride - 1] = i - 1;
8791 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8792 EVT ExtVT = Src.getValueType();
8793 if (Subtarget.hasP9Altivec())
8804 {Op.getOperand(0), Extend}, Flags);
8806 return DAG.
getNode(Opc, dl,
Op.getValueType(), Extend);
8814 bool IsStrict =
Op->isStrictFPOpcode();
8815 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8820 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8822 EVT InVT = Src.getValueType();
8823 EVT OutVT =
Op.getValueType();
8826 return LowerINT_TO_FPVector(
Op, DAG, dl);
8829 if (
Op.getValueType() == MVT::f128)
8830 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8833 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8836 if (Src.getValueType() == MVT::i1) {
8848 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8849 Subtarget.
isPPC64() && Subtarget.hasFPCVT())
8850 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8852 assert((IsSigned || Subtarget.hasFPCVT()) &&
8853 "UINT_TO_FP is supported only with FPCVT");
8855 if (Src.getValueType() == MVT::i64) {
8867 if (
Op.getValueType() == MVT::f32 &&
8868 !Subtarget.hasFPCVT() &&
8909 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8910 Bits = DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8911 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8914 }
else if (Subtarget.hasLFIWAX() &&
8915 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8918 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8919 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8922 Ops, MVT::i32, MMO);
8925 }
else if (Subtarget.hasFPCVT() &&
8926 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8929 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8930 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8933 Ops, MVT::i32, MMO);
8936 }
else if (((Subtarget.hasLFIWAX() &&
8938 (Subtarget.hasFPCVT() &&
8952 assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
8953 "Expected an i32 store");
8959 RLI.Alignment =
Align(4);
8963 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8964 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8967 dl, DAG.
getVTList(MVT::f64, MVT::Other),
8968 Ops, MVT::i32, MMO);
8969 Chain =
Bits.getValue(1);
8975 Chain =
FP.getValue(1);
8977 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8981 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)},
8990 assert(Src.getValueType() == MVT::i32 &&
8991 "Unhandled INT_TO_FP type in custom expander!");
9001 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
9004 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
9013 assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
9014 "Expected an i32 store");
9020 RLI.Alignment =
Align(4);
9025 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
9026 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
9028 DAG.
getVTList(MVT::f64, MVT::Other), Ops,
9031 if (ReusingLoad && RLI.ResChain) {
9036 "i32->FP without LFIWAX supported only on PPC64");
9045 Chain, dl, Ext64, FIdx,
9051 MVT::f64, dl, Chain, FIdx,
9059 Chain =
FP.getValue(1);
9060 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
9064 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)}, Flags);
9080 if (
auto *CVal = dyn_cast<ConstantSDNode>(
Op.getOperand(1))) {
9082 assert(Mode < 4 &&
"Unsupported rounding mode!");
9083 unsigned InternalRnd =
Mode ^ (~(
Mode >> 1) & 1);
9084 if (Subtarget.isISA3_0())
9087 PPC::MFFSCRNI, Dl, {MVT::f64, MVT::Other},
9088 {DAG.getConstant(InternalRnd, Dl, MVT::i32, true), Chain}),
9091 (InternalRnd & 2) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9092 {DAG.
getConstant(30, Dl, MVT::i32,
true), Chain});
9094 (InternalRnd & 1) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9112 if (!Subtarget.isISA3_0()) {
9114 Chain =
MFFS.getValue(1);
9118 if (Subtarget.isISA3_0()) {
9123 PPC::RLDIMI, Dl, MVT::i64,
9128 NewFPSCR =
SDValue(InsertRN, 0);
9139 if (Subtarget.isISA3_0()) {
9147 PPC::RLWIMI, Dl, MVT::i32,
9148 {Tmp, DstFlag, DAG.getTargetConstant(0, Dl, MVT::i32),
9149 DAG.getTargetConstant(30, Dl, MVT::i32),
9150 DAG.getTargetConstant(31, Dl, MVT::i32)}),
9158 if (Subtarget.isISA3_0())
9164 PPC::MTFSF, Dl, MVT::Other,
9165 {DAG.
getConstant(255, Dl, MVT::i32,
true), NewFPSCR, Zero, Zero, Chain});
9192 EVT VT =
Op.getValueType();
9198 Chain =
MFFS.getValue(1);
9212 "Stack slot adjustment is valid only on big endian subtargets!");
9242 EVT VT =
Op.getValueType();
9246 VT ==
Op.getOperand(1).getValueType() &&
9266 SDValue OutOps[] = { OutLo, OutHi };
9271 EVT VT =
Op.getValueType();
9275 VT ==
Op.getOperand(1).getValueType() &&
9295 SDValue OutOps[] = { OutLo, OutHi };
9301 EVT VT =
Op.getValueType();
9304 VT ==
Op.getOperand(1).getValueType() &&
9324 SDValue OutOps[] = { OutLo, OutHi };
9331 EVT VT =
Op.getValueType();
9338 EVT AmtVT =
Z.getValueType();
9361 static const MVT VTys[] = {
9362 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9365 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9368 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9373 EVT CanonicalVT = VTys[SplatSize-1];
9386 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9387 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9396 EVT DestVT = MVT::Other) {
9397 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9406 EVT DestVT = MVT::Other) {
9409 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9421 for (
unsigned i = 0; i != 16; ++i)
9442 EVT VecVT = V->getValueType(0);
9443 bool RightType = VecVT == MVT::v2f64 ||
9444 (HasP8Vector && VecVT == MVT::v4f32) ||
9445 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9449 bool IsSplat =
true;
9450 bool IsLoad =
false;
9451 SDValue Op0 = V->getOperand(0);
9456 if (V->isConstant())
9458 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9459 if (V->getOperand(i).isUndef())
9463 if (V->getOperand(i).getOpcode() ==
ISD::LOAD ||
9465 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9467 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9469 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD))
9473 if (V->getOperand(i) != Op0 ||
9474 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9477 return !(IsSplat && IsLoad);
9487 (
Op.getValueType() != MVT::f128))
9492 if ((
Lo.getValueType() != MVT::i64) || (
Hi.getValueType() != MVT::i64))
9512 LoadSDNode *LD = cast<LoadSDNode>(*InputLoad);
9520 APFloat APFloatToConvert = ArgAPFloat;
9521 bool LosesInfo =
true;
9526 ArgAPFloat = APFloatToConvert;
9548 APFloat APFloatToConvert = ArgAPFloat;
9549 bool LosesInfo =
true;
9553 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9558 LoadSDNode *InputNode = dyn_cast<LoadSDNode>(
Op.getOperand(0));
9562 EVT Ty =
Op->getValueType(0);
9565 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9574 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9578 if (Ty == MVT::v2i64) {
9581 if (MemVT == MVT::i32) {
9601 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9604 APInt APSplatBits, APSplatUndef;
9605 unsigned SplatBitSize;
9607 bool BVNIsConstantSplat =
9615 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9616 Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
9619 if ((
Op->getValueType(0) == MVT::v2f64) &&
9652 if (!BVNIsConstantSplat || SplatBitSize > 32) {
9659 const SDValue *InputLoad = &
Op.getOperand(0);
9664 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9665 unsigned ElementSize =
9668 assert(((ElementSize == 2 * MemorySize)
9672 "Unmatched element size and opcode!\n");
9677 unsigned NumUsesOfInputLD = 128 / ElementSize;
9679 if (BVInOp.isUndef())
9694 if (NumUsesOfInputLD == 1 &&
9697 Subtarget.hasLFIWAX()))
9706 Subtarget.isISA3_1() && ElementSize <= 16)
9709 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9711 Subtarget.hasVSX()) {
9718 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other), Ops,
9719 LD->getMemoryVT(),
LD->getMemOperand());
9731 if (Subtarget.hasVSX() && Subtarget.
isPPC64() &&
9733 Subtarget.hasP8Vector()))
9740 unsigned SplatSize = SplatBitSize / 8;
9745 if (SplatBits == 0) {
9747 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9759 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 2)
9761 Op.getValueType(), DAG, dl);
9763 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 4)
9768 if (Subtarget.hasP9Vector() && SplatSize == 1)
9773 int32_t SextVal =
SignExtend32(SplatBits, SplatBitSize);
9774 if (SextVal >= -16 && SextVal <= 15)
9787 if (SextVal >= -32 && SextVal <= 31) {
9792 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9793 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9796 if (VT ==
Op.getValueType())
9805 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9819 static const signed char SplatCsts[] = {
9820 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9821 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9824 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9827 int i = SplatCsts[idx];
9831 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9834 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9836 static const unsigned IIDs[] = {
9837 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9838 Intrinsic::ppc_altivec_vslw
9845 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9847 static const unsigned IIDs[] = {
9848 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9849 Intrinsic::ppc_altivec_vsrw
9856 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9857 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9859 static const unsigned IIDs[] = {
9860 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
9861 Intrinsic::ppc_altivec_vrlw
9868 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
9874 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
9880 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
9895 unsigned OpNum = (PFEntry >> 26) & 0x0F;
9896 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
9897 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
9913 if (LHSID == (1*9+2)*9+3)
return LHS;
9914 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
9926 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
9927 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
9928 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
9929 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
9932 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
9933 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
9934 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
9935 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
9938 for (
unsigned i = 0; i != 16; ++i)
9939 ShufIdxs[i] = (i&3)+0;
9942 for (
unsigned i = 0; i != 16; ++i)
9943 ShufIdxs[i] = (i&3)+4;
9946 for (
unsigned i = 0; i != 16; ++i)
9947 ShufIdxs[i] = (i&3)+8;
9950 for (
unsigned i = 0; i != 16; ++i)
9951 ShufIdxs[i] = (i&3)+12;
9972 const unsigned BytesInVector = 16;
9977 unsigned ShiftElts = 0, InsertAtByte = 0;
9981 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
9982 0, 15, 14, 13, 12, 11, 10, 9};
9983 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
9984 1, 2, 3, 4, 5, 6, 7, 8};
9987 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
9999 bool FoundCandidate =
false;
10003 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
10006 for (
unsigned i = 0; i < BytesInVector; ++i) {
10007 unsigned CurrentElement =
Mask[i];
10010 if (
V2.isUndef() && CurrentElement != VINSERTBSrcElem)
10013 bool OtherElementsInOrder =
true;
10016 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
10023 (!
V2.isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
10024 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
10025 OtherElementsInOrder =
false;
10032 if (OtherElementsInOrder) {
10034 if (
V2.isUndef()) {
10039 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
10040 : BigEndianShifts[CurrentElement & 0xF];
10041 Swap = CurrentElement < BytesInVector;
10043 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
10044 FoundCandidate =
true;
10049 if (!FoundCandidate)
10073 const unsigned NumHalfWords = 8;
10074 const unsigned BytesInVector = NumHalfWords * 2;
10083 unsigned ShiftElts = 0, InsertAtByte = 0;
10087 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
10088 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
10091 uint32_t OriginalOrderLow = 0x1234567;
10092 uint32_t OriginalOrderHigh = 0x89ABCDEF;
10095 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10096 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10113 bool FoundCandidate =
false;
10116 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10117 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10125 if (
V2.isUndef()) {
10127 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
10128 TargetOrder = OriginalOrderLow;
10132 if (MaskOneElt == VINSERTHSrcElem &&
10133 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10134 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10135 FoundCandidate =
true;
10141 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
10143 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10145 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
10146 : BigEndianShifts[MaskOneElt & 0x7];
10147 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10148 Swap = MaskOneElt < NumHalfWords;
10149 FoundCandidate =
true;
10155 if (!FoundCandidate)
10190 auto ShuffleMask = SVN->
getMask();
10205 ShuffleMask = CommutedSV->
getMask();
10214 APInt APSplatValue, APSplatUndef;
10215 unsigned SplatBitSize;
10231 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
10232 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
10233 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
10235 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
10236 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
10237 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
10245 for (; SplatBitSize < 32; SplatBitSize <<= 1)
10246 SplatVal |= (SplatVal << SplatBitSize);
10260 assert(
Op.getValueType() == MVT::v1i128 &&
10261 "Only set v1i128 as custom, other type shouldn't reach here!");
10266 if (SHLAmt % 8 == 0) {
10267 std::array<int, 16>
Mask;
10268 std::iota(
Mask.begin(),
Mask.end(), 0);
10269 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10298 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10299 if (!isa<ShuffleVectorSDNode>(NewShuffle))
10302 SVOp = cast<ShuffleVectorSDNode>(
Op);
10303 V1 =
Op.getOperand(0);
10304 V2 =
Op.getOperand(1);
10306 EVT VT =
Op.getValueType();
10309 unsigned ShiftElts, InsertAtByte;
10315 bool IsPermutedLoad =
false;
10317 if (InputLoad && Subtarget.hasVSX() &&
V2.isUndef() &&
10327 if (IsPermutedLoad) {
10328 assert((isLittleEndian || IsFourByte) &&
10329 "Unexpected size for permuted load on big endian target");
10330 SplatIdx += IsFourByte ? 2 : 1;
10331 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10332 "Splat of a value outside of the loaded memory");
10337 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10340 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10342 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10346 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10359 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10362 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10371 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10374 if (Subtarget.hasP9Vector() &&
10395 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
10397 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10398 return SplatInsertNode;
10401 if (Subtarget.hasP9Altivec()) {
10403 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10406 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10410 if (Subtarget.hasVSX() &&
10423 if (Subtarget.hasVSX() &&
10436 if (Subtarget.hasP9Vector()) {
10456 if (Subtarget.hasVSX()) {
10477 if (
V2.isUndef()) {
10490 (Subtarget.hasP8Altivec() && (
10501 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10511 (Subtarget.hasP8Altivec() && (
10522 unsigned PFIndexes[4];
10523 bool isFourElementShuffle =
true;
10524 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10526 unsigned EltNo = 8;
10527 for (
unsigned j = 0;
j != 4; ++
j) {
10528 if (PermMask[i * 4 + j] < 0)
10531 unsigned ByteSource = PermMask[i * 4 +
j];
10532 if ((ByteSource & 3) != j) {
10533 isFourElementShuffle =
false;
10538 EltNo = ByteSource / 4;
10539 }
else if (EltNo != ByteSource / 4) {
10540 isFourElementShuffle =
false;
10544 PFIndexes[i] = EltNo;
10552 if (isFourElementShuffle) {
10554 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10555 PFIndexes[2] * 9 + PFIndexes[3];
10558 unsigned Cost = (PFEntry >> 30);
10578 if (
V2.isUndef())
V2 = V1;
10580 return LowerVPERM(
Op, DAG, PermMask, VT, V1, V2);
10589 bool NeedSwap =
false;
10591 bool isPPC64 = Subtarget.
isPPC64();
10593 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10595 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10596 "XXPERM instead\n");
10602 if ((!isLittleEndian && !
V2->hasOneUse() && V1->
hasOneUse()) ||
10603 (isLittleEndian && !V1->
hasOneUse() &&
V2->hasOneUse())) {
10605 NeedSwap = !NeedSwap;
10640 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10642 if (V1HasXXSWAPD) {
10645 else if (SrcElt < 16)
10648 if (V2HasXXSWAPD) {
10651 else if (SrcElt > 15)
10660 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10661 if (isLittleEndian)
10663 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10666 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10669 if (V1HasXXSWAPD) {
10673 if (V2HasXXSWAPD) {
10674 dl =
SDLoc(
V2->getOperand(0));
10675 V2 =
V2->getOperand(0)->getOperand(1);
10678 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10679 if (ValType != MVT::v2f64)
10681 if (
V2.getValueType() != MVT::v2f64)
10685 ShufflesHandledWithVPERM++;
10690 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10692 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10695 dbgs() <<
"With the following permute control vector:\n";
10700 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10704 if (isLittleEndian)
10710 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10722 switch (IntrinsicID) {
10726 case Intrinsic::ppc_altivec_vcmpbfp_p:
10730 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10734 case Intrinsic::ppc_altivec_vcmpequb_p:
10738 case Intrinsic::ppc_altivec_vcmpequh_p:
10742 case Intrinsic::ppc_altivec_vcmpequw_p:
10746 case Intrinsic::ppc_altivec_vcmpequd_p:
10747 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10753 case Intrinsic::ppc_altivec_vcmpneb_p:
10754 case Intrinsic::ppc_altivec_vcmpneh_p:
10755 case Intrinsic::ppc_altivec_vcmpnew_p:
10756 case Intrinsic::ppc_altivec_vcmpnezb_p:
10757 case Intrinsic::ppc_altivec_vcmpnezh_p:
10758 case Intrinsic::ppc_altivec_vcmpnezw_p:
10759 if (Subtarget.hasP9Altivec()) {
10760 switch (IntrinsicID) {
10763 case Intrinsic::ppc_altivec_vcmpneb_p:
10766 case Intrinsic::ppc_altivec_vcmpneh_p:
10769 case Intrinsic::ppc_altivec_vcmpnew_p:
10772 case Intrinsic::ppc_altivec_vcmpnezb_p:
10775 case Intrinsic::ppc_altivec_vcmpnezh_p:
10778 case Intrinsic::ppc_altivec_vcmpnezw_p:
10786 case Intrinsic::ppc_altivec_vcmpgefp_p:
10790 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10794 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10798 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10802 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10806 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10807 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10813 case Intrinsic::ppc_altivec_vcmpgtub_p:
10817 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10821 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10825 case Intrinsic::ppc_altivec_vcmpgtud_p:
10826 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10833 case Intrinsic::ppc_altivec_vcmpequq:
10834 case Intrinsic::ppc_altivec_vcmpgtsq:
10835 case Intrinsic::ppc_altivec_vcmpgtuq:
10836 if (!Subtarget.isISA3_1())
10838 switch (IntrinsicID) {
10841 case Intrinsic::ppc_altivec_vcmpequq:
10844 case Intrinsic::ppc_altivec_vcmpgtsq:
10847 case Intrinsic::ppc_altivec_vcmpgtuq:
10854 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10855 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10856 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10857 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10858 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10859 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10860 if (Subtarget.hasVSX()) {
10861 switch (IntrinsicID) {
10862 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10865 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10868 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10871 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10874 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10877 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10887 case Intrinsic::ppc_altivec_vcmpbfp:
10890 case Intrinsic::ppc_altivec_vcmpeqfp:
10893 case Intrinsic::ppc_altivec_vcmpequb:
10896 case Intrinsic::ppc_altivec_vcmpequh:
10899 case Intrinsic::ppc_altivec_vcmpequw:
10902 case Intrinsic::ppc_altivec_vcmpequd:
10903 if (Subtarget.hasP8Altivec())
10908 case Intrinsic::ppc_altivec_vcmpneb:
10909 case Intrinsic::ppc_altivec_vcmpneh:
10910 case Intrinsic::ppc_altivec_vcmpnew:
10911 case Intrinsic::ppc_altivec_vcmpnezb:
10912 case Intrinsic::ppc_altivec_vcmpnezh:
10913 case Intrinsic::ppc_altivec_vcmpnezw:
10914 if (Subtarget.hasP9Altivec())
10915 switch (IntrinsicID) {
10918 case Intrinsic::ppc_altivec_vcmpneb:
10921 case Intrinsic::ppc_altivec_vcmpneh:
10924 case Intrinsic::ppc_altivec_vcmpnew:
10927 case Intrinsic::ppc_altivec_vcmpnezb:
10930 case Intrinsic::ppc_altivec_vcmpnezh:
10933 case Intrinsic::ppc_altivec_vcmpnezw:
10940 case Intrinsic::ppc_altivec_vcmpgefp:
10943 case Intrinsic::ppc_altivec_vcmpgtfp:
10946 case Intrinsic::ppc_altivec_vcmpgtsb:
10949 case Intrinsic::ppc_altivec_vcmpgtsh:
10952 case Intrinsic::ppc_altivec_vcmpgtsw:
10955 case Intrinsic::ppc_altivec_vcmpgtsd:
10956 if (Subtarget.hasP8Altivec())
10961 case Intrinsic::ppc_altivec_vcmpgtub:
10964 case Intrinsic::ppc_altivec_vcmpgtuh:
10967 case Intrinsic::ppc_altivec_vcmpgtuw:
10970 case Intrinsic::ppc_altivec_vcmpgtud:
10971 if (Subtarget.hasP8Altivec())
10976 case Intrinsic::ppc_altivec_vcmpequq_p:
10977 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10978 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10979 if (!Subtarget.isISA3_1())
10981 switch (IntrinsicID) {
10984 case Intrinsic::ppc_altivec_vcmpequq_p:
10987 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10990 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11004 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
11008 switch (IntrinsicID) {
11009 case Intrinsic::thread_pointer:
11015 case Intrinsic::ppc_rldimi: {
11016 assert(Subtarget.
isPPC64() &&
"rldimi is only available in 64-bit!");
11020 return Op.getOperand(2);
11021 if (
Mask.isAllOnes())
11024 unsigned MB = 0, ME = 0;
11028 if (ME < 63 - SH) {
11031 }
else if (ME > 63 - SH) {
11037 {Op.getOperand(2), Src,
11038 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
11039 DAG.getTargetConstant(MB, dl, MVT::i32)}),
11043 case Intrinsic::ppc_rlwimi: {
11046 return Op.getOperand(2);
11047 if (
Mask.isAllOnes())
11050 unsigned MB = 0, ME = 0;
11054 PPC::RLWIMI, dl, MVT::i32,
11055 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
11056 DAG.getTargetConstant(MB, dl, MVT::i32),
11057 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11061 case Intrinsic::ppc_rlwnm: {
11062 if (
Op.getConstantOperandVal(3) == 0)
11064 unsigned MB = 0, ME = 0;
11069 {Op.getOperand(1), Op.getOperand(2),
11070 DAG.getTargetConstant(MB, dl, MVT::i32),
11071 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11075 case Intrinsic::ppc_mma_disassemble_acc: {
11076 if (Subtarget.isISAFuture()) {
11077 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11115 case Intrinsic::ppc_vsx_disassemble_pair: {
11118 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
11123 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
11134 case Intrinsic::ppc_mma_xxmfacc:
11135 case Intrinsic::ppc_mma_xxmtacc: {
11137 if (!Subtarget.isISAFuture())
11148 case Intrinsic::ppc_unpack_longdouble: {
11149 auto *
Idx = dyn_cast<ConstantSDNode>(
Op.getOperand(2));
11150 assert(
Idx && (
Idx->getSExtValue() == 0 ||
Idx->getSExtValue() == 1) &&
11151 "Argument of long double unpack must be 0 or 1!");
11154 Idx->getValueType(0)));
11157 case Intrinsic::ppc_compare_exp_lt:
11158 case Intrinsic::ppc_compare_exp_gt:
11159 case Intrinsic::ppc_compare_exp_eq:
11160 case Intrinsic::ppc_compare_exp_uo: {
11162 switch (IntrinsicID) {
11163 case Intrinsic::ppc_compare_exp_lt:
11166 case Intrinsic::ppc_compare_exp_gt:
11169 case Intrinsic::ppc_compare_exp_eq:
11172 case Intrinsic::ppc_compare_exp_uo:
11178 PPC::SELECT_CC_I4, dl, MVT::i32,
11179 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
11180 Op.getOperand(1), Op.getOperand(2)),
11182 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11183 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
11186 case Intrinsic::ppc_test_data_class: {
11187 EVT OpVT =
Op.getOperand(1).getValueType();
11188 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
11189 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
11193 PPC::SELECT_CC_I4, dl, MVT::i32,
11194 {SDValue(DAG.getMachineNode(CmprOpc, dl, MVT::i32, Op.getOperand(2),
11197 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11198 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
11201 case Intrinsic::ppc_fnmsub: {
11202 EVT VT =
Op.getOperand(1).getValueType();
11203 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
11209 Op.getOperand(2),
Op.getOperand(3));
11211 case Intrinsic::ppc_convert_f128_to_ppcf128:
11212 case Intrinsic::ppc_convert_ppcf128_to_f128: {
11213 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
11214 ? RTLIB::CONVERT_PPCF128_F128
11215 : RTLIB::CONVERT_F128_PPCF128;
11216 MakeLibCallOptions CallOptions;
11217 std::pair<SDValue, SDValue>
Result =
11218 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
11222 case Intrinsic::ppc_maxfe:
11223 case Intrinsic::ppc_maxfl:
11224 case Intrinsic::ppc_maxfs:
11225 case Intrinsic::ppc_minfe:
11226 case Intrinsic::ppc_minfl:
11227 case Intrinsic::ppc_minfs: {
11228 EVT VT =
Op.getValueType();
11231 [VT](
const SDUse &
Use) { return Use.getValueType() == VT; }) &&
11232 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
11235 if (IntrinsicID == Intrinsic::ppc_minfe ||
11236 IntrinsicID == Intrinsic::ppc_minfl ||
11237 IntrinsicID == Intrinsic::ppc_minfs)
11259 Op.getOperand(1),
Op.getOperand(2),
11270 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11278 switch (
Op.getConstantOperandVal(1)) {
11283 Bitx = PPC::sub_eq;
11289 Bitx = PPC::sub_eq;
11295 Bitx = PPC::sub_lt;
11301 Bitx = PPC::sub_lt;
11307 if (Subtarget.isISA3_1()) {
11312 CR6Reg, SubRegIdx, GlueOp),
11314 return DAG.
getNode(SetOp, dl, MVT::i32, CRBit);
11340 int ArgStart = isa<ConstantSDNode>(
Op.getOperand(0)) ? 0 : 1;
11342 switch (
Op.getConstantOperandVal(ArgStart)) {
11343 case Intrinsic::ppc_cfence: {
11344 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11345 SDValue Val =
Op.getOperand(ArgStart + 1);
11347 if (Ty == MVT::i128) {
11352 unsigned Opcode = Subtarget.
isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11355 Opcode,
DL, MVT::Other,
11377 int VectorIndex = 0;
11390 "Expecting an atomic compare-and-swap here.");
11392 auto *AtomicNode = cast<AtomicSDNode>(
Op.getNode());
11393 EVT MemVT = AtomicNode->getMemoryVT();
11411 for (
int i = 0, e = AtomicNode->getNumOperands(); i <
e; i++)
11412 Ops.
push_back(AtomicNode->getOperand(i));
11424 EVT MemVT =
N->getMemoryVT();
11426 "Expect quadword atomic operations");
11428 unsigned Opc =
N->getOpcode();
11436 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11437 for (
int I = 1, E =
N->getNumOperands();
I < E; ++
I)
11440 Ops, MemVT,
N->getMemOperand());
11447 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11457 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11467 N->getMemOperand());
11479 enum DataClassMask {
11481 DC_NEG_INF = 1 << 4,
11482 DC_POS_INF = 1 << 5,
11483 DC_NEG_ZERO = 1 << 2,
11484 DC_POS_ZERO = 1 << 3,
11485 DC_NEG_SUBNORM = 1,
11486 DC_POS_SUBNORM = 1 << 1,
11489 EVT VT =
Op.getValueType();
11491 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11492 : VT == MVT::f64 ? PPC::XSTSTDCDP
11503 return DAG.
getNOT(Dl, Rev, MVT::i1);
11510 TestOp, Dl, MVT::i32,
11512 DC_NEG_ZERO | DC_POS_ZERO |
11513 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11519 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11525 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11530 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11543 bool IsQuiet = Mask &
fcQNan;
11549 if (VT == MVT::f128) {
11553 QuietMask = 0x8000;
11554 }
else if (VT == MVT::f64) {
11566 QuietMask = 0x80000;
11567 }
else if (VT == MVT::f32) {
11569 QuietMask = 0x400000;
11585 unsigned NativeMask = 0;
11587 NativeMask |= DC_NAN;
11589 NativeMask |= DC_NEG_INF;
11591 NativeMask |= DC_POS_INF;
11593 NativeMask |= DC_NEG_ZERO;
11595 NativeMask |= DC_POS_ZERO;
11597 NativeMask |= DC_NEG_SUBNORM;
11599 NativeMask |= DC_POS_SUBNORM;
11602 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11604 TestOp, Dl, MVT::i32,
11613 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11615 uint64_t RHSC =
Op.getConstantOperandVal(1);
11618 if (
LHS.getValueType() == MVT::ppcf128) {
11634 unsigned EltSize =
Op.getValueType().getScalarSizeInBits();
11635 if (isa<ConstantSDNode>(Op0) && EltSize <= 32) {
11636 int64_t
IntVal =
Op.getConstantOperandVal(0);
11637 if (IntVal >= -16 && IntVal <= 15)
11643 if (Subtarget.hasLFIWAX() && Subtarget.hasVSX() &&
11650 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
11657 return Bits.getValue(0);
11678 64 -
Op.getValueType().getScalarSizeInBits(), dl, ShiftAmountTy);
11685 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx,
11699 "Should only be called for ISD::INSERT_VECTOR_ELT");
11703 EVT VT =
Op.getValueType();
11708 if (VT == MVT::v2f64 &&
C)
11711 if (Subtarget.hasP9Vector()) {
11720 if ((VT == MVT::v4f32) && (
V2.getValueType() == MVT::f32) &&
11721 (isa<LoadSDNode>(V2))) {
11726 BitcastLoad,
Op.getOperand(2));
11727 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
11731 if (Subtarget.isISA3_1()) {
11732 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.
isPPC64())
11736 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
11737 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
11747 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
11750 unsigned InsertAtElement =
C->getZExtValue();
11751 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
11753 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
11767 EVT VT =
Op.getValueType();
11769 if (VT != MVT::v256i1 && VT != MVT::v512i1)
11775 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
11776 "Type unsupported without MMA");
11777 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
11778 "Type unsupported without paired vector support");
11783 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
11785 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
11795 std::reverse(Loads.
begin(), Loads.
end());
11796 std::reverse(LoadChains.
begin(), LoadChains.
end());
11814 EVT StoreVT =
Value.getValueType();
11816 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
11822 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
11823 "Type unsupported without MMA");
11824 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
11825 "Type unsupported without paired vector support");
11828 unsigned NumVecs = 2;
11829 if (StoreVT == MVT::v512i1) {
11830 if (Subtarget.isISAFuture()) {
11831 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11833 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
11836 Value2 =
SDValue(ExtNode, 1);
11841 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
11844 if (Subtarget.isISAFuture()) {
11854 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
11868 if (
Op.getValueType() == MVT::v4i32) {
11885 LHS, RHS, DAG, dl, MVT::v4i32);
11888 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
11893 }
else if (
Op.getValueType() == MVT::v16i8) {
11899 LHS, RHS, DAG, dl, MVT::v8i16);
11904 LHS, RHS, DAG, dl, MVT::v8i16);
11912 for (
unsigned i = 0; i != 8; ++i) {
11913 if (isLittleEndian) {
11915 Ops[i*2+1] = 2*i+16;
11918 Ops[i*2+1] = 2*i+1+16;
11921 if (isLittleEndian)
11931 bool IsStrict =
Op->isStrictFPOpcode();
11932 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
11933 !Subtarget.hasP9Vector())
11943 "Should only be called for ISD::FP_EXTEND");
11947 if (
Op.getValueType() != MVT::v2f64 ||
11948 Op.getOperand(0).getValueType() != MVT::v2f32)
11960 "Node should have 2 operands with second one being a constant!");
11972 int DWord =
Idx >> 1;
11995 LD->getMemoryVT(),
LD->getMemOperand());
12008 LD->getMemoryVT(),
LD->getMemOperand());
12023 for (
unsigned i = 0, ie =
U->getNumOperands(); i != ie; ++i) {
12024 if (
U->getOperand(i).getOpcode() !=
ISD::UADDO &&
12038 EVT VT =
Op.getNode()->getValueType(0);
12060 EVT VT =
Op.getNode()->getValueType(0);
12082 switch (
Op.getOpcode()) {
12102 return LowerSSUBO(
Op, DAG);
12114 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
12135 return LowerSET_ROUNDING(
Op, DAG);
12142 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
12143 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
12155 return LowerFP_ROUND(
Op, DAG);
12168 return LowerINTRINSIC_VOID(
Op, DAG);
12170 return LowerBSWAP(
Op, DAG);
12172 return LowerATOMIC_CMP_SWAP(
Op, DAG);
12174 return LowerATOMIC_LOAD_STORE(
Op, DAG);
12176 return LowerIS_FPCLASS(
Op, DAG);
12184 switch (
N->getOpcode()) {
12186 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
12203 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
12206 assert(
N->getValueType(0) == MVT::i1 &&
12207 "Unexpected result type for CTR decrement intrinsic");
12209 N->getValueType(0));
12219 switch (
N->getConstantOperandVal(0)) {
12220 case Intrinsic::ppc_pack_longdouble:
12222 N->getOperand(2),
N->getOperand(1)));
12224 case Intrinsic::ppc_maxfe:
12225 case Intrinsic::ppc_minfe:
12226 case Intrinsic::ppc_fnmsub:
12227 case Intrinsic::ppc_convert_f128_to_ppcf128:
12237 EVT VT =
N->getValueType(0);
12239 if (VT == MVT::i64) {
12252 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
12256 Results.push_back(LoweredValue);
12257 if (
N->isStrictFPOpcode())
12262 if (!
N->getValueType(0).isVector())
12317 if (isa<LoadInst>(Inst))
12328 unsigned AtomicSize,
12329 unsigned BinOpcode,
12330 unsigned CmpOpcode,
12331 unsigned CmpPred)
const {
12335 auto LoadMnemonic = PPC::LDARX;
12336 auto StoreMnemonic = PPC::STDCX;
12337 switch (AtomicSize) {
12341 LoadMnemonic = PPC::LBARX;
12342 StoreMnemonic = PPC::STBCX;
12343 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12346 LoadMnemonic = PPC::LHARX;
12347 StoreMnemonic = PPC::STHCX;
12348 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12351 LoadMnemonic = PPC::LWARX;
12352 StoreMnemonic = PPC::STWCX;
12355 LoadMnemonic = PPC::LDARX;
12356 StoreMnemonic = PPC::STDCX;
12372 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12374 F->insert(It, loopMBB);
12376 F->insert(It, loop2MBB);
12377 F->insert(It, exitMBB);
12383 Register TmpReg = (!BinOpcode) ? incr :
12385 : &PPC::GPRCRegClass);
12410 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
12417 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
12419 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
12447 switch(
MI.getOpcode()) {
12451 return TII->isSignExtended(
MI.getOperand(1).getReg(),
12452 &
MI.getMF()->getRegInfo());
12476 case PPC::EXTSB8_32_64:
12477 case PPC::EXTSB8_rec:
12478 case PPC::EXTSB_rec:
12481 case PPC::EXTSH8_32_64:
12482 case PPC::EXTSH8_rec:
12483 case PPC::EXTSH_rec:
12485 case PPC::EXTSWSLI:
12486 case PPC::EXTSWSLI_32_64:
12487 case PPC::EXTSWSLI_32_64_rec:
12488 case PPC::EXTSWSLI_rec:
12489 case PPC::EXTSW_32:
12490 case PPC::EXTSW_32_64:
12491 case PPC::EXTSW_32_64_rec:
12492 case PPC::EXTSW_rec:
12495 case PPC::SRAWI_rec:
12496 case PPC::SRAW_rec:
12505 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
12515 bool IsSignExtended =
12518 if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
12520 BuildMI(*BB,
MI, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
12521 .
addReg(
MI.getOperand(3).getReg());
12522 MI.getOperand(3).setReg(ValueReg);
12526 if (Subtarget.hasPartwordAtomics())
12534 bool is64bit = Subtarget.
isPPC64();
12536 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
12547 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12549 F->insert(It, loopMBB);
12551 F->insert(It, loop2MBB);
12552 F->insert(It, exitMBB);
12558 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12603 if (ptrA != ZeroReg) {
12605 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
12613 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
12614 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
12617 .
addImm(is8bit ? 28 : 27);
12618 if (!isLittleEndian)
12619 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
12621 .
addImm(is8bit ? 24 : 16);
12623 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
12628 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
12638 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
12642 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
12647 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
12651 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
12654 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
12666 unsigned ValueReg = SReg;
12667 unsigned CmpReg = Incr2Reg;
12668 if (CmpOpcode == PPC::CMPW) {
12670 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
12674 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
12676 ValueReg = ValueSReg;
12708 .
addImm(is8bit ? 24 : 16)
12729 Register DstReg =
MI.getOperand(0).getReg();
12731 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
12732 Register mainDstReg =
MRI.createVirtualRegister(RC);
12733 Register restoreDstReg =
MRI.createVirtualRegister(RC);
12736 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
12737 "Invalid Pointer Size!");
12785 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
12786 Register BufReg =
MI.getOperand(1).getReg();
12801 BaseReg = Subtarget.
isPPC64() ? PPC::X1 : PPC::R1;
12803 BaseReg = Subtarget.
isPPC64() ? PPC::BP8 : PPC::BP;
12806 TII->get(Subtarget.
isPPC64() ? PPC::STD : PPC::STW))
12829 TII->get(Subtarget.
isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
12850 TII->get(PPC::PHI), DstReg)
12854 MI.eraseFromParent();
12868 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
12869 "Invalid Pointer Size!");
12872 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12875 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
12876 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
12890 Register BufReg =
MI.getOperand(0).getReg();
12895 if (PVT == MVT::i64) {
12907 if (PVT == MVT::i64) {
12919 if (PVT == MVT::i64) {
12931 if (PVT == MVT::i64) {
12943 if (PVT == MVT::i64 && Subtarget.
isSVR4ABI()) {
12953 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
12956 MI.eraseFromParent();
12972 "Unexpected stack alignment");
12976 unsigned StackProbeSize =
12979 StackProbeSize &= ~(StackAlign - 1);
12980 return StackProbeSize ? StackProbeSize : StackAlign;
12992 const bool isPPC64 = Subtarget.
isPPC64();
13024 MF->
insert(MBBIter, TestMBB);
13025 MF->
insert(MBBIter, BlockMBB);
13026 MF->
insert(MBBIter, TailMBB);
13031 Register DstReg =
MI.getOperand(0).getReg();
13032 Register NegSizeReg =
MI.getOperand(1).getReg();
13034 Register FinalStackPtr =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13035 Register FramePointer =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13036 Register ActualNegSizeReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13042 if (!
MRI.hasOneNonDBGUse(NegSizeReg))
13044 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
13050 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
13051 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
13053 .
addDef(ActualNegSizeReg)
13055 .
add(
MI.getOperand(2))
13056 .
add(
MI.getOperand(3));
13062 .
addReg(ActualNegSizeReg);
13065 int64_t NegProbeSize = -(int64_t)ProbeSize;
13066 assert(isInt<32>(NegProbeSize) &&
"Unhandled probe size!");
13067 Register ScratchReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13068 if (!isInt<16>(NegProbeSize)) {
13069 Register TempReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13071 .
addImm(NegProbeSize >> 16);
13075 .
addImm(NegProbeSize & 0xFFFF);
13082 Register Div =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13084 .
addReg(ActualNegSizeReg)
13086 Register Mul =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13090 Register NegMod =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13093 .
addReg(ActualNegSizeReg);
13102 Register CmpResult =
MRI.createVirtualRegister(&PPC::CRRCRegClass);
13103 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
13128 MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13130 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
13131 MaxCallFrameSizeReg)
13132 .
add(
MI.getOperand(2))
13133 .
add(
MI.getOperand(3));
13134 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
13136 .
addReg(MaxCallFrameSizeReg);
13145 MI.eraseFromParent();
13147 ++NumDynamicAllocaProbed;
13152 switch (
MI.getOpcode()) {
13153 case PPC::SELECT_CC_I4:
13154 case PPC::SELECT_CC_I8:
13155 case PPC::SELECT_CC_F4:
13156 case PPC::SELECT_CC_F8:
13157 case PPC::SELECT_CC_F16:
13158 case PPC::SELECT_CC_VRRC:
13159 case PPC::SELECT_CC_VSFRC:
13160 case PPC::SELECT_CC_VSSRC:
13161 case PPC::SELECT_CC_VSRC:
13162 case PPC::SELECT_CC_SPE4:
13163 case PPC::SELECT_CC_SPE:
13171 switch (
MI.getOpcode()) {
13172 case PPC::SELECT_I4:
13173 case PPC::SELECT_I8:
13174 case PPC::SELECT_F4:
13175 case PPC::SELECT_F8:
13176 case PPC::SELECT_F16:
13177 case PPC::SELECT_SPE:
13178 case PPC::SELECT_SPE4:
13179 case PPC::SELECT_VRRC:
13180 case PPC::SELECT_VSFRC:
13181 case PPC::SELECT_VSSRC:
13182 case PPC::SELECT_VSRC:
13192 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
13193 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
13195 MI.getOpcode() == TargetOpcode::PATCHPOINT &&
13208 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
13209 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
13211 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
13212 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
13226 if (Subtarget.hasISEL() &&
13227 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13228 MI.getOpcode() == PPC::SELECT_CC_I8 ||
13229 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
13231 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13232 MI.getOpcode() == PPC::SELECT_CC_I8)
13233 Cond.push_back(
MI.getOperand(4));
13236 Cond.push_back(
MI.getOperand(1));
13239 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
13240 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
13256 F->insert(It, copy0MBB);
13257 F->insert(It, sinkMBB);
13261 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
13276 .
addReg(
MI.getOperand(1).getReg())
13279 unsigned SelectPred =
MI.getOperand(4).getImm();
13282 .
addReg(
MI.getOperand(1).getReg())
13299 .
addReg(
MI.getOperand(3).getReg())
13301 .
addReg(
MI.getOperand(2).getReg())
13303 }
else if (
MI.getOpcode() == PPC::ReadTB) {
13319 F->insert(It, readMBB);
13320 F->insert(It, sinkMBB);
13341 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
13351 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
13353 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
13355 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
13357 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
13360 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
13362 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
13364 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
13366 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
13369 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
13371 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
13373 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
13375 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
13378 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
13380 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
13382 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
13384 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
13387 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
13389 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
13391 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
13393 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
13396 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
13398 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
13400 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
13402 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
13405 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
13407 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
13409 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
13411 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
13414 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
13416 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
13418 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
13420 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
13423 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
13425 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
13427 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
13429 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
13432 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
13434 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
13436 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
13438 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
13441 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
13443 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
13445 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
13447 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
13449 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
13450 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
13451 (Subtarget.hasPartwordAtomics() &&
13452 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
13453 (Subtarget.hasPartwordAtomics() &&
13454 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
13455 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
13457 auto LoadMnemonic = PPC::LDARX;
13458 auto StoreMnemonic = PPC::STDCX;
13459 switch (
MI.getOpcode()) {
13462 case PPC::ATOMIC_CMP_SWAP_I8:
13463 LoadMnemonic = PPC::LBARX;
13464 StoreMnemonic = PPC::STBCX;
13465 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13467 case PPC::ATOMIC_CMP_SWAP_I16:
13468 LoadMnemonic = PPC::LHARX;
13469 StoreMnemonic = PPC::STHCX;
13470 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13472 case PPC::ATOMIC_CMP_SWAP_I32:
13473 LoadMnemonic = PPC::LWARX;
13474 StoreMnemonic = PPC::STWCX;
13476 case PPC::ATOMIC_CMP_SWAP_I64:
13477 LoadMnemonic = PPC::LDARX;
13478 StoreMnemonic = PPC::STDCX;
13486 Register oldval =
MI.getOperand(3).getReg();
13487 Register newval =
MI.getOperand(4).getReg();
13493 F->insert(It, loop1MBB);
13494 F->insert(It, loop2MBB);
13495 F->insert(It, exitMBB);
13516 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
13542 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
13543 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
13547 bool is64bit = Subtarget.
isPPC64();
13549 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
13554 Register oldval =
MI.getOperand(3).getReg();
13555 Register newval =
MI.getOperand(4).getReg();
13561 F->insert(It, loop1MBB);
13562 F->insert(It, loop2MBB);
13563 F->insert(It, exitMBB);
13570 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13589 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13621 if (ptrA != ZeroReg) {
13623 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13632 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13633 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
13636 .
addImm(is8bit ? 28 : 27);
13637 if (!isLittleEndian)
13638 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13640 .
addImm(is8bit ? 24 : 16);
13642 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13647 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13652 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
13655 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
13662 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13666 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13669 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
13672 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
13677 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13694 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13718 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
13743 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
13751 }
else if (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
13752 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT ||
13753 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
13754 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
13755 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
13756 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
13759 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
13760 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
13764 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
13768 .
addReg(
MI.getOperand(1).getReg())
13771 MI.getOperand(0).getReg())
13772 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
13773 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
13779 MI.getOperand(0).getReg())
13781 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
13783 unsigned Imm =
MI.getOperand(1).getImm();
13786 MI.getOperand(0).getReg())
13788 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
13790 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13793 if (
MRI.use_empty(OldFPSCRReg))
13794 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
13796 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13807 unsigned Mode =
MI.getOperand(1).getImm();
13808 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
13812 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
13815 }
else if (
MI.getOpcode() == PPC::SETRND) {
13823 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
13824 if (Subtarget.hasDirectMove()) {
13825 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
13829 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
13832 if (RC == &PPC::F8RCRegClass) {
13835 "Unsupported RegClass.");
13837 StoreOp = PPC::STFD;
13842 (RegInfo.
getRegClass(DestReg) == &PPC::F8RCRegClass) &&
13843 "Unsupported RegClass.");
13876 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13879 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13893 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
13901 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
13902 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
13908 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
13915 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
13924 }
else if (
MI.getOpcode() == PPC::SETFLM) {
13928 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13929 if (
MRI.use_empty(OldFPSCRReg))
13930 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
13932 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13935 Register NewFPSCRReg =
MI.getOperand(1).getReg();
13941 }
else if (
MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
13942 MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
13944 }
else if (
MI.getOpcode() == PPC::SPLIT_QUADWORD) {
13951 .
addUse(Src, 0, PPC::sub_gp8_x1);
13954 .
addUse(Src, 0, PPC::sub_gp8_x0);
13955 }
else if (
MI.getOpcode() == PPC::LQX_PSEUDO ||
13956 MI.getOpcode() == PPC::STQX_PSEUDO) {
13962 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
13968 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
13969 :
TII->get(PPC::STQ))
13977 MI.eraseFromParent();
13990 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
13993 return RefinementSteps;
13999 EVT VT =
Op.getValueType();
14002 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
14026PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
14029 EVT VT =
Op.getValueType();
14030 if (VT != MVT::f64 &&
14031 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
14038 int Enabled,
int &RefinementSteps,
14039 bool &UseOneConstNR,
14040 bool Reciprocal)
const {
14042 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
14043 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
14044 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14045 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14051 UseOneConstNR = !Subtarget.needsTwoConstNR();
14059 int &RefinementSteps)
const {
14061 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
14062 (VT == MVT::f64 && Subtarget.hasFRE()) ||
14063 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14064 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14072unsigned PPCTargetLowering::combineRepeatedFPDivisors()
const {
14110 unsigned Bytes,
int Dist,
14120 int FI = cast<FrameIndexSDNode>(Loc)->getIndex();
14121 int BFI = cast<FrameIndexSDNode>(BaseLoc)->getIndex();
14124 if (FS != BFS || FS != (
int)Bytes)
return false;
14128 SDValue Base1 = Loc, Base2 = BaseLoc;
14129 int64_t Offset1 = 0, Offset2 = 0;
14132 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
14142 if (isGA1 && isGA2 && GV1 == GV2)
14143 return Offset1 == (Offset2 + Dist*Bytes);
14150 unsigned Bytes,
int Dist,
14153 EVT VT = LS->getMemoryVT();
14154 SDValue Loc = LS->getBasePtr();
14160 switch (
N->getConstantOperandVal(1)) {
14161 default:
return false;
14162 case Intrinsic::ppc_altivec_lvx:
14163 case Intrinsic::ppc_altivec_lvxl:
14164 case Intrinsic::ppc_vsx_lxvw4x:
14165 case Intrinsic::ppc_vsx_lxvw4x_be:
14168 case Intrinsic::ppc_vsx_lxvd2x:
14169 case Intrinsic::ppc_vsx_lxvd2x_be:
14172 case Intrinsic::ppc_altivec_lvebx:
14175 case Intrinsic::ppc_altivec_lvehx:
14178 case Intrinsic::ppc_altivec_lvewx:
14188 switch (
N->getConstantOperandVal(1)) {
14189 default:
return false;
14190 case Intrinsic::ppc_altivec_stvx:
14191 case Intrinsic::ppc_altivec_stvxl:
14192 case Intrinsic::ppc_vsx_stxvw4x:
14195 case Intrinsic::ppc_vsx_stxvd2x:
14198 case Intrinsic::ppc_vsx_stxvw4x_be:
14201 case Intrinsic::ppc_vsx_stxvd2x_be:
14204 case Intrinsic::ppc_altivec_stvebx:
14207 case Intrinsic::ppc_altivec_stvehx:
14210 case Intrinsic::ppc_altivec_stvewx:
14227 SDValue Chain = LD->getChain();
14228 EVT VT = LD->getMemoryVT();
14237 while (!Queue.empty()) {
14238 SDNode *ChainNext = Queue.pop_back_val();
14239 if (!Visited.
insert(ChainNext).second)
14242 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(ChainNext)) {
14246 if (!Visited.
count(ChainLD->getChain().getNode()))
14247 Queue.push_back(ChainLD->getChain().getNode());
14249 for (
const SDUse &O : ChainNext->
ops())
14250 if (!Visited.
count(O.getNode()))
14251 Queue.push_back(O.getNode());
14253 LoadRoots.
insert(ChainNext);
14264 for (
SDNode *
I : LoadRoots) {
14265 Queue.push_back(
I);
14267 while (!Queue.empty()) {
14268 SDNode *LoadRoot = Queue.pop_back_val();
14269 if (!Visited.
insert(LoadRoot).second)
14272 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(LoadRoot))
14277 if (((isa<MemSDNode>(U) &&
14278 cast<MemSDNode>(U)->getChain().
getNode() == LoadRoot) ||
14281 Queue.push_back(U);
14314 auto Final = Shifted;
14325 DAGCombinerInfo &DCI)
const {
14333 if (!DCI.isAfterLegalizeDAG())
14338 for (
const SDNode *U :
N->users())
14343 auto OpSize =
N->getOperand(0).getValueSizeInBits();
14347 if (OpSize <
Size) {
14365 DAGCombinerInfo &DCI)
const {
14369 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
14380 N->getValueType(0) != MVT::i1)
14383 if (
N->getOperand(0).getValueType() != MVT::i32 &&
14384 N->getOperand(0).getValueType() != MVT::i64)
14392 cast<CondCodeSDNode>(
N->getOperand(
14394 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
14405 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
14428 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
14429 N->getOperand(0).getOpcode() !=
ISD::OR &&
14430 N->getOperand(0).getOpcode() !=
ISD::XOR &&
14440 N->getOperand(1).getOpcode() !=
ISD::AND &&
14441 N->getOperand(1).getOpcode() !=
ISD::OR &&
14442 N->getOperand(1).getOpcode() !=
ISD::XOR &&
14455 for (
unsigned i = 0; i < 2; ++i) {
14459 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
14460 isa<ConstantSDNode>(
N->getOperand(i)))
14471 while (!BinOps.
empty()) {
14479 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
14513 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14514 if (isa<ConstantSDNode>(Inputs[i]))
14537 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
14559 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14562 if (isa<ConstantSDNode>(Inputs[i]))
14568 std::list<HandleSDNode> PromOpHandles;
14569 for (
auto &PromOp : PromOps)
14570 PromOpHandles.emplace_back(PromOp);
14577 while (!PromOpHandles.empty()) {
14579 PromOpHandles.pop_back();
14585 if (!isa<ConstantSDNode>(PromOp.
getOperand(0)) &&
14588 PromOpHandles.emplace_front(PromOp);
14593 if (isa<ConstantSDNode>(RepValue))
14602 default:
C = 0;
break;
14607 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
14615 PromOpHandles.emplace_front(PromOp);
14622 for (
unsigned i = 0; i < 2; ++i)
14623 if (isa<ConstantSDNode>(Ops[
C+i]))
14632 return N->getOperand(0);
14640 DAGCombinerInfo &DCI)
const {
14658 if (
N->getValueType(0) != MVT::i32 &&
14659 N->getValueType(0) != MVT::i64)
14662 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
14663 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.
isPPC64())))
14666 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
14667 N->getOperand(0).getOpcode() !=
ISD::OR &&
14668 N->getOperand(0).getOpcode() !=
ISD::XOR &&
14679 while (!BinOps.
empty()) {
14687 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
14718 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14719 if (isa<ConstantSDNode>(Inputs[i]))
14730 SelectTruncOp[0].
insert(std::make_pair(
User,
14734 SelectTruncOp[0].
insert(std::make_pair(
User,
14737 SelectTruncOp[1].
insert(std::make_pair(
User,
14743 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
14752 SelectTruncOp[0].
insert(std::make_pair(
User,
14756 SelectTruncOp[0].
insert(std::make_pair(
User,
14759 SelectTruncOp[1].
insert(std::make_pair(
User,
14765 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
14766 bool ReallyNeedsExt =
false;
14770 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14771 if (isa<ConstantSDNode>(Inputs[i]))
14775 Inputs[i].getOperand(0).getValueSizeInBits();
14776 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
14781 OpBits-PromBits))) ||
14784 (OpBits-(PromBits-1)))) {
14785 ReallyNeedsExt =
true;
14793 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14797 if (isa<ConstantSDNode>(Inputs[i]))
14800 SDValue InSrc = Inputs[i].getOperand(0);
14814 std::list<HandleSDNode> PromOpHandles;
14815 for (
auto &PromOp : PromOps)
14816 PromOpHandles.emplace_back(PromOp);
14822 while (!PromOpHandles.empty()) {
14824 PromOpHandles.pop_back();
14828 default:
C = 0;
break;
14833 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
14841 PromOpHandles.emplace_front(PromOp);
14851 (SelectTruncOp[1].count(PromOp.
getNode()) &&
14853 PromOpHandles.emplace_front(PromOp);
14862 for (
unsigned i = 0; i < 2; ++i) {
14863 if (!isa<ConstantSDNode>(Ops[
C+i]))
14880 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
14881 if (SI0 != SelectTruncOp[0].
end())
14883 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
14884 if (SI1 != SelectTruncOp[1].
end())
14893 if (!ReallyNeedsExt)
14894 return N->getOperand(0);
14901 N->getValueSizeInBits(0), PromBits),
14902 dl,
N->getValueType(0)));
14905 "Invalid extension type");
14908 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
14916 DAGCombinerInfo &DCI)
const {
14918 "Should be called with a SETCC node");
14936 EVT VT =
N->getValueType(0);
14937 EVT OpVT =
LHS.getValueType();
14943 return DAGCombineTruncBoolExt(
N, DCI);
14948 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(
Op.getNode()))
14950 Op.getValueType() == MVT::f64;
14962combineElementTruncationToVectorTruncation(
SDNode *
N,
14963 DAGCombinerInfo &DCI)
const {
14965 "Should be called with a BUILD_VECTOR node");
14970 SDValue FirstInput =
N->getOperand(0);
14972 "The input operand must be an fp-to-int conversion.");
14981 bool IsSplat =
true;
14986 EVT TargetVT =
N->getValueType(0);
14987 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
14988 SDValue NextOp =
N->getOperand(i);
14992 if (NextConversion != FirstConversion)
15000 if (
N->getOperand(i) != FirstInput)
15011 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
15012 SDValue In =
N->getOperand(i).getOperand(0);
15035 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
15037 return DAG.
getNode(Opcode, dl, TargetVT, BV);
15050 "Should be called with a BUILD_VECTOR node");
15055 if (!
N->getValueType(0).getVectorElementType().isByteSized())
15058 bool InputsAreConsecutiveLoads =
true;
15059 bool InputsAreReverseConsecutive =
true;
15060 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
15061 SDValue FirstInput =
N->getOperand(0);
15062 bool IsRoundOfExtLoad =
false;
15067 FirstLoad = cast<LoadSDNode>(FirstInput.
getOperand(0));
15072 N->getNumOperands() == 1)
15075 if (!IsRoundOfExtLoad)
15076 FirstLoad = cast<LoadSDNode>(FirstInput);
15080 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
15082 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
15085 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
15091 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
15092 LoadSDNode *LD1 = cast<LoadSDNode>(PreviousInput);
15093 LoadSDNode *LD2 = cast<LoadSDNode>(NextInput);
15102 InputsAreConsecutiveLoads =
false;
15104 InputsAreReverseConsecutive =
false;
15107 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
15112 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
15113 "The loads cannot be both consecutive and reverse consecutive.");
15117 if (InputsAreConsecutiveLoads) {
15118 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
15122 ReturnSDVal = WideLoad;
15123 }
else if (InputsAreReverseConsecutive) {
15125 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
15130 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
15134 DAG.
getUNDEF(
N->getValueType(0)), Ops);
15138 for (
auto *LD : InputLoads)
15140 return ReturnSDVal;
15157 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
15159 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
15161 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
15162 CorrectElems = CorrectElems >> 8;
15163 Elems = Elems >> 8;
15170 EVT VT =
N->getValueType(0);
15208 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
15228 if (Input && Input != Extract.
getOperand(0))
15234 Elems = Elems << 8;
15243 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
15244 if (!isSExtOfVecExtract(
N->getOperand(i))) {
15251 int TgtElemArrayIdx;
15253 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
15254 if (InputSize + OutputSize == 40)
15255 TgtElemArrayIdx = 0;
15256 else if (InputSize + OutputSize == 72)
15257 TgtElemArrayIdx = 1;
15258 else if (InputSize + OutputSize == 48)
15259 TgtElemArrayIdx = 2;
15260 else if (InputSize + OutputSize == 80)
15261 TgtElemArrayIdx = 3;
15262 else if (InputSize + OutputSize == 96)
15263 TgtElemArrayIdx = 4;
15267 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
15269 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
15270 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
15271 if (Elems != CorrectElems) {
15287 if (
N->getValueType(0) != MVT::v1i128)
15290 SDValue Operand =
N->getOperand(0);
15296 auto *LD = cast<LoadSDNode>(Operand);
15297 EVT MemoryType = LD->getMemoryVT();
15301 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
15302 MemoryType == MVT::i32 || MemoryType == MVT::i64;
15305 if (!ValidLDType ||
15311 LD->getChain(), LD->getBasePtr(),
15315 DAG.
getVTList(MVT::v1i128, MVT::Other),
15316 LoadOps, MemoryType, LD->getMemOperand());
15320 DAGCombinerInfo &DCI)
const {
15322 "Should be called with a BUILD_VECTOR node");
15327 if (!Subtarget.hasVSX())
15333 SDValue FirstInput =
N->getOperand(0);
15335 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
15350 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
15359 if (Subtarget.isISA3_1()) {
15365 if (
N->getValueType(0) != MVT::v2f64)
15376 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
15380 SDValue Ext2 =
N->getOperand(1).getOperand(0);
15387 if (!Ext1Op || !Ext2Op)
15396 if (FirstElem == 0 && SecondElem == 1)
15398 else if (FirstElem == 2 && SecondElem == 3)
15406 return DAG.
getNode(NodeType, dl, MVT::v2f64,
15411 DAGCombinerInfo &DCI)
const {
15414 "Need an int -> FP conversion node here");
15425 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
15427 if (!
Op.getOperand(0).getValueType().isSimple())
15429 if (
Op.getOperand(0).getValueType().getSimpleVT() <=
MVT(MVT::i1) ||
15430 Op.getOperand(0).getValueType().getSimpleVT() >
MVT(MVT::i64))
15433 SDValue FirstOperand(
Op.getOperand(0));
15434 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
15435 (FirstOperand.getValueType() == MVT::i8 ||
15436 FirstOperand.getValueType() == MVT::i16);
15437 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
15439 bool DstDouble =
Op.getValueType() == MVT::f64;
15440 unsigned ConvOp =
Signed ?
15446 LoadSDNode *LDN = cast<LoadSDNode>(FirstOperand.getNode());
15455 SDValue ExtOps[] = { Ld, WidthConst };
15457 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
15459 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
15467 if (
Op.getOperand(0).getValueType() == MVT::i32)
15471 "UINT_TO_FP is supported only with FPCVT");
15475 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
15480 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
15487 Subtarget.hasFPCVT()) ||
15489 SDValue Src =
Op.getOperand(0).getOperand(0);
15490 if (Src.getValueType() == MVT::f32) {
15492 DCI.AddToWorklist(Src.getNode());
15493 }
else if (Src.getValueType() != MVT::f64) {
15505 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
15508 DCI.AddToWorklist(
FP.getNode());
15532 switch (
N->getOpcode()) {
15537 Chain = LD->getChain();
15538 Base = LD->getBasePtr();
15539 MMO = LD->getMemOperand();
15558 MVT VecTy =
N->getValueType(0).getSimpleVT();
15566 Chain = Load.getValue(1);
15572 if (VecTy != MVT::v2f64) {
15599 switch (
N->getOpcode()) {
15604 Chain = ST->getChain();
15605 Base = ST->getBasePtr();
15606 MMO = ST->getMemOperand();
15626 SDValue Src =
N->getOperand(SrcOpnd);
15627 MVT VecTy = Src.getValueType().getSimpleVT();
15630 if (VecTy != MVT::v2f64) {
15636 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
15642 StoreOps, VecTy, MMO);
15649 DAGCombinerInfo &DCI)
const {
15652 unsigned Opcode =
N->getOperand(1).getOpcode();
15654 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
15658 &&
"Not a FP_TO_INT Instruction!");
15660 SDValue Val =
N->getOperand(1).getOperand(Strict ? 1 : 0);
15661 EVT Op1VT =
N->getOperand(1).getValueType();
15664 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
15668 bool ValidTypeForStoreFltAsInt =
15669 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.
isPPC64()) ||
15670 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
15673 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
15676 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
15677 cast<StoreSDNode>(
N)->isTruncatingStore() || !ValidTypeForStoreFltAsInt)
15684 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
15690 cast<StoreSDNode>(
N)->getMemoryVT(),
15691 cast<StoreSDNode>(
N)->getMemOperand());
15699 bool PrevElemFromFirstVec = Mask[0] < NumElts;
15700 for (
int i = 1, e = Mask.size(); i < e; i++) {
15701 if (PrevElemFromFirstVec && Mask[i] < NumElts)
15703 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
15705 PrevElemFromFirstVec = !PrevElemFromFirstVec;
15717 FirstOp =
Op.getOperand(i);
15724 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
15734 Op =
Op.getOperand(0);
15750 int RHSFirstElt,
int RHSLastElt,
int HalfVec,
unsigned LHSNumValidElts,
15751 unsigned RHSNumValidElts,
const PPCSubtarget &Subtarget) {
15753 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - LHSNumValidElts;
15755 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - RHSNumValidElts;
15756 for (
int I = 0, E = ShuffV.
size();
I < E; ++
I) {
15757 int Idx = ShuffV[
I];
15758 if (
Idx >= LHSFirstElt &&
Idx <= LHSLastElt)
15759 ShuffV[
I] += LHSEltFixup;
15760 else if (
Idx >= RHSFirstElt &&
Idx <= RHSLastElt)
15761 ShuffV[
I] += RHSEltFixup;
15772 SDLoc dl(OrigSToV);
15775 "Expecting a SCALAR_TO_VECTOR here");
15788 "Cannot produce a permuted scalar_to_vector for one element vector");
15790 unsigned ResultInElt = NumElts / 2;
15792 NewMask[ResultInElt] =
Idx->getZExtValue();
15801 int HalfVec,
int LHSLastElementDefined,
15802 int RHSLastElementDefined) {
15803 for (
int Index : ShuffV) {
15807 if ((LHSLastElementDefined >= 0) && (Index < HalfVec) &&
15808 (Index > LHSLastElementDefined))
15811 if ((RHSLastElementDefined >= 0) &&
15812 (Index > HalfVec + RHSLastElementDefined))
15819 int ScalarSize,
uint64_t ShuffleEltWidth,
unsigned &NumValidElts,
15820 int FirstElt,
int &LastElt,
SDValue VecShuffOperand,
SDValue SToVNode,
15836 LastElt = (
uint64_t)ScalarSize > ShuffleEltWidth
15837 ? ScalarSize / ShuffleEltWidth - 1 + FirstElt
15840 if (SToVPermuted.
getValueType() != VecShuffOperandType)
15841 SToVPermuted = DAG.
getBitcast(VecShuffOperandType, SToVPermuted);
15842 return SToVPermuted;
15862 int NumElts =
LHS.getValueType().getVectorNumElements();
15872 if (!Subtarget.hasDirectMove())
15882 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
15891 if (SToVLHS || SToVRHS) {
15894 int ShuffleNumElts = ShuffV.
size();
15895 int HalfVec = ShuffleNumElts / 2;
15901 unsigned LHSNumValidElts = HalfVec;
15902 unsigned RHSNumValidElts = HalfVec;
15907 int LHSFirstElt = 0;
15908 int RHSFirstElt = ShuffleNumElts;
15909 int LHSLastElt = -1;
15910 int RHSLastElt = -1;
15918 int LHSScalarSize = 0;
15919 int RHSScalarSize = 0;
15922 if (!IsLittleEndian && LHSScalarSize >= 64)
15927 if (!IsLittleEndian && RHSScalarSize >= 64)
15930 if (LHSScalarSize != 0)
15932 LHSScalarSize, ShuffleEltWidth, LHSNumValidElts, LHSFirstElt,
15933 LHSLastElt, LHS, SToVLHS, DAG, Subtarget);
15934 if (RHSScalarSize != 0)
15936 RHSScalarSize, ShuffleEltWidth, RHSNumValidElts, RHSFirstElt,
15937 RHSLastElt, RHS, SToVRHS, DAG, Subtarget);
15948 ShuffV, LHSFirstElt, LHSLastElt, RHSFirstElt, RHSLastElt, HalfVec,
15949 LHSNumValidElts, RHSNumValidElts, Subtarget);
15954 if (!isa<ShuffleVectorSDNode>(Res))
15956 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
15975 if (IsLittleEndian) {
15978 if (Mask[0] < NumElts)
15979 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
15983 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
15988 for (
int i = 0, e =
Mask.size(); i <
e; i += 2) {
15992 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
15997 if (Mask[0] < NumElts)
15998 for (
int i = 0, e =
Mask.size(); i <
e; i += 2) {
16002 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
16007 for (
int i = 1, e =
Mask.size(); i <
e; i += 2) {
16011 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
16018 cast<BuildVectorSDNode>(TheSplat.
getNode())->getSplatValue();
16021 if (IsLittleEndian)
16030 DAGCombinerInfo &DCI)
const {
16032 "Not a reverse memop pattern!");
16037 auto I =
Mask.rbegin();
16038 auto E =
Mask.rend();
16040 for (;
I != E; ++
I) {
16057 if (!Subtarget.hasP9Vector())
16060 if(!IsElementReverse(SVN))
16068 if (
Use.getResNo() == 0 &&
16099 if (IntrinsicID == Intrinsic::ppc_stdcx)
16101 else if (IntrinsicID == Intrinsic::ppc_stwcx)
16103 else if (IntrinsicID == Intrinsic::ppc_sthcx)
16105 else if (IntrinsicID == Intrinsic::ppc_stbcx)
16116 switch (
N->getOpcode()) {
16119 return combineADD(
N, DCI);
16128 !isa<ConstantSDNode>(Op2) ||
N->getValueType(0) != MVT::i64 ||
16138 if (!isUInt<32>(Imm))
16145 return combineSHL(
N, DCI);
16147 return combineSRA(
N, DCI);
16149 return combineSRL(
N, DCI);
16151 return combineMUL(
N, DCI);
16154 return combineFMALike(
N, DCI);
16157 return N->getOperand(0);
16161 return N->getOperand(0);
16167 return N->getOperand(0);
16173 return DAGCombineExtBoolTrunc(
N, DCI);
16175 return combineTRUNCATE(
N, DCI);
16177 if (
SDValue CSCC = combineSetCC(
N, DCI))
16181 return DAGCombineTruncBoolExt(
N, DCI);
16184 return combineFPToIntToFP(
N, DCI);
16187 LSBaseSDNode* LSBase = cast<LSBaseSDNode>(
N->getOperand(0));
16188 return combineVReverseMemOP(cast<ShuffleVectorSDNode>(
N), LSBase, DCI);
16190 return combineVectorShuffle(cast<ShuffleVectorSDNode>(
N), DCI.
DAG);
16193 EVT Op1VT =
N->getOperand(1).getValueType();
16194 unsigned Opcode =
N->getOperand(1).getOpcode();
16198 SDValue Val = combineStoreFPToInt(
N, DCI);
16205 SDValue Val= combineVReverseMemOP(SVN, cast<LSBaseSDNode>(
N), DCI);
16211 if (cast<StoreSDNode>(
N)->isUnindexed() && Opcode ==
ISD::BSWAP &&
16212 N->getOperand(1).getNode()->hasOneUse() &&
16213 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
16214 (Subtarget.hasLDBRX() && Subtarget.
isPPC64() && Op1VT == MVT::i64))) {
16218 EVT mVT = cast<StoreSDNode>(
N)->getMemoryVT();
16222 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
16229 if (Op1VT.
bitsGT(mVT)) {
16234 if (Op1VT == MVT::i64)
16239 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
16243 Ops, cast<StoreSDNode>(
N)->getMemoryVT(),
16244 cast<StoreSDNode>(
N)->getMemOperand());
16250 isa<ConstantSDNode>(
N->getOperand(1)) && Op1VT == MVT::i32) {
16252 EVT MemVT = cast<StoreSDNode>(
N)->getMemoryVT();
16262 cast<StoreSDNode>(
N)->setTruncatingStore(
true);
16271 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
16272 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
16279 EVT VT = LD->getValueType(0);
16286 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
16287 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
16298 auto ReplaceTwoFloatLoad = [&]() {
16299 if (VT != MVT::i64)
16314 if (!LD->hasNUsesOfValue(2, 0))
16317 auto UI = LD->user_begin();
16318 while (UI.getUse().getResNo() != 0) ++UI;
16320 while (UI.getUse().getResNo() != 0) ++UI;
16321 SDNode *RightShift = *UI;
16329 if (RightShift->getOpcode() !=
ISD::SRL ||
16330 !isa<ConstantSDNode>(RightShift->getOperand(1)) ||
16331 RightShift->getConstantOperandVal(1) != 32 ||
16332 !RightShift->hasOneUse())
16335 SDNode *Trunc2 = *RightShift->user_begin();
16345 Bitcast->getValueType(0) != MVT::f32)
16357 SDValue BasePtr = LD->getBasePtr();
16358 if (LD->isIndexed()) {
16360 "Non-pre-inc AM on PPC?");
16368 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
16369 LD->getPointerInfo(), LD->getAlign(),
16370 MMOFlags, LD->getAAInfo());
16376 LD->getPointerInfo().getWithOffset(4),
16379 if (LD->isIndexed()) {
16393 if (ReplaceTwoFloatLoad())
16396 EVT MemVT = LD->getMemoryVT();
16399 if (LD->isUnindexed() && VT.
isVector() &&
16402 !Subtarget.hasP8Vector() &&
16403 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
16404 VT == MVT::v4f32))) &&
16405 LD->getAlign() < ABIAlignment) {
16407 SDValue Chain = LD->getChain();
16436 MVT PermCntlTy, PermTy, LDTy;
16437 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
16438 : Intrinsic::ppc_altivec_lvsl;
16439 IntrLD = Intrinsic::ppc_altivec_lvx;
16440 IntrPerm = Intrinsic::ppc_altivec_vperm;
16441 PermCntlTy = MVT::v16i8;
16442 PermTy = MVT::v4i32;
16461 SDValue BaseLoadOps[] = { Chain, LDXIntID,
Ptr };
16465 BaseLoadOps, LDTy, BaseMMO);
16474 int IncValue = IncOffset;
16491 SDValue ExtraLoadOps[] = { Chain, LDXIntID,
Ptr };
16495 ExtraLoadOps, LDTy, ExtraMMO);
16506 if (isLittleEndian)
16508 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
16511 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
16514 Perm = Subtarget.hasAltivec()
16530 unsigned IID =
N->getConstantOperandVal(0);
16532 : Intrinsic::ppc_altivec_lvsl);
16533 if (IID ==
Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
16540 .
zext(
Add.getScalarValueSizeInBits()))) {
16541 SDNode *BasePtr =
Add->getOperand(0).getNode();
16542 for (
SDNode *U : BasePtr->users()) {
16544 U->getConstantOperandVal(0) == IID) {
16554 if (isa<ConstantSDNode>(
Add->getOperand(1))) {
16555 SDNode *BasePtr =
Add->getOperand(0).getNode();
16556 for (
SDNode *U : BasePtr->users()) {
16558 isa<ConstantSDNode>(U->getOperand(1)) &&
16559 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
16565 V->getConstantOperandVal(0) == IID) {
16577 (IID == Intrinsic::ppc_altivec_vmaxsw ||
16578 IID == Intrinsic::ppc_altivec_vmaxsh ||
16579 IID == Intrinsic::ppc_altivec_vmaxsb)) {
16595 V2.getOperand(1) == V1) {
16610 switch (
N->getConstantOperandVal(1)) {
16613 case Intrinsic::ppc_altivec_vsum4sbs:
16614 case Intrinsic::ppc_altivec_vsum4shs:
16615 case Intrinsic::ppc_altivec_vsum4ubs: {
16621 dyn_cast<BuildVectorSDNode>(
N->getOperand(3))) {
16622 APInt APSplatBits, APSplatUndef;
16623 unsigned SplatBitSize;
16626 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
16629 if (BVNIsConstantSplat && APSplatBits == 0)
16634 case Intrinsic::ppc_vsx_lxvw4x:
16635 case Intrinsic::ppc_vsx_lxvd2x:
16647 switch (
N->getConstantOperandVal(1)) {
16650 case Intrinsic::ppc_vsx_stxvw4x:
16651 case Intrinsic::ppc_vsx_stxvd2x:
16660 bool Is64BitBswapOn64BitTgt =
16661 Subtarget.
isPPC64() &&
N->getValueType(0) == MVT::i64;
16663 N->getOperand(0).hasOneUse();
16664 if (IsSingleUseNormalLd &&
16665 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
16666 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
16677 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
16678 MVT::i64 : MVT::i32, MVT::Other),
16679 Ops, LD->getMemoryVT(), LD->getMemOperand());
16683 if (
N->getValueType(0) == MVT::i16)
16700 !IsSingleUseNormalLd)
16702 LoadSDNode *LD = cast<LoadSDNode>(
N->getOperand(0));
16705 if (!LD->isSimple())
16707 SDValue BasePtr = LD->getBasePtr();
16709 LD->getPointerInfo(), LD->getAlign());
16714 LD->getMemOperand(), 4, 4);
16724 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
16733 if (!
N->getOperand(0).hasOneUse() &&
16734 !
N->getOperand(1).hasOneUse() &&
16735 !
N->getOperand(2).hasOneUse()) {
16738 SDNode *VCMPrecNode =
nullptr;
16740 SDNode *LHSN =
N->getOperand(0).getNode();
16746 VCMPrecNode =
User;
16758 SDNode *FlagUser =
nullptr;
16760 FlagUser ==
nullptr; ++UI) {
16761 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
16774 return SDValue(VCMPrecNode, 0);
16796 auto RHSAPInt =
RHS->getAsAPIntVal();
16797 if (!RHSAPInt.isIntN(64))
16800 unsigned Val = RHSAPInt.getZExtValue();
16801 auto isImpossibleCompare = [&]() {
16804 if (Val != 0 && Val != 1) {
16806 return N->getOperand(0);
16809 N->getOperand(0),
N->getOperand(4));
16814 unsigned StoreWidth = 0;
16817 if (
SDValue Impossible = isImpossibleCompare())
16831 auto *MemNode = cast<MemSDNode>(
LHS);
16834 DAG.
getVTList(MVT::i32, MVT::Other, MVT::Glue), Ops,
16835 MemNode->getMemoryVT(), MemNode->getMemOperand());
16839 if (
N->getOperand(0) ==
LHS.getValue(1))
16840 InChain =
LHS.getOperand(0);
16852 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
16858 assert(isDot &&
"Can't compare against a vector result!");
16860 if (
SDValue Impossible = isImpossibleCompare())
16863 bool BranchOnWhenPredTrue = (
CC ==
ISD::SETEQ) ^ (Val == 0);
16870 EVT VTs[] = {
LHS.getOperand(2).getValueType(), MVT::Glue };
16875 switch (
LHS.getConstantOperandVal(1)) {
16894 N->getOperand(4), CompNode.
getValue(1));
16899 return DAGCombineBuildVector(
N, DCI);
16910 EVT VT =
N->getValueType(0);
16911 if (VT == MVT::i64 && !Subtarget.
isPPC64())
16913 if ((VT != MVT::i32 && VT != MVT::i64) ||
16921 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
16941 const APInt &DemandedElts,
16943 unsigned Depth)
const {
16945 switch (
Op.getOpcode()) {
16949 if (cast<VTSDNode>(
Op.getOperand(2))->getVT() == MVT::i16)
16950 Known.
Zero = 0xFFFF0000;
16954 switch (
Op.getConstantOperandVal(0)) {
16956 case Intrinsic::ppc_altivec_vcmpbfp_p:
16957 case Intrinsic::ppc_altivec_vcmpeqfp_p:
16958 case Intrinsic::ppc_altivec_vcmpequb_p:
16959 case Intrinsic::ppc_altivec_vcmpequh_p:
16960 case Intrinsic::ppc_altivec_vcmpequw_p:
16961 case Intrinsic::ppc_altivec_vcmpequd_p:
16962 case Intrinsic::ppc_altivec_vcmpequq_p:
16963 case Intrinsic::ppc_altivec_vcmpgefp_p:
16964 case Intrinsic::ppc_altivec_vcmpgtfp_p:
16965 case Intrinsic::ppc_altivec_vcmpgtsb_p:
16966 case Intrinsic::ppc_altivec_vcmpgtsh_p:
16967 case Intrinsic::ppc_altivec_vcmpgtsw_p:
16968 case Intrinsic::ppc_altivec_vcmpgtsd_p:
16969 case Intrinsic::ppc_altivec_vcmpgtsq_p:
16970 case Intrinsic::ppc_altivec_vcmpgtub_p:
16971 case Intrinsic::ppc_altivec_vcmpgtuh_p:
16972 case Intrinsic::ppc_altivec_vcmpgtuw_p:
16973 case Intrinsic::ppc_altivec_vcmpgtud_p:
16974 case Intrinsic::ppc_altivec_vcmpgtuq_p:
16981 switch (
Op.getConstantOperandVal(1)) {
16984 case Intrinsic::ppc_load2r:
16986 Known.
Zero = 0xFFFF0000;
17017 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
17026 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
17028 LoopSize +=
TII->getInstSizeInBytes(J);
17033 if (LoopSize > 16 && LoopSize <= 32)
17047 if (Constraint.
size() == 1) {
17048 switch (Constraint[0]) {
17066 }
else if (Constraint ==
"wc") {
17068 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
17069 Constraint ==
"wf" || Constraint ==
"ws" ||
17070 Constraint ==
"wi" || Constraint ==
"ww") {
17083 Value *CallOperandVal =
info.CallOperandVal;
17086 if (!CallOperandVal)
17093 else if ((
StringRef(constraint) ==
"wa" ||
17105 switch (*constraint) {
17135std::pair<unsigned, const TargetRegisterClass *>
17139 if (Constraint.
size() == 1) {
17141 switch (Constraint[0]) {
17143 if (VT == MVT::i64 && Subtarget.
isPPC64())
17144 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
17145 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
17147 if (VT == MVT::i64 && Subtarget.
isPPC64())
17148 return std::make_pair(0U, &PPC::G8RCRegClass);
17149 return std::make_pair(0U, &PPC::GPRCRegClass);
17155 if (Subtarget.hasSPE()) {
17156 if (VT == MVT::f32 || VT == MVT::i32)
17157 return std::make_pair(0U, &PPC::GPRCRegClass);
17158 if (VT == MVT::f64 || VT == MVT::i64)
17159 return std::make_pair(0U, &PPC::SPERCRegClass);
17161 if (VT == MVT::f32 || VT == MVT::i32)
17162 return std::make_pair(0U, &PPC::F4RCRegClass);
17163 if (VT == MVT::f64 || VT == MVT::i64)
17164 return std::make_pair(0U, &PPC::F8RCRegClass);
17168 if (Subtarget.hasAltivec() && VT.
isVector())
17169 return std::make_pair(0U, &PPC::VRRCRegClass);
17170 else if (Subtarget.hasVSX())
17172 return std::make_pair(0U, &PPC::VFRCRegClass);
17175 return std::make_pair(0U, &PPC::CRRCRegClass);
17177 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
17179 return std::make_pair(0U, &PPC::CRBITRCRegClass);
17180 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
17181 Constraint ==
"wf" || Constraint ==
"wi") &&
17182 Subtarget.hasVSX()) {
17186 return std::make_pair(0U, &PPC::VSRCRegClass);
17187 if (VT == MVT::f32 && Subtarget.hasP8Vector())
17188 return std::make_pair(0U, &PPC::VSSRCRegClass);
17189 return std::make_pair(0U, &PPC::VSFRCRegClass);
17190 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
17191 if (VT == MVT::f32 && Subtarget.hasP8Vector())
17192 return std::make_pair(0U, &PPC::VSSRCRegClass);
17194 return std::make_pair(0U, &PPC::VSFRCRegClass);
17195 }
else if (Constraint ==
"lr") {
17196 if (VT == MVT::i64)
17197 return std::make_pair(0U, &PPC::LR8RCRegClass);
17199 return std::make_pair(0U, &PPC::LRRCRegClass);
17204 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
17208 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
17209 int VSNum = atoi(Constraint.
data() + 3);
17210 assert(VSNum >= 0 && VSNum <= 63 &&
17211 "Attempted to access a vsr out of range");
17213 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
17214 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
17219 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
17220 int RegNum = atoi(Constraint.
data() + 2);
17221 if (RegNum > 31 || RegNum < 0)
17223 if (VT == MVT::f32 || VT == MVT::i32)
17224 return Subtarget.hasSPE()
17225 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
17226 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
17227 if (VT == MVT::f64 || VT == MVT::i64)
17228 return Subtarget.hasSPE()
17229 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
17230 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
17234 std::pair<unsigned, const TargetRegisterClass *> R =
17243 if (R.first && VT == MVT::i64 && Subtarget.
isPPC64() &&
17244 PPC::GPRCRegClass.contains(R.first))
17245 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
17246 PPC::sub_32, &PPC::G8RCRegClass),
17247 &PPC::G8RCRegClass);
17250 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
17251 R.first = PPC::CR0;
17252 R.second = &PPC::CRRCRegClass;
17256 if (Subtarget.
isAIXABI() && !TM.getAIXExtendedAltivecABI()) {
17257 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
17258 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
17259 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
17260 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
17261 "default AIX AltiVec ABI and cannot be used\n";
17271 std::vector<SDValue> &Ops,
17276 if (Constraint.
size() > 1)
17279 char Letter = Constraint[0];
17294 EVT TCVT = MVT::i64;
17299 if (isInt<16>(
Value))
17303 if (isShiftedUInt<16, 16>(
Value))
17307 if (isShiftedInt<16, 16>(
Value))
17311 if (isUInt<16>(
Value))
17327 if (isInt<16>(-
Value))
17335 if (Result.getNode()) {
17336 Ops.push_back(Result);
17347 if (
I.getNumOperands() <= 1)
17349 if (!isa<ConstantSDNode>(Ops[1].
getNode()))
17351 auto IntrinsicID = Ops[1].getNode()->getAsZExtVal();
17352 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
17353 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
17356 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
17384 switch (AM.
Scale) {
17415 unsigned Depth =
Op.getConstantOperandVal(0);
17439 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
17447 unsigned Depth =
Op.getConstantOperandVal(0);
17454 bool isPPC64 = PtrVT == MVT::i64;
17460 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
17462 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
17472#define GET_REGISTER_MATCHER
17473#include "PPCGenAsmMatcher.inc"
17477 bool IsPPC64 = Subtarget.
isPPC64();
17490 if ((IsPPC64 && Reg == PPC::R2) || Reg == PPC::R0)
17496 Reg = Reg.id() - PPC::R0 + PPC::X0;
17518 if (isa<JumpTableSDNode>(GA) || isa<BlockAddressSDNode>(GA))
17536 unsigned Intrinsic)
const {
17537 switch (Intrinsic) {
17538 case Intrinsic::ppc_atomicrmw_xchg_i128:
17539 case Intrinsic::ppc_atomicrmw_add_i128:
17540 case Intrinsic::ppc_atomicrmw_sub_i128:
17541 case Intrinsic::ppc_atomicrmw_nand_i128:
17542 case Intrinsic::ppc_atomicrmw_and_i128:
17543 case Intrinsic::ppc_atomicrmw_or_i128:
17544 case Intrinsic::ppc_atomicrmw_xor_i128:
17545 case Intrinsic::ppc_cmpxchg_i128:
17547 Info.memVT = MVT::i128;
17548 Info.ptrVal =
I.getArgOperand(0);
17554 case Intrinsic::ppc_atomic_load_i128:
17556 Info.memVT = MVT::i128;
17557 Info.ptrVal =
I.getArgOperand(0);
17562 case Intrinsic::ppc_atomic_store_i128:
17564 Info.memVT = MVT::i128;
17565 Info.ptrVal =
I.getArgOperand(2);
17570 case Intrinsic::ppc_altivec_lvx:
17571 case Intrinsic::ppc_altivec_lvxl:
17572 case Intrinsic::ppc_altivec_lvebx:
17573 case Intrinsic::ppc_altivec_lvehx:
17574 case Intrinsic::ppc_altivec_lvewx:
17575 case Intrinsic::ppc_vsx_lxvd2x:
17576 case Intrinsic::ppc_vsx_lxvw4x:
17577 case Intrinsic::ppc_vsx_lxvd2x_be:
17578 case Intrinsic::ppc_vsx_lxvw4x_be:
17579 case Intrinsic::ppc_vsx_lxvl:
17580 case Intrinsic::ppc_vsx_lxvll: {
17582 switch (Intrinsic) {
17583 case Intrinsic::ppc_altivec_lvebx:
17586 case Intrinsic::ppc_altivec_lvehx:
17589 case Intrinsic::ppc_altivec_lvewx:
17592 case Intrinsic::ppc_vsx_lxvd2x:
17593 case Intrinsic::ppc_vsx_lxvd2x_be:
17603 Info.ptrVal =
I.getArgOperand(0);
17610 case Intrinsic::ppc_altivec_stvx:
17611 case Intrinsic::ppc_altivec_stvxl:
17612 case Intrinsic::ppc_altivec_stvebx:
17613 case Intrinsic::ppc_altivec_stvehx:
17614 case Intrinsic::ppc_altivec_stvewx:
17615 case Intrinsic::ppc_vsx_stxvd2x:
17616 case Intrinsic::ppc_vsx_stxvw4x:
17617 case Intrinsic::ppc_vsx_stxvd2x_be:
17618 case Intrinsic::ppc_vsx_stxvw4x_be:
17619 case Intrinsic::ppc_vsx_stxvl:
17620 case Intrinsic::ppc_vsx_stxvll: {
17622 switch (Intrinsic) {
17623 case Intrinsic::ppc_altivec_stvebx:
17626 case Intrinsic::ppc_altivec_stvehx:
17629 case Intrinsic::ppc_altivec_stvewx:
17632 case Intrinsic::ppc_vsx_stxvd2x:
17633 case Intrinsic::ppc_vsx_stxvd2x_be:
17643 Info.ptrVal =
I.getArgOperand(1);
17650 case Intrinsic::ppc_stdcx:
17651 case Intrinsic::ppc_stwcx:
17652 case Intrinsic::ppc_sthcx:
17653 case Intrinsic::ppc_stbcx: {
17655 auto Alignment =
Align(8);
17656 switch (Intrinsic) {
17657 case Intrinsic::ppc_stdcx:
17660 case Intrinsic::ppc_stwcx:
17662 Alignment =
Align(4);
17664 case Intrinsic::ppc_sthcx:
17666 Alignment =
Align(2);
17668 case Intrinsic::ppc_stbcx:
17670 Alignment =
Align(1);
17675 Info.ptrVal =
I.getArgOperand(0);
17677 Info.align = Alignment;
17695 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
17696 if (
Op.isMemset() && Subtarget.hasVSX()) {
17701 if (TailSize > 2 && TailSize <= 4) {
17706 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
17725 return !(BitSize == 0 || BitSize > 64);
17733 return NumBits1 == 64 && NumBits2 == 32;
17741 return NumBits1 == 64 && NumBits2 == 32;
17747 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(Val)) {
17748 EVT MemVT = LD->getMemoryVT();
17749 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
17750 (Subtarget.
isPPC64() && MemVT == MVT::i32)) &&
17766 "invalid fpext types");
17768 if (DestVT == MVT::f128)
17774 return isInt<16>(Imm) || isUInt<16>(Imm);
17778 return isInt<16>(Imm) || isUInt<16>(Imm);
17783 unsigned *
Fast)
const {
17797 !Subtarget.allowsUnalignedFPAccess())
17801 if (Subtarget.hasVSX()) {
17802 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
17803 VT != MVT::v4f32 && VT != MVT::v4i32)
17810 if (VT == MVT::ppcf128)
17824 if (
auto *ConstNode = dyn_cast<ConstantSDNode>(
C.getNode())) {
17825 if (!ConstNode->getAPIntValue().isSignedIntN(64))
17833 int64_t Imm = ConstNode->getSExtValue();
17834 unsigned Shift = llvm::countr_zero<uint64_t>(Imm);
17836 if (isInt<16>(Imm))
17861 return Subtarget.hasP9Vector();
17869 if (!
I->hasOneUse())
17873 assert(
User &&
"A single use instruction with no uses.");
17875 switch (
I->getOpcode()) {
17876 case Instruction::FMul: {
17878 if (
User->getOpcode() != Instruction::FSub &&
17879 User->getOpcode() != Instruction::FAdd)
17892 case Instruction::Load: {
17905 if (
User->getOpcode() != Instruction::Store)
17925 static const MCPhysReg ScratchRegs[] = {
17926 PPC::X12, PPC::LR8, PPC::CTR8, 0
17929 return ScratchRegs;
17933 const Constant *PersonalityFn)
const {
17934 return Subtarget.
isPPC64() ? PPC::X3 : PPC::R3;
17938 const Constant *PersonalityFn)
const {
17939 return Subtarget.
isPPC64() ? PPC::X4 : PPC::R4;
17944 EVT VT ,
unsigned DefinedValues)
const {
17945 if (VT == MVT::v2i64)
17946 return Subtarget.hasDirectMove();
17948 if (Subtarget.hasVSX())
17982 bool LegalOps,
bool OptForSize,
17984 unsigned Depth)
const {
17988 unsigned Opc =
Op.getOpcode();
17989 EVT VT =
Op.getValueType();
18014 if (Flags.hasNoSignedZeros() ||
Options.NoSignedZerosFPMath) {
18018 N0Cost,
Depth + 1);
18022 N1Cost,
Depth + 1);
18024 if (NegN0 && N0Cost <= N1Cost) {
18025 Cost = std::min(N0Cost, N2Cost);
18026 return DAG.
getNode(Opc, Loc, VT, NegN0, N1, NegN2, Flags);
18027 }
else if (NegN1) {
18028 Cost = std::min(N1Cost, N2Cost);
18029 return DAG.
getNode(Opc, Loc, VT, N0, NegN1, NegN2, Flags);
18048 if (M.getStackProtectorGuard() ==
"tls" || Subtarget.
isTargetLinux())
18072 bool ForCodeSize)
const {
18073 if (!VT.
isSimple() || !Subtarget.hasVSX())
18083 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
18088 APSInt IntResult(16,
false);
18093 if (IsExact && IntResult <= 15 && IntResult >= -16)
18095 return Imm.isZero();
18098 return Imm.isPosZero();
18110 unsigned Opcode =
N->getOpcode();
18111 unsigned TargetOpcode;
18130 if (Mask->getZExtValue() == OpSizeInBits - 1)
18136SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18142 if (!Subtarget.isISA3_0() || !Subtarget.
isPPC64() ||
18145 N->getValueType(0) != MVT::i64)
18160 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
18166SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18173SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18192 auto isZextOfCompareWithConstant = [](
SDValue Op) {
18194 Op.getValueType() != MVT::i64)
18198 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
18199 Cmp.getOperand(0).getValueType() != MVT::i64)
18202 if (
auto *
Constant = dyn_cast<ConstantSDNode>(Cmp.getOperand(1))) {
18203 int64_t NegConstant = 0 -
Constant->getSExtValue();
18206 return isInt<16>(NegConstant);
18212 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
18213 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
18216 if (LHSHasPattern && !RHSHasPattern)
18218 else if (!LHSHasPattern && !RHSHasPattern)
18224 SDValue Z = Cmp.getOperand(0);
18225 auto *
Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
18226 int64_t NegConstant = 0 -
Constant->getSExtValue();
18228 switch(cast<CondCodeSDNode>(Cmp.getOperand(2))->get()) {
18239 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
18254 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
18291 if (!GSDN || !ConstNode)
18298 if (!isInt<34>(NewOffset))
18311SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18331 DAGCombinerInfo &DCI)
const {
18333 if (Subtarget.useCRBits()) {
18335 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
18336 return CRTruncValue;
18343 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
18346 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
18356 EltToExtract = EltToExtract ? 0 : 1;
18366 return DCI.DAG.getNode(
18368 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
18373SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18377 if (!ConstOpOrElement)
18385 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne,
EVT VT) ->
bool {
18409 return IsAddOne && IsNeg ? VT.
isVector() :
true;
18413 EVT VT =
N->getValueType(0);
18420 if ((MulAmtAbs - 1).isPowerOf2()) {
18424 if (!IsProfitable(IsNeg,
true, VT))
18437 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
18441 if (!IsProfitable(IsNeg,
false, VT))
18462 DAGCombinerInfo &DCI)
const {
18467 EVT VT =
N->getValueType(0);
18470 unsigned Opc =
N->getOpcode();
18472 bool LegalOps = !DCI.isBeforeLegalizeOps();
18480 if (!
Flags.hasNoSignedZeros() && !
Options.NoSignedZerosFPMath)
18496bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
18513 if (!Callee ||
Callee->isVarArg())
18526bool PPCTargetLowering::
18527isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
18530 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(Mask)) {
18532 if (CI->getBitWidth() > 64)
18534 int64_t ConstVal = CI->getZExtValue();
18535 return isUInt<16>(ConstVal) ||
18536 (isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
18545PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
18551 if ((Flags & FlagSet) == FlagSet)
18554 if ((Flags & FlagSet) == FlagSet)
18557 if ((Flags & FlagSet) == FlagSet)
18560 if ((Flags & FlagSet) == FlagSet)
18581 if ((FrameIndexAlign % 4) != 0)
18582 FlagSet &= ~PPC::MOF_RPlusSImm16Mult4;
18583 if ((FrameIndexAlign % 16) != 0)
18584 FlagSet &= ~PPC::MOF_RPlusSImm16Mult16;
18588 if ((FrameIndexAlign % 4) == 0)
18590 if ((FrameIndexAlign % 16) == 0)
18603 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
18604 if ((Imm & 0x3) == 0)
18606 if ((Imm & 0xf) == 0)
18612 const APInt &ConstImm = CN->getAPIntValue();
18631 const APInt &ConstImm = CN->getAPIntValue();
18641 }
else if (
RHS.getOpcode() ==
PPCISD::Lo && !
RHS.getConstantOperandVal(1))
18653 isValidPCRelNode<ConstantPoolSDNode>(
N) ||
18654 isValidPCRelNode<GlobalAddressSDNode>(
N) ||
18655 isValidPCRelNode<JumpTableSDNode>(
N) ||
18656 isValidPCRelNode<BlockAddressSDNode>(
N));
18661unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
18666 if (!Subtarget.hasP9Vector())
18671 if (Subtarget.hasPrefixInstrs())
18674 if (Subtarget.hasSPE())
18683 unsigned ParentOp = Parent->
getOpcode();
18687 if ((
ID == Intrinsic::ppc_vsx_lxvp) || (
ID == Intrinsic::ppc_vsx_stxvp)) {
18688 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
18699 if (
const LSBaseSDNode *LSB = dyn_cast<LSBaseSDNode>(Parent))
18700 if (LSB->isIndexed())
18705 const MemSDNode *MN = dyn_cast<MemSDNode>(Parent);
18706 assert(MN &&
"Parent should be a MemSDNode!");
18711 "Not expecting scalar integers larger than 16 bytes!");
18714 else if (
Size == 32)
18721 else if (
Size == 256) {
18722 assert(Subtarget.pairedVectorMemops() &&
18723 "256-bit vectors are only available when paired vector memops is "
18731 else if (MemVT == MVT::f128 || MemVT.
isVector())
18741 if (
const LoadSDNode *LN = dyn_cast<LoadSDNode>(Parent)) {
18762 FlagSet &= ~PPC::MOF_NoExt;
18767 bool IsNonP1034BitConst =
18771 IsNonP1034BitConst)
18784 int16_t ForceXFormImm = 0;
18787 Disp =
N.getOperand(0);
18788 Base =
N.getOperand(1);
18799 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
18800 Disp =
N.getOperand(0);
18801 Base =
N.getOperand(1);
18815 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID>
CC)
const {
18821 if (PartVT == MVT::f64 &&
18822 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
18831SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
18835 EVT RetVT =
Op.getValueType();
18843 EVT ArgVT =
N.getValueType();
18848 Entry.IsZExt = !Entry.IsSExt;
18849 Args.push_back(Entry);
18857 (
RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
18863 .setTailCall(isTailCall)
18870SDValue PPCTargetLowering::lowerLibCallBasedOnType(
18871 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
18873 if (
Op.getValueType() == MVT::f32)
18874 return lowerToLibCall(LibCallFloatName,
Op, DAG);
18876 if (
Op.getValueType() == MVT::f64)
18877 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
18882bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
18884 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
18888bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
18889 return Op.getNode()->getFlags().hasApproximateFuncs();
18892bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
18896SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
18897 const char *LibCallFloatName,
18898 const char *LibCallDoubleNameFinite,
18899 const char *LibCallFloatNameFinite,
18902 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
18905 if (!isLowringToMASSFiniteSafe(
Op))
18906 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
18909 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
18910 LibCallDoubleNameFinite,
Op, DAG);
18914 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
18915 "__xl_powf_finite",
Op, DAG);
18919 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
18920 "__xl_sinf_finite",
Op, DAG);
18924 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
18925 "__xl_cosf_finite",
Op, DAG);
18929 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
18930 "__xl_logf_finite",
Op, DAG);
18934 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
18935 "__xl_log10f_finite",
Op, DAG);
18939 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
18940 "__xl_expf_finite",
Op, DAG);
18947 if (!isa<FrameIndexSDNode>(
N))
18965 unsigned Flags = computeMOFlags(Parent,
N, DAG);
18977 "Must be using PC-Relative calls when a valid PC-Relative node is "
19007 Disp =
N.getOperand(1).getOperand(0);
19012 Base =
N.getOperand(0);
19019 auto *CN = cast<ConstantSDNode>(
N);
19020 EVT CNType = CN->getValueType(0);
19021 uint64_t CNImm = CN->getZExtValue();
19032 if ((CNType == MVT::i32 || isInt<32>(CNImm)) &&
19034 int32_t
Addr = (int32_t)CNImm;
19039 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
19055 unsigned Opcode =
N.getOpcode();
19063 Base =
N.getOperand(0);
19082 Base = FI ?
N :
N.getOperand(1);
19094 bool IsVarArg)
const {
19104 return Subtarget.
isPPC64() && Subtarget.hasQuadwordAtomics();
19140 return Intrinsic::ppc_atomicrmw_xchg_i128;
19142 return Intrinsic::ppc_atomicrmw_add_i128;
19144 return Intrinsic::ppc_atomicrmw_sub_i128;
19146 return Intrinsic::ppc_atomicrmw_and_i128;
19148 return Intrinsic::ppc_atomicrmw_or_i128;
19150 return Intrinsic::ppc_atomicrmw_xor_i128;
19152 return Intrinsic::ppc_atomicrmw_nand_i128;
19169 {AlignedAddr, IncrLo, IncrHi});
19175 Lo, Builder.
CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
19196 Builder.
CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
19203 Lo, Builder.
CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
unsigned const MachineRegisterInfo * MRI
static MCRegister MatchRegisterName(StringRef Name)
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall, std::optional< CallLowering::PtrAuthInfo > &PAI, MachineRegisterInfo &MRI)
static SDValue GeneratePerfectShuffle(unsigned ID, SDValue V1, SDValue V2, unsigned PFEntry, SDValue LHS, SDValue RHS, SelectionDAG &DAG, const SDLoc &dl)
GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit the specified operations t...
static bool isSignExtended(SDValue N, SelectionDAG &DAG)
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
static std::pair< Register, unsigned > getBaseWithConstantOffset(MachineRegisterInfo &MRI, Register Reg)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
static bool isLoad(int Opcode)
static bool isFloatingPointZero(SDValue Op)
isFloatingPointZero - Return true if this is +0.0.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
Atomic ordering constants.
Analysis containing CSE Info
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
const HexagonInstrInfo * TII
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, ISD::ArgFlagsTy Flags, SelectionDAG &DAG, const SDLoc &dl)
CreateCopyOfByValArgument - Make a copy of an aggregate at address specified by "Src" to address "Dst...
Module.h This file contains the declarations for the Module class.
This defines the Use class.
static int getEstimateRefinementSteps(EVT VT, const LoongArchSubtarget &Subtarget)
static bool isConstantOrUndef(const SDValue Op)
static bool isSplat(Value *V)
Return true if V is a splat of a value (which is used when multiplying a matrix with a scalar).
unsigned const TargetRegisterInfo * TRI
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
cl::opt< bool > ANDIGlueBug("expose-ppc-andi-glue-bug", cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden)
static SDValue getCanonicalConstSplat(uint64_t Val, unsigned SplatSize, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
getCanonicalConstSplat - Build a canonical splat immediate of Val with an element size of SplatSize.
static bool IsSelectCC(MachineInstr &MI)
static const TargetRegisterClass * getRegClassForSVT(MVT::SimpleValueType SVT, bool IsPPC64, bool HasP8Vector, bool HasVSX)
static bool isGPRShadowAligned(MCPhysReg Reg, Align RequiredAlign)
static bool needStackSlotPassParameters(const PPCSubtarget &Subtarget, const SmallVectorImpl< ISD::OutputArg > &Outs)
static bool isAlternatingShuffMask(const ArrayRef< int > &Mask, int NumElts)
static bool isShuffleMaskInRange(const SmallVectorImpl< int > &ShuffV, int HalfVec, int LHSLastElementDefined, int RHSLastElementDefined)
static SDValue addShuffleForVecExtend(SDNode *N, SelectionDAG &DAG, SDValue Input, uint64_t Elems, uint64_t CorrectElems)
static cl::opt< bool > DisablePPCUnaligned("disable-ppc-unaligned", cl::desc("disable unaligned load/store generation on PPC"), cl::Hidden)
static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool findConsecutiveLoad(LoadSDNode *LD, SelectionDAG &DAG)
static SDValue generateEquivalentSub(SDNode *N, int Size, bool Complement, bool Swap, SDLoc &DL, SelectionDAG &DAG)
This function is called when we have proved that a SETCC node can be replaced by subtraction (and oth...
static unsigned mapArgRegToOffsetAIX(unsigned Reg, const PPCFrameLowering *FL)
static void CalculateTailCallArgDest(SelectionDAG &DAG, MachineFunction &MF, bool IsPPC64, SDValue Arg, int SPDiff, unsigned ArgOffset, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
CalculateTailCallArgDest - Remember Argument for later processing.
static SDValue combineADDToMAT_PCREL_ADDR(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setAlignFlagsForFI(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Set alignment flags based on whether or not the Frame Index is aligned.
static bool isTOCSaveRestoreRequired(const PPCSubtarget &Subtarget)
static void updateForAIXShLibTLSModelOpt(TLSModel::Model &Model, SelectionDAG &DAG, const TargetMachine &TM)
updateForAIXShLibTLSModelOpt - Helper to initialize TLS model opt settings, and then apply the update...
static bool provablyDisjointOr(SelectionDAG &DAG, const SDValue &N)
Used when computing address flags for selecting loads and stores.
static bool callsShareTOCBase(const Function *Caller, const GlobalValue *CalleeGV, const TargetMachine &TM)
static SDValue generateSToVPermutedForVecShuffle(int ScalarSize, uint64_t ShuffleEltWidth, unsigned &NumValidElts, int FirstElt, int &LastElt, SDValue VecShuffOperand, SDValue SToVNode, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
constexpr uint64_t AIXSmallTlsPolicySizeLimit
static bool isPCRelNode(SDValue N)
static void LowerMemOpCallTo(SelectionDAG &DAG, MachineFunction &MF, SDValue Chain, SDValue Arg, SDValue PtrOff, int SPDiff, unsigned ArgOffset, bool isPPC64, bool isTailCall, bool isVector, SmallVectorImpl< SDValue > &MemOpChains, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments, const SDLoc &dl)
LowerMemOpCallTo - Store the argument to the stack or remember it in case of tail calls.
static cl::opt< unsigned > PPCGatherAllAliasesMaxDepth("ppc-gather-alias-max-depth", cl::init(18), cl::Hidden, cl::desc("max depth when checking alias info in GatherAllAliases()"))
static bool areCallingConvEligibleForTCO_64SVR4(CallingConv::ID CallerCC, CallingConv::ID CalleeCC)
static const MCPhysReg FPR[]
FPR - The set of FP registers that should be allocated for arguments on Darwin and AIX.
static SDNode * isBLACompatibleAddress(SDValue Op, SelectionDAG &DAG)
isCallCompatibleAddress - Return the immediate to use if the specified 32-bit value is representable ...
static Align CalculateStackSlotAlignment(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotAlignment - Calculates the alignment of this argument on the stack.
static bool IsSelect(MachineInstr &MI)
static bool haveEfficientBuildVectorPattern(BuildVectorSDNode *V, bool HasDirectMove, bool HasP8Vector)
Do we have an efficient pattern in a .td file for this node?
static SDValue getSToVPermuted(SDValue OrigSToV, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &S)
static void setUsesTOCBasePtr(MachineFunction &MF)
static SDValue transformCallee(const SDValue &Callee, SelectionDAG &DAG, const SDLoc &dl, const PPCSubtarget &Subtarget)
static unsigned EnsureStackAlignment(const PPCFrameLowering *Lowering, unsigned NumBytes)
EnsureStackAlignment - Round stack frame size up from NumBytes to ensure minimum alignment required f...
static SDValue stripModuloOnShift(const TargetLowering &TLI, SDNode *N, SelectionDAG &DAG)
static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth)
static bool hasSameArgumentList(const Function *CallerFn, const CallBase &CB)
static bool isFPExtLoad(SDValue Op)
static SDValue BuildIntrinsicOp(unsigned IID, SDValue Op, SelectionDAG &DAG, const SDLoc &dl, EVT DestVT=MVT::Other)
BuildIntrinsicOp - Return a unary operator intrinsic node with the specified intrinsic ID.
static bool isConsecutiveLSLoc(SDValue Loc, EVT VT, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static void StoreTailCallArgumentsToStackSlot(SelectionDAG &DAG, SDValue Chain, const SmallVectorImpl< TailCallArgumentInfo > &TailCallArgs, SmallVectorImpl< SDValue > &MemOpChains, const SDLoc &dl)
StoreTailCallArgumentsToStackSlot - Stores arguments to their stack slot.
static const char AIXSSPCanaryWordName[]
static cl::opt< bool > UseAbsoluteJumpTables("ppc-use-absolute-jumptables", cl::desc("use absolute jump tables on ppc"), cl::Hidden)
static void setXFormForUnalignedFI(SDValue N, unsigned Flags, PPC::AddrMode &Mode)
static void getMaxByValAlign(Type *Ty, Align &MaxAlign, Align MaxMaxAlign)
getMaxByValAlign - Helper for getByValTypeAlignment to determine the desired ByVal argument alignment...
static bool isConsecutiveLS(SDNode *N, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static bool isVMerge(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned LHSStart, unsigned RHSStart)
isVMerge - Common function, used to match vmrg* shuffles.
static void getLabelAccessInfo(bool IsPIC, const PPCSubtarget &Subtarget, unsigned &HiOpFlags, unsigned &LoOpFlags, const GlobalValue *GV=nullptr)
Return true if we should reference labels using a PICBase, set the HiOpFlags and LoOpFlags to the tar...
cl::opt< bool > DisableAutoPairedVecSt("disable-auto-paired-vec-st", cl::desc("disable automatically generated 32byte paired vector stores"), cl::init(true), cl::Hidden)
static void buildCallOperands(SmallVectorImpl< SDValue > &Ops, PPCTargetLowering::CallFlags CFlags, const SDLoc &dl, SelectionDAG &DAG, SmallVector< std::pair< unsigned, SDValue >, 8 > &RegsToPass, SDValue Glue, SDValue Chain, SDValue &Callee, int SPDiff, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableInnermostLoopAlign32("disable-ppc-innermost-loop-align32", cl::desc("don't always align innermost loop to 32 bytes on ppc"), cl::Hidden)
static bool usePartialVectorLoads(SDNode *N, const PPCSubtarget &ST)
Returns true if we should use a direct load into vector instruction (such as lxsd or lfd),...
static SDValue getDataClassTest(SDValue Op, FPClassTest Mask, const SDLoc &Dl, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void fixupShuffleMaskForPermutedSToV(SmallVectorImpl< int > &ShuffV, int LHSFirstElt, int LHSLastElt, int RHSFirstElt, int RHSLastElt, int HalfVec, unsigned LHSNumValidElts, unsigned RHSNumValidElts, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableSCO("disable-ppc-sco", cl::desc("disable sibling call optimization on ppc"), cl::Hidden)
static void fixupFuncForFI(SelectionDAG &DAG, int FrameIdx, EVT VT)
static cl::opt< bool > DisablePPCPreinc("disable-ppc-preinc", cl::desc("disable preincrement load/store generation on PPC"), cl::Hidden)
static Intrinsic::ID getIntrinsicForAtomicRMWBinOp128(AtomicRMWInst::BinOp BinOp)
static SDValue convertFPToInt(SDValue Op, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static unsigned CalculateStackSlotSize(EVT ArgVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotSize - Calculates the size reserved for this argument on the stack.
static int CalculateTailCallSPDiff(SelectionDAG &DAG, bool isTailCall, unsigned ParamSize)
CalculateTailCallSPDiff - Get the amount the stack pointer has to be adjusted to accommodate the argu...
static Instruction * callIntrinsic(IRBuilderBase &Builder, Intrinsic::ID Id)
static void prepareIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, const SDLoc &dl)
static SDValue LowerLabelRef(SDValue HiPart, SDValue LoPart, bool isPIC, SelectionDAG &DAG)
static SDValue isScalarToVec(SDValue Op)
static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl)
static cl::opt< bool > DisablePerfectShuffle("ppc-disable-perfect-shuffle", cl::desc("disable vector permute decomposition"), cl::init(true), cl::Hidden)
static bool getVectorCompareInfo(SDValue Intrin, int &CompareOpc, bool &isDot, const PPCSubtarget &Subtarget)
getVectorCompareInfo - Given an intrinsic, return false if it is not a vector comparison.
static unsigned invertFMAOpcode(unsigned Opc)
static const SDValue * getNormalLoadInput(const SDValue &Op, bool &IsPermuted)
static cl::opt< unsigned > PPCMinimumJumpTableEntries("ppc-min-jump-table-entries", cl::init(64), cl::Hidden, cl::desc("Set minimum number of entries to use a jump table on PPC"))
static bool isValidSplatLoad(const PPCSubtarget &Subtarget, const SDValue &Op, unsigned &Opcode)
static SDValue convertIntToFP(SDValue Op, SDValue Src, SelectionDAG &DAG, const PPCSubtarget &Subtarget, SDValue Chain=SDValue())
static void PrepareTailCall(SelectionDAG &DAG, SDValue &InGlue, SDValue &Chain, const SDLoc &dl, int SPDiff, unsigned NumBytes, SDValue LROp, SDValue FPOp, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
static SDValue EmitTailCallStoreFPAndRetAddr(SelectionDAG &DAG, SDValue Chain, SDValue OldRetAddr, SDValue OldFP, int SPDiff, const SDLoc &dl)
EmitTailCallStoreFPAndRetAddr - Move the frame pointer and return address to the appropriate stack sl...
static SDValue BuildVSLDOI(SDValue LHS, SDValue RHS, unsigned Amt, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
BuildVSLDOI - Return a VECTOR_SHUFFLE that is a vsldoi of the specified amount.
static SDValue combineBVZEXTLOAD(SDNode *N, SelectionDAG &DAG)
static SDValue truncateScalarIntegerArg(ISD::ArgFlagsTy Flags, EVT ValVT, SelectionDAG &DAG, SDValue ArgValue, MVT LocVT, const SDLoc &dl)
static void computeFlagsForAddressComputation(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Given a node, compute flags that are used for address computation when selecting load and store instr...
cl::opt< bool > ANDIGlueBug
static SDValue getOutputChainFromCallSeq(SDValue CallSeqStart)
static bool CalculateStackSlotUsed(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize, unsigned LinkageSize, unsigned ParamAreaSize, unsigned &ArgOffset, unsigned &AvailableFPRs, unsigned &AvailableVRs)
CalculateStackSlotUsed - Return whether this argument will use its stack slot (instead of being passe...
static cl::opt< unsigned > PPCAIXTLSModelOptUseIEForLDLimit("ppc-aix-shared-lib-tls-model-opt-limit", cl::init(1), cl::Hidden, cl::desc("Set inclusive limit count of TLS local-dynamic access(es) in a " "function to use initial-exec"))
static unsigned getPPCStrictOpcode(unsigned Opc)
static void prepareDescriptorIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, SDValue CallSeqStart, const CallBase *CB, const SDLoc &dl, bool hasNest, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableP10StoreForward("disable-p10-store-forward", cl::desc("disable P10 store forward-friendly conversion"), cl::Hidden, cl::init(false))
static bool isXXBRShuffleMaskHelper(ShuffleVectorSDNode *N, int Width)
static bool isFunctionGlobalAddress(const GlobalValue *CalleeGV)
static bool isSplatBV(SDValue Op)
static SDValue combineBVOfVecSExt(SDNode *N, SelectionDAG &DAG)
static cl::opt< bool > DisableILPPref("disable-ppc-ilp-pref", cl::desc("disable setting the node scheduling preference to ILP on PPC"), cl::Hidden)
static bool isNByteElemShuffleMask(ShuffleVectorSDNode *, unsigned, int)
Check that the mask is shuffling N byte elements.
static SDValue combineBVOfConsecutiveLoads(SDNode *N, SelectionDAG &DAG)
Reduce the number of loads when building a vector.
static bool isValidPCRelNode(SDValue N)
static constexpr Register SPReg
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SI optimize exec mask operations pre RA
static const MCExpr * MaskShift(const MCExpr *Val, uint32_t Mask, uint32_t Shift, MCContext &Ctx)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This file describes how to lower LLVM code to machine code.
bool isFixed(unsigned ValNo) const
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
bool isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
APInt zext(unsigned width) const
Zero extend to a new width.
uint64_t getZExtValue() const
Get zero extended value.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
APInt abs() const
Get the absolute value.
bool isNegative() const
Determine sign of this APInt.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
bool getBoolValue() const
Convert APInt to a boolean value.
double bitsToDouble() const
Converts APInt bits to a double.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
An arbitrary precision integer that knows its signedness.
This class represents an incoming formal argument to a Function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
An instruction that atomically checks whether a specified value is in a memory location,...
Value * getNewValOperand()
an instruction that atomically reads a memory location, combines it with another value,...
BinOp
This enumeration lists the possible modifications atomicrmw can make.
@ USubCond
Subtract only if no unsigned overflow.
@ USubSat
*p = usub.sat(old, v) usub.sat matches the behavior of llvm.usub.sat.
@ UIncWrap
Increment one up to a maximum value.
@ UDecWrap
Decrement one until a minimum value or zero.
BinOp getOperation() const
This is an SDNode representing atomic operations.
StringRef getValueAsString() const
Return the attribute's value as a string.
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
int64_t getOffset() const
const BlockAddress * getBlockAddress() const
The address of a basic block.
static BranchProbability getOne()
static BranchProbability getZero()
A "pseudo-class" with methods for operating on BUILD_VECTORs.
bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
CCState - This class holds information needed while lowering arguments and return values.
MachineFunction & getMachineFunction() const
unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const
getFirstUnallocated - Return the index of the first unallocated register in the set,...
MCRegister AllocateReg(MCPhysReg Reg)
AllocateReg - Attempt to allocate one register.
int64_t AllocateStack(unsigned Size, Align Alignment)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
uint64_t getStackSize() const
Returns the size of the currently allocated portion of the stack.
void addLoc(const CCValAssign &V)
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP)
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
int64_t getLocMemOffset() const
unsigned getValNo() const
static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool isStrictFP() const
Determine if the call requires strict floating point semantics.
CallingConv::ID getCallingConv() const
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
bool isMustTailCall() const
Tests if this call site must be tail call optimized.
Value * getCalledOperand() const
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
unsigned arg_size() const
Function * getCaller()
Helper to get the caller (the parent function).
This class represents a function call, abstracting a target machine's calling convention.
ConstantFP - Floating Point Values [float, double].
This is the shared class of boolean and integer constants.
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
int64_t getSExtValue() const
This is an important base class in LLVM.
This class represents an Operation in the Expression.
uint64_t getNumOperands() const
A parsed version of the target data layout string in and methods for querying it.
bool isLittleEndian() const
Layout endianness...
unsigned getLargestLegalIntTypeSizeInBits() const
Returns the size of largest legal integer type size, or 0 if none are set.
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
Align getABITypeAlign(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
AttributeList getAttributes() const
Return the attribute list for this Function.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Type * getReturnType() const
Returns the type of the ret val.
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
int64_t getOffset() const
unsigned getTargetFlags() const
const GlobalValue * getGlobal() const
const GlobalObject * getAliaseeObject() const
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
void setThreadLocalMode(ThreadLocalMode Val)
bool hasHiddenVisibility() const
StringRef getSection() const
Module * getParent()
Get the module that this global value is contained inside of...
bool isStrongDefinitionForLinker() const
Returns true if this global's definition will be the one chosen by the linker.
const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
Type * getValueType() const
bool hasProtectedVisibility() const
Common base class shared among various IRBuilders.
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
BasicBlock * GetInsertBlock() const
CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
bool hasAtomicLoad() const LLVM_READONLY
Return true if this atomic instruction loads from memory.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
This is an important class for using LLVM in a threaded context.
Base class for LoadSDNode and StoreSDNode.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
TypeSize getValue() const
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
Wrapper class representing physical registers. Should be passed by value.
MCSymbolXCOFF * getQualNameSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
@ INVALID_SIMPLE_VALUE_TYPE
uint64_t getScalarSizeInBits() const
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
void setCallFrameSize(unsigned N)
Set the call frame size on entry to this basic block.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setHasTailCall(bool V=true)
void setReturnAddressIsTaken(bool s)
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool hasVAStart() const
Returns true if the function calls the llvm.va_start intrinsic.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
MCSymbol * getPICBaseSymbol() const
getPICBaseSymbol - Return a function-local symbol to represent the PIC base.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
@ EK_LabelDifference32
EK_LabelDifference32 - Each entry is the address of the block minus the address of the jump table.
A description of a memory reference used in the backend.
LocationSize getSize() const
Return the size in bytes of the memory reference.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
MachineOperand class - Representation of each machine instruction operand.
static MachineOperand CreateImm(int64_t Val)
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Register getLiveInVirtReg(MCRegister PReg) const
getLiveInVirtReg - If PReg is a live-in physical register, return the corresponding live-in virtual r...
An SDNode that represents everything that will be needed to construct a MachineInstr.
This SDNode is used for target intrinsics that touch memory and need an associated MachineMemOperand.
This is an abstract virtual class for memory operations.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getBasePtr() const
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
uint64_t getReturnSaveOffset() const
getReturnSaveOffset - Return the previous frame offset to save the return address.
uint64_t getFramePointerSaveOffset() const
getFramePointerSaveOffset - Return the previous frame offset to save the frame pointer.
unsigned getLinkageSize() const
getLinkageSize - Return the size of the PowerPC ABI linkage area.
uint64_t getTOCSaveOffset() const
getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
void setVarArgsNumFPR(unsigned Num)
void setReturnAddrSaveIndex(int idx)
bool isAIXFuncUseTLSIEForLD() const
int getReturnAddrSaveIndex() const
unsigned getVarArgsNumFPR() const
void setAIXFuncUseTLSIEForLD()
int getFramePointerSaveIndex() const
void setVarArgsNumGPR(unsigned Num)
void appendParameterType(ParamType Type)
int getVarArgsFrameIndex() const
void setLRStoreRequired()
bool isAIXFuncTLSModelOptInitDone() const
void setTailCallSPDelta(int size)
void setAIXFuncTLSModelOptInitDone()
bool isLRStoreRequired() const
void setMinReservedArea(unsigned size)
unsigned getVarArgsNumGPR() const
unsigned getMinReservedArea() const
void setVarArgsStackOffset(int Offset)
void setVarArgsFrameIndex(int Index)
void addLiveInAttr(Register VReg, ISD::ArgFlagsTy Flags)
This function associates attributes for each live-in virtual register.
int getVarArgsStackOffset() const
void setFramePointerSaveIndex(int Idx)
static bool hasPCRelFlag(unsigned TF)
bool is32BitELFABI() const
unsigned descriptorTOCAnchorOffset() const
MVT getScalarIntVT() const
bool useSoftFloat() const
const PPCFrameLowering * getFrameLowering() const override
bool needsSwapsForVSXMemOps() const
bool isPPC64() const
isPPC64 - Return true if we are generating code for 64-bit pointer mode.
bool isUsingPCRelativeCalls() const
bool usesFunctionDescriptors() const
True if the ABI is descriptor based.
MCRegister getEnvironmentPointerRegister() const
const PPCInstrInfo * getInstrInfo() const override
unsigned getCPUDirective() const
getCPUDirective - Returns the -m directive specified for the cpu.
POPCNTDKind hasPOPCNTD() const
bool isLittleEndian() const
bool isTargetLinux() const
MCRegister getTOCPointerRegister() const
MCRegister getStackPointerRegister() const
bool is64BitELFABI() const
const PPCTargetMachine & getTargetMachine() const
bool isPredictableSelectIsExpensive() const
bool enableMachineScheduler() const override
Scheduling customization.
const PPCRegisterInfo * getRegisterInfo() const override
bool isGVIndirectSymbol(const GlobalValue *GV) const
True if the GV will be accessed via an indirect symbol.
unsigned descriptorEnvironmentPointerOffset() const
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
CCAssignFn * ccAssignFnForCall(CallingConv::ID CC, bool Return, bool IsVarArg) const
bool isTruncateFree(Type *Ty1, Type *Ty2) const override
isTruncateFree - Return true if it's free to truncate a value of type Ty1 to type Ty2.
Value * emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI, Value *AlignedAddr, Value *Incr, Value *Mask, Value *ShiftAmt, AtomicOrdering Ord) const override
Perform a masked atomicrmw using a target-specific intrinsic.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
bool isFPExtFree(EVT DestVT, EVT SrcVT) const override
Return true if an fpext operation is free (for instance, because single-precision floating-point numb...
PPC::AddrMode SelectForceXFormMode(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
SelectForceXFormMode - Given the specified address, force it to be represented as an indexed [r+r] op...
Instruction * emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
bool hasInlineStackProbe(const MachineFunction &MF) const override
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
const char * getTargetNodeName(unsigned Opcode) const override
getTargetNodeName() - This method returns the name of a target specific DAG node.
bool supportsTailCallFor(const CallBase *CB) const
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
MachineBasicBlock * emitProbedAlloca(MachineInstr &MI, MachineBasicBlock *MBB) const
bool isZExtFree(SDValue Val, EVT VT2) const override
Return true if zero-extending the specific node Val to type VT2 is free (either because it's implicit...
MachineBasicBlock * EmitPartwordAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, bool is8bit, unsigned Opcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const override
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
bool SelectAddressRegImm(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign EncodingAlignment) const
SelectAddressRegImm - Returns true if the address N can be represented by a base register plus a sign...
bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I, MachineFunction &MF, unsigned Intrinsic) const override
Given an intrinsic, checks if on the target the intrinsic will need to map to a MemIntrinsicNode (tou...
SDValue expandVSXLoadForLE(SDNode *N, DAGCombinerInfo &DCI) const
bool splitValueIntoRegisterParts(SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts, unsigned NumParts, MVT PartVT, std::optional< CallingConv::ID > CC) const override
Target-specific splitting of values into parts that fit a register storing a legal type.
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
LowerAsmOperandForConstraint - Lower the specified operand into the Ops vector.
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
ReplaceNodeResults - Replace the results of node with an illegal result type with new values built ou...
TargetLowering::AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
Align getByValTypeAlignment(Type *Ty, const DataLayout &DL) const override
getByValTypeAlignment - Return the desired alignment for ByVal aggregate function arguments in the ca...
bool SelectAddressRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG, MaybeAlign EncodingAlignment=std::nullopt) const
SelectAddressRegReg - Given the specified addressed, check to see if it can be more efficiently repre...
MachineBasicBlock * EmitAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned AtomicSize, unsigned BinOpcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, SmallVectorImpl< SDNode * > &Created) const override
Targets may override this function to provide custom SDIV lowering for power-of-2 denominators.
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
bool SelectAddressRegRegOnly(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressRegRegOnly - Given the specified addressed, force it to be represented as an indexed [r+...
bool useSoftFloat() const override
SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const override
Returns relocation base for the given PIC jumptable.
void insertSSPDeclarations(Module &M) const override
Inserts necessary declarations for SSP (stack protection) purpose.
Value * emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder, AtomicCmpXchgInst *CI, Value *AlignedAddr, Value *CmpVal, Value *NewVal, Value *Mask, AtomicOrdering Ord) const override
Perform a masked cmpxchg using a target-specific intrinsic.
ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
bool enableAggressiveFMAFusion(EVT VT) const override
Return true if target always benefits from combining into FMA for a given value type.
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
bool decomposeMulByConstant(LLVMContext &Context, EVT VT, SDValue C) const override
Return true if it is profitable to transform an integer multiplication-by-constant into simpler opera...
unsigned getJumpTableEncoding() const override
Return the entry encoding for a jump table in the current function.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
isLegalAddressingMode - Return true if the addressing mode represented by AM is legal for this target...
bool preferIncOfAddToSubOfNot(EVT VT) const override
These two forms are equivalent: sub y, (xor x, -1) add (add x, 1), y The variant with two add's is IR...
bool shouldConvertConstantLoadToIntImm(const APInt &Imm, Type *Ty) const override
Returns true if it is beneficial to convert a load of a constant to just the constant itself.
const MCPhysReg * getScratchRegisters(CallingConv::ID CC) const override
Returns a 0 terminated array of registers that can be safely used as scratch registers.
bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const override
getPreIndexedAddressParts - returns true by value, base pointer and offset pointer and addressing mod...
bool isProfitableToHoist(Instruction *I) const override
isProfitableToHoist - Check if it is profitable to hoist instruction I to its dominator block.
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
ConstraintType getConstraintType(StringRef Constraint) const override
getConstraintType - Given a constraint, return the type of constraint it is for this target.
const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const override
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
bool shallExtractConstSplatVectorElementToStore(Type *VectorTy, unsigned ElemSizeInBits, unsigned &Index) const override
Return true if the target shall perform extract vector element and store given that the vector is kno...
EVT getOptimalMemOpType(const MemOp &Op, const AttributeList &FuncAttributes) const override
It returns EVT::Other if the type should be determined using generic target-independent logic.
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
SDValue expandVSXStoreForLE(SDNode *N, DAGCombinerInfo &DCI) const
void CollectTargetIntrinsicOperands(const CallInst &I, SmallVectorImpl< SDValue > &Ops, SelectionDAG &DAG) const override
unsigned getStackProbeSize(const MachineFunction &MF) const
PPCTargetLowering(const PPCTargetMachine &TM, const PPCSubtarget &STI)
TargetLowering::AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
bool useLoadStackGuardNode(const Module &M) const override
Override to support customized stack guard loading.
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster than a pair of fmul and fadd i...
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const override
Is unaligned memory access allowed for the given type, and is it fast relative to software emulation.
bool shouldExpandBuildVectorWithShuffles(EVT VT, unsigned DefinedValues) const override
bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
Similar to the 16-bit case but for instructions that take a 34-bit displacement field (prefixed loads...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
bool isJumpTableRelative() const override
Register getExceptionPointerRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
PPC::AddrMode SelectOptimalAddrMode(const SDNode *Parent, SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign Align) const
SelectOptimalAddrMode - Based on a node N and it's Parent (a MemSDNode), compute the address flags of...
Value * getSDagStackGuard(const Module &M) const override
Return the variable that's previously inserted by insertSSPDeclarations, if any, otherwise return nul...
bool SelectAddressPCRel(SDValue N, SDValue &Base) const
SelectAddressPCRel - Represent the specified address as pc relative to be represented as [pc+imm].
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the ISD::SETCC ValueType
bool SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressEVXRegReg - Given the specified addressed, check to see if it can be more efficiently re...
bool isLegalICmpImmediate(int64_t Imm) const override
isLegalICmpImmediate - Return true if the specified immediate is legal icmp immediate,...
bool isAccessedAsGotIndirect(SDValue N) const
Align getPrefLoopAlignment(MachineLoop *ML) const override
Return the preferred loop alignment.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo) const override
createFastISel - This method returns a target-specific FastISel object, or null if the target does no...
bool shouldInlineQuadwordAtomics() const
Instruction * emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Inserts in the IR a target-specific intrinsic specifying a fence.
bool isLegalAddImmediate(int64_t Imm) const override
isLegalAddImmediate - Return true if the specified immediate is legal add immediate,...
Common code between 32-bit and 64-bit PowerPC targets.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
This class provides iterator support for SDUse operands that use a specific SDNode.
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
void dump() const
Dump this node, for debugging.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
iterator_range< use_iterator > uses()
SDNodeFlags getFlags() const
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
user_iterator user_begin() const
Provide iteration support to walk over all users of an SDNode.
op_iterator op_end() const
op_iterator op_begin() const
static use_iterator use_end()
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getOpcode() const
unsigned getNumOperands() const
static SectionKind getMetadata()
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getStackArgumentTokenFactor(SDValue Chain)
Compute a TokenFactor to force all the incoming stack arguments to be loaded from the stack.
const TargetSubtargetInfo & getSubtarget() const
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
SDValue 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,...
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
Align getEVTAlign(EVT MemoryVT) const
Compute the default alignment value for the given type.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
static constexpr unsigned MaxRecursionDepth
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
SDValue getTokenFactor(const SDLoc &DL, SmallVectorImpl< SDValue > &Vals)
Creates a new TokenFactor containing Vals.
bool areNonVolatileConsecutiveLoads(LoadSDNode *LD, LoadSDNode *Base, unsigned Bytes, int Dist) const
Return true if loads are next to each other and can be merged.
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getMDNode(const MDNode *MD)
Return an MDNodeSDNode which holds an MDNode.
void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV)
Returns an ISD::VECTOR_SHUFFLE node semantically equivalent to the shuffle node in input but with swa...
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
SDValue getBoolExtOrTrunc(SDValue Op, const SDLoc &SL, EVT VT, EVT OpVT)
Convert Op, which must be of integer type, to the integer type VT, by using an extension appropriate ...
SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond)
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
SDValue getValueType(EVT)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
SDValue getBoolConstant(bool V, const SDLoc &DL, EVT VT, EVT OpVT)
Create a true or false constant of type VT using the target's BooleanContent for type OpVT.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
SDValue getRegisterMask(const uint32_t *RegMask)
SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
SDValue getCondCode(ISD::CondCode Cond)
bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, LocationSize Size=0, const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
SDValue getMCSymbol(MCSymbol *Sym, EVT VT)
SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
int getMaskElt(unsigned Idx) const
ArrayRef< int > getMask() const
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getValue() const
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Class to represent struct types.
Information about stack frame layout on the target.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual bool shouldExpandBuildVectorWithShuffles(EVT, unsigned DefinedValues) const
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
MachineBasicBlock * emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const
Replace/modify any TargetFrameIndex operands with a targte-dependent sequence of memory operands that...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
void setMinStackArgumentAlignment(Align Alignment)
Set the minimum stack alignment of an argument.
virtual MVT getVectorIdxTy(const DataLayout &DL) const
Returns the type to be used for the index operand of: ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT...
const TargetMachine & getTargetMachine() const
unsigned MaxLoadsPerMemcmp
Specify maximum number of load instructions per memcmp call.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
virtual Value * getSDagStackGuard(const Module &M) const
Return the variable that's previously inserted by insertSSPDeclarations, if any, otherwise return nul...
void setIndexedLoadAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed load does or does not work with the specified type and indicate w...
void setPrefLoopAlignment(Align Alignment)
Set the target's preferred loop alignment.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Sched::Preference getSchedulingPreference() const
Return target scheduling preference.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
bool isOperationCustom(unsigned Op, EVT VT) const
Return true if the operation uses custom lowering, regardless of whether the type is legal or not.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
bool hasBigEndianPartOrdering(EVT VT, const DataLayout &DL) const
When splitting a value of the specified type into parts, does the Lo or Hi part come first?...
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL) const
Returns the type for the shift amount of a shift opcode.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
virtual Align getPrefLoopAlignment(MachineLoop *ML=nullptr) const
Return the preferred loop alignment.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
void setIndexedStoreAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed store does or does not work with the specified type and indicate ...
virtual bool isJumpTableRelative() const
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setLibcallName(RTLIB::Libcall Call, const char *Name)
Rename the default libcall routine name for the specified libcall.
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
virtual AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setMinimumJumpTableEntries(unsigned Val)
Indicate the minimum number of blocks to generate jump tables.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
unsigned MaxLoadsPerMemcmpOptSize
Likewise for functions with the OptSize attribute.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
virtual AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
unsigned GatherAllAliasesMaxDepth
Depth that GatherAllAliases should continue looking for chain dependencies when trying to find a more...
NegatibleCost
Enum that specifies when a float negation is beneficial.
virtual bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const
Returns true if arguments should be sign-extended in lib calls.
std::vector< ArgListEntry > ArgListTy
void setHasMultipleConditionRegisters(bool hasManyRegs=true)
Tells the code generator that the target has multiple (allocatable) condition registers that can be u...
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
virtual void insertSSPDeclarations(Module &M) const
Inserts necessary declarations for SSP (stack protection) purpose.
void setJumpIsExpensive(bool isExpensive=true)
Tells the code generator not to expand logic operations on comparison predicates into separate sequen...
virtual MCSymbol * getFunctionEntryPointSymbol(const GlobalValue *Func, const TargetMachine &TM) const
If supported, return the function entry point symbol.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
SDValue lowerCmpEqZeroToCtlzSrl(SDValue Op, SelectionDAG &DAG) const
void softenSetCCOperands(SelectionDAG &DAG, EVT VT, SDValue &NewLHS, SDValue &NewRHS, ISD::CondCode &CCCode, const SDLoc &DL, const SDValue OldLHS, const SDValue OldRHS) const
Soften the operands of a comparison.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
SDValue getCheaperNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, unsigned Depth=0) const
This is the helper function to return the newly negated expression only when the cost is cheaper.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool isPositionIndependent() const
virtual SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG, const DenormalMode &Mode) const
Return a target-dependent comparison result if the input operand is suitable for use with a square ro...
virtual SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const
Returns relocation base for the given PIC jumptable.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
bool verifyReturnAddressArgumentIsConstant(SDValue Op, SelectionDAG &DAG) const
bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node, SDValue &Chain) const
Check whether a given call node is in tail position within its function.
virtual SDValue getSqrtResultForDenormInput(SDValue Operand, SelectionDAG &DAG) const
Return a target-dependent result if the input operand is not suitable for use with a square root esti...
virtual bool useLoadStackGuardNode(const Module &M) const
If this function returns true, SelectionDAGBuilder emits a LOAD_STACK_GUARD node when it is lowering ...
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
virtual bool isGAPlusOffset(SDNode *N, const GlobalValue *&GA, int64_t &Offset) const
Returns true (and the GlobalValue and the offset) if the node is a GlobalAddress + offset.
virtual unsigned getJumpTableEncoding() const
Return the entry encoding for a jump table in the current function.
Primary interface to the complete machine description for the target machine.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
Reloc::Model getRelocationModel() const
Returns the code generation relocation model.
bool shouldAssumeDSOLocal(const GlobalValue *GV) const
CodeModel::Model getCodeModel() const
Returns the code model.
unsigned UnsafeFPMath
UnsafeFPMath - This flag is enabled when the -enable-unsafe-fp-math flag is specified on the command ...
unsigned NoInfsFPMath
NoInfsFPMath - This flag is enabled when the -enable-no-infs-fp-math flag is specified on the command...
unsigned PPCGenScalarMASSEntries
Enables scalar MASS conversions.
unsigned NoNaNsFPMath
NoNaNsFPMath - This flag is enabled when the -enable-no-nans-fp-math flag is specified on the command...
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
bool isEmptyTy() const
Return true if this type is empty, that is, it has no elements or all of its elements are empty.
@ FloatTyID
32-bit floating point type
@ DoubleTyID
64-bit floating point type
@ FP128TyID
128-bit floating point type (112-bit significand)
static Type * getVoidTy(LLVMContext &C)
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isFunctionTy() const
True if this is an instance of FunctionType.
static IntegerType * getInt64Ty(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeID getTypeID() const
Return the type id for the type.
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
A Use represents the edge between a Value definition and its users.
User * getUser() const
Returns the User that contains this Use.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ BSWAP
Byte Swap and Counting operators.
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADDC
Carry-setting nodes for multiple precision addition and subtraction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ INIT_TRAMPOLINE
INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ SET_ROUNDING
Set rounding mode.
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ BR
Control flow instructions. These all have token chains.
@ PREFETCH
PREFETCH - This corresponds to a prefetch intrinsic.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ SSUBO
Same for subtraction.
@ BR_JT
BR_JT - Jumptable branch.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ GET_ROUNDING
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimumNumber or maximumNumber on two values,...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two values.
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ INLINEASM_BR
INLINEASM_BR - Branching version of inline asm. Used by asm-goto.
@ EH_DWARF_CFA
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA),...
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ ADDE
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ INLINEASM
INLINEASM - Represents an inline asm block.
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ CALLSEQ_START
CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of a call sequence,...
@ GET_DYNAMIC_AREA_OFFSET
GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of the most recent dynamic alloca.
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ ADJUST_TRAMPOLINE
ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
bool isBitwiseLogicOp(unsigned Opcode)
Whether this is bitwise logic opcode.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
bool isEXTLoad(const SDNode *N)
Returns true if the specified node is a EXTLOAD.
bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
bool isSEXTLoad(const SDNode *N)
Returns true if the specified node is a SEXTLOAD.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
bool isUnsignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs an unsigned comparison when used with intege...
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
ID ArrayRef< Type * > Tys
Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
@ MO_TLSLDM_FLAG
MO_TLSLDM_FLAG - on AIX the ML relocation type is only valid for a reference to a TOC symbol from the...
@ MO_PIC_LO_FLAG
MO_PIC_LO_FLAG = MO_PIC_FLAG | MO_LO.
@ MO_TPREL_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TPREL_FLAG.
@ MO_GOT_TPREL_PCREL_FLAG
MO_GOT_TPREL_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_GOT_PCREL_FLAG
MO_GOT_PCREL_FLAG = MO_PCREL_FLAG | MO_GOT_FLAG.
@ MO_TLSGDM_FLAG
MO_TLSGDM_FLAG - If this bit is set the symbol reference is relative to the region handle of TLS Gene...
@ MO_PCREL_FLAG
MO_PCREL_FLAG - If this bit is set, the symbol reference is relative to the current instruction addre...
@ MO_TLSLD_FLAG
MO_TLSLD_FLAG - If this bit is set the symbol reference is relative to TLS Local Dynamic model.
@ MO_TLS_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TLS.
@ MO_PLT
On PPC, the 12 bits are not enough for all target operand flags.
@ MO_TLS
Symbol for VK_PPC_TLS fixup attached to an ADD instruction.
@ MO_TPREL_FLAG
MO_TPREL_FLAG - If this bit is set, the symbol reference is relative to the thread pointer and the sy...
@ MO_LO
MO_LO, MO_HA - lo16(symbol) and ha16(symbol)
@ MO_GOT_TLSLD_PCREL_FLAG
MO_GOT_TLSLD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_HA_FLAG
MO_PIC_HA_FLAG = MO_PIC_FLAG | MO_HA.
@ MO_TLSGD_FLAG
MO_TLSGD_FLAG - If this bit is set the symbol reference is relative to TLS General Dynamic model for ...
@ MO_GOT_TLSGD_PCREL_FLAG
MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_FLAG
MO_PIC_FLAG - If this bit is set, the symbol reference is relative to the function's picbase,...
@ SEXT_LD_SPLAT
VSRC, CHAIN = SEXT_LD_SPLAT, CHAIN, Ptr - a splatting load memory that sign-extends.
@ FCTIDUZ
Newer FCTI[D,W]UZ floating-point-to-integer conversion instructions for unsigned integers with round ...
@ ADDI_TLSGD_L_ADDR
G8RC = ADDI_TLSGD_L_ADDR G8RReg, Symbol, Symbol - Op that combines ADDI_TLSGD_L and GET_TLS_ADDR unti...
@ FSQRT
Square root instruction.
@ STRICT_FCFID
Constrained integer-to-floating-point conversion instructions.
@ DYNALLOC
The following two target-specific nodes are used for calls through function pointers in the 64-bit SV...
@ COND_BRANCH
CHAIN = COND_BRANCH CHAIN, CRRC, OPC, DESTBB [, INFLAG] - This corresponds to the COND_BRANCH pseudo ...
@ TLSLD_AIX
[GP|G8]RC = TLSLD_AIX, TOC_ENTRY(module handle) Op that requires a single input of the module handle ...
@ CALL_RM
The variants that implicitly define rounding mode for calls with strictfp semantics.
@ STORE_VEC_BE
CHAIN = STORE_VEC_BE CHAIN, VSRC, Ptr - Occurs only for little endian.
@ BDNZ
CHAIN = BDNZ CHAIN, DESTBB - These are used to create counter-based loops.
@ MTVSRZ
Direct move from a GPR to a VSX register (zero)
@ SRL
These nodes represent PPC shifts.
@ VECINSERT
VECINSERT - The PPC vector insert instruction.
@ LXSIZX
GPRC, CHAIN = LXSIZX, CHAIN, Ptr, ByteWidth - This is a load of an integer smaller than 64 bits into ...
@ FNMSUB
FNMSUB - Negated multiply-subtract instruction.
@ RFEBB
CHAIN = RFEBB CHAIN, State - Return from event-based branch.
@ FCTIDZ
FCTI[D,W]Z - The FCTIDZ and FCTIWZ instructions, taking an f32 or f64 operand, producing an f64 value...
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
@ GET_TLS_ADDR
x3 = GET_TLS_ADDR x3, Symbol - For the general-dynamic TLS model, produces a call to __tls_get_addr(s...
@ XXSPLTI32DX
XXSPLTI32DX - The PPC XXSPLTI32DX instruction.
@ ANDI_rec_1_EQ_BIT
i1 = ANDI_rec_1_[EQ|GT]_BIT(i32 or i64 x) - Represents the result of the eq or gt bit of CR0 after ex...
@ FRE
Reciprocal estimate instructions (unary FP ops).
@ ADDIS_GOT_TPREL_HA
G8RC = ADDIS_GOT_TPREL_HA x2, Symbol - Used by the initial-exec TLS model, produces an ADDIS8 instruc...
@ CLRBHRB
CHAIN = CLRBHRB CHAIN - Clear branch history rolling buffer.
@ STORE_COND
CHAIN,Glue = STORE_COND CHAIN, GPR, Ptr The store conditional instruction ST[BHWD]ARX that produces a...
@ SINT_VEC_TO_FP
Extract a subvector from signed integer vector and convert to FP.
@ EXTRACT_SPE
Extract SPE register component, second argument is high or low.
@ XXSWAPD
VSRC, CHAIN = XXSWAPD CHAIN, VSRC - Occurs only for little endian.
@ ADDI_TLSLD_L_ADDR
G8RC = ADDI_TLSLD_L_ADDR G8RReg, Symbol, Symbol - Op that combines ADDI_TLSLD_L and GET_TLSLD_ADDR un...
@ ATOMIC_CMP_SWAP_8
ATOMIC_CMP_SWAP - the exact same as the target-independent nodes except they ensure that the compare ...
@ ST_VSR_SCAL_INT
Store scalar integers from VSR.
@ VCMP
RESVEC = VCMP(LHS, RHS, OPC) - Represents one of the altivec VCMP* instructions.
@ BCTRL
CHAIN,FLAG = BCTRL(CHAIN, INFLAG) - Directly corresponds to a BCTRL instruction.
@ BUILD_SPE64
BUILD_SPE64 and EXTRACT_SPE are analogous to BUILD_PAIR and EXTRACT_ELEMENT but take f64 arguments in...
@ LFIWZX
GPRC, CHAIN = LFIWZX CHAIN, Ptr - This is a floating-point load which zero-extends from a 32-bit inte...
@ RET_GLUE
Return with a glue operand, matched by 'blr'.
@ SCALAR_TO_VECTOR_PERMUTED
PowerPC instructions that have SCALAR_TO_VECTOR semantics tend to place the value into the least sign...
@ EXTRACT_VSX_REG
EXTRACT_VSX_REG = Extract one of the underlying vsx registers of an accumulator or pair register.
@ STXSIX
STXSIX - The STXSI[bh]X instruction.
@ MAT_PCREL_ADDR
MAT_PCREL_ADDR = Materialize a PC Relative address.
@ MFOCRF
R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
@ XXSPLT
XXSPLT - The PPC VSX splat instructions.
@ TOC_ENTRY
GPRC = TOC_ENTRY GA, TOC Loads the entry for GA from the TOC, where the TOC base is given by the last...
@ XXPERMDI
XXPERMDI - The PPC XXPERMDI instruction.
@ ADDIS_DTPREL_HA
G8RC = ADDIS_DTPREL_HA x3, Symbol - For the local-dynamic TLS model, produces an ADDIS8 instruction t...
@ ADD_TLS
G8RC = ADD_TLS G8RReg, Symbol - Can be used by the initial-exec and local-exec TLS models,...
@ MTVSRA
Direct move from a GPR to a VSX register (algebraic)
@ VADD_SPLAT
VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded during instruction selection to optimi...
@ PPC32_GOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ ADDI_DTPREL_L
G8RC = ADDI_DTPREL_L G8RReg, Symbol - For the local-dynamic TLS model, produces an ADDI8 instruction ...
@ BCTRL_LOAD_TOC
CHAIN,FLAG = BCTRL(CHAIN, ADDR, INFLAG) - The combination of a bctrl instruction and the TOC reload r...
@ PPC32_PICGOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ FCFID
FCFID - The FCFID instruction, taking an f64 operand and producing and f64 value containing the FP re...
@ CR6SET
ch, gl = CR6[UN]SET ch, inglue - Toggle CR bit 6 for SVR4 vararg calls
@ LBRX
GPRC, CHAIN = LBRX CHAIN, Ptr, Type - This is a byte-swapping load instruction.
@ GET_TLS_MOD_AIX
x3 = GET_TLS_MOD_AIX _$TLSML - For the AIX local-dynamic TLS model, produces a call to ....
@ SETBC
SETBC - The ISA 3.1 (P10) SETBC instruction.
@ LD_VSX_LH
VSRC, CHAIN = LD_VSX_LH CHAIN, Ptr - This is a floating-point load of a v2f32 value into the lower ha...
@ PROBED_ALLOCA
To avoid stack clash, allocation is performed by block and each block is probed.
@ XXMFACC
XXMFACC = This corresponds to the xxmfacc instruction.
@ ADDIS_TLSGD_HA
G8RC = ADDIS_TLSGD_HA x2, Symbol - For the general-dynamic TLS model, produces an ADDIS8 instruction ...
@ SETBCR
SETBCR - The ISA 3.1 (P10) SETBCR instruction.
@ ACC_BUILD
ACC_BUILD = Build an accumulator register from 4 VSX registers.
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
@ LXVD2X
VSRC, CHAIN = LXVD2X_LE CHAIN, Ptr - Occurs only for little endian.
@ XSMAXC
XSMAXC[DQ]P, XSMINC[DQ]P - C-type min/max instructions.
@ CALL
CALL - A direct function call.
@ MTCTR
CHAIN,FLAG = MTCTR(VAL, CHAIN[, INFLAG]) - Directly corresponds to a MTCTR instruction.
@ TC_RETURN
TC_RETURN - A tail call return.
@ STFIWX
STFIWX - The STFIWX instruction.
@ LD_SPLAT
VSRC, CHAIN = LD_SPLAT, CHAIN, Ptr - a splatting load memory instructions such as LXVDSX,...
@ VCMP_rec
RESVEC, OUTFLAG = VCMP_rec(LHS, RHS, OPC) - Represents one of the altivec VCMP*_rec instructions.
@ MFFS
F8RC = MFFS - This moves the FPSCR (not modeled) into the register.
@ PADDI_DTPREL
G8RC = PADDI_DTPREL x3, Symbol - For the pc-rel based local-dynamic TLS model, produces a PADDI8 inst...
@ BUILD_FP128
Direct move of 2 consecutive GPR to a VSX register.
@ VEXTS
VEXTS, ByteWidth - takes an input in VSFRC and produces an output in VSFRC that is sign-extended from...
@ TLS_LOCAL_EXEC_MAT_ADDR
TLS_LOCAL_EXEC_MAT_ADDR = Materialize an address for TLS global address when using local exec access ...
@ VPERM
VPERM - The PPC VPERM Instruction.
@ ADDIS_TLSLD_HA
G8RC = ADDIS_TLSLD_HA x2, Symbol - For the local-dynamic TLS model, produces an ADDIS8 instruction th...
@ XXSPLTI_SP_TO_DP
XXSPLTI_SP_TO_DP - The PPC VSX splat instructions for immediates for converting immediate single prec...
@ GET_TLSLD_ADDR
x3 = GET_TLSLD_ADDR x3, Symbol - For the local-dynamic TLS model, produces a call to __tls_get_addr(s...
@ ADDI_TLSGD_L
x3 = ADDI_TLSGD_L G8RReg, Symbol - For the general-dynamic TLS model, produces an ADDI8 instruction t...
@ DYNAREAOFFSET
This instruction is lowered in PPCRegisterInfo::eliminateFrameIndex to compute an offset from native ...
@ PAIR_BUILD
PAIR_BUILD = Build a vector pair register from 2 VSX registers.
@ STRICT_FADDRTZ
Constrained floating point add in round-to-zero mode.
@ FTSQRT
Test instruction for software square root.
@ FP_EXTEND_HALF
FP_EXTEND_HALF(VECTOR, IDX) - Custom extend upper (IDX=0) half or lower (IDX=1) half of v4f32 to v2f6...
@ CMPB
The CMPB instruction (takes two operands of i32 or i64).
@ VECSHL
VECSHL - The PPC vector shift left instruction.
@ ADDI_TLSLD_L
x3 = ADDI_TLSLD_L G8RReg, Symbol - For the local-dynamic TLS model, produces an ADDI8 instruction tha...
@ FADDRTZ
F8RC = FADDRTZ F8RC, F8RC - This is an FADD done with rounding towards zero.
@ ZEXT_LD_SPLAT
VSRC, CHAIN = ZEXT_LD_SPLAT, CHAIN, Ptr - a splatting load memory that zero-extends.
@ SRA_ADDZE
The combination of sra[wd]i and addze used to implemented signed integer division by a power of 2.
@ EXTSWSLI
EXTSWSLI = The PPC extswsli instruction, which does an extend-sign word and shift left immediate.
@ STXVD2X
CHAIN = STXVD2X CHAIN, VSRC, Ptr - Occurs only for little endian.
@ TLSGD_AIX
GPRC = TLSGD_AIX, TOC_ENTRY, TOC_ENTRY G8RC = TLSGD_AIX, TOC_ENTRY, TOC_ENTRY Op that combines two re...
@ UINT_VEC_TO_FP
Extract a subvector from unsigned integer vector and convert to FP.
@ GET_TPOINTER
x3 = GET_TPOINTER - Used for the local- and initial-exec TLS model on 32-bit AIX, produces a call to ...
@ LXVRZX
LXVRZX - Load VSX Vector Rightmost and Zero Extend This node represents v1i128 BUILD_VECTOR of a zero...
@ MFBHRBE
GPRC, CHAIN = MFBHRBE CHAIN, Entry, Dummy - Move from branch history rolling buffer entry.
@ FCFIDU
Newer FCFID[US] integer-to-floating-point conversion instructions for unsigned integers and single-pr...
@ FSEL
FSEL - Traditional three-operand fsel node.
@ SWAP_NO_CHAIN
An SDNode for swaps that are not associated with any loads/stores and thereby have no chain.
@ LOAD_VEC_BE
VSRC, CHAIN = LOAD_VEC_BE CHAIN, Ptr - Occurs only for little endian.
@ LFIWAX
GPRC, CHAIN = LFIWAX CHAIN, Ptr - This is a floating-point load which sign-extends from a 32-bit inte...
@ LD_GOT_TPREL_L
G8RC = LD_GOT_TPREL_L Symbol, G8RReg - Used by the initial-exec TLS model, produces a LD instruction ...
@ MFVSR
Direct move from a VSX register to a GPR.
@ TLS_DYNAMIC_MAT_PCREL_ADDR
TLS_DYNAMIC_MAT_PCREL_ADDR = Materialize a PC Relative address for TLS global address when using dyna...
@ Hi
Hi/Lo - These represent the high and low 16-bit parts of a global address respectively.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
SDValue get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG)
get_VSPLTI_elt - If this is a build_vector of constants which can be formed by using a vspltis[bhw] i...
bool isXXBRDShuffleMask(ShuffleVectorSDNode *N)
isXXBRDShuffleMask - Return true if this is a shuffle mask suitable for a XXBRD instruction.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo)
bool isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for a VRGH* instruction with the ...
bool isVPKUDUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUDUMShuffleMask - Return true if this is the shuffle mask for a VPKUDUM instruction.
bool isVMRGEOShuffleMask(ShuffleVectorSDNode *N, bool CheckEven, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGEOShuffleMask - Return true if this is a shuffle mask suitable for a VMRGEW or VMRGOW instructi...
bool isXXBRQShuffleMask(ShuffleVectorSDNode *N)
isXXBRQShuffleMask - Return true if this is a shuffle mask suitable for a XXBRQ instruction.
bool isXXBRWShuffleMask(ShuffleVectorSDNode *N)
isXXBRWShuffleMask - Return true if this is a shuffle mask suitable for a XXBRW instruction.
bool isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXPERMDIShuffleMask - Return true if this is a shuffle mask suitable for a XXPERMDI instruction.
bool isXXBRHShuffleMask(ShuffleVectorSDNode *N)
isXXBRHShuffleMask - Return true if this is a shuffle mask suitable for a XXBRH instruction.
unsigned getSplatIdxForPPCMnemonics(SDNode *N, unsigned EltSize, SelectionDAG &DAG)
getSplatIdxForPPCMnemonics - Return the splat index as a value that is appropriate for PPC mnemonics ...
bool isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXSLDWIShuffleMask - Return true if this is a shuffle mask suitable for a XXSLDWI instruction.
int isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift amount, otherwise return -1.
bool isVMRGLShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for a VRGL* instruction with the ...
bool isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, unsigned &InsertAtByte, bool &Swap, bool IsLE)
isXXINSERTWMask - Return true if this VECTOR_SHUFFLE can be handled by the XXINSERTW instruction intr...
bool isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize)
isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand specifies a splat of a singl...
bool isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a VPKUWUM instruction.
bool isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a VPKUHUM instruction.
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit.
@ Define
Register definition.
Reg
All possible values of the reg field in the ModR/M byte.
@ XTY_ER
External reference.
initializer< Ty > init(const Ty &Val)
const_iterator end(StringRef path LLVM_LIFETIME_BOUND)
Get end iterator over path.
This is an optimization pass for GlobalISel generic memory operations.
static bool isIndirectCall(const MachineInstr &MI)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool checkConvertToNonDenormSingle(APFloat &ArgAPFloat)
void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
bool CC_PPC32_SVR4_ByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
bool isIntS16Immediate(SDNode *N, int16_t &Imm)
isIntS16Immediate - This method tests to see if the node is either a 32-bit or 64-bit immediate,...
bool CC_PPC32_SVR4_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
static bool isRunOfOnes64(uint64_t Val, unsigned &MB, unsigned &ME)
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
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)