71#include "llvm/IR/IntrinsicsPowerPC.h"
106#define DEBUG_TYPE "ppc-lowering"
128 cl::desc(
"disable vector permute decomposition"),
132 "disable-auto-paired-vec-st",
133 cl::desc(
"disable automatically generated 32byte paired vector stores"),
138 cl::desc(
"Set minimum number of entries to use a jump table on PPC"));
143 "Number of shuffles lowered to a VPERM or XXPERM");
144STATISTIC(NumDynamicAllocaProbed,
"Number of dynamic stack allocation probed");
167 initializeAddrModeMap();
170 bool isPPC64 = Subtarget.
isPPC64();
179 if (!Subtarget.hasEFPU2())
204 if (Subtarget.isISA3_0()) {
234 if (!Subtarget.hasSPE()) {
242 const MVT ScalarIntVTs[] = { MVT::i32, MVT::i64 };
243 for (
MVT VT : ScalarIntVTs) {
250 if (Subtarget.useCRBits()) {
253 if (isPPC64 || Subtarget.hasFPCVT()) {
256 isPPC64 ? MVT::i64 : MVT::i32);
259 isPPC64 ? MVT::i64 : MVT::i32);
263 isPPC64 ? MVT::i64 : MVT::i32);
266 isPPC64 ? MVT::i64 : MVT::i32);
270 isPPC64 ? MVT::i64 : MVT::i32);
273 isPPC64 ? MVT::i64 : MVT::i32);
277 isPPC64 ? MVT::i64 : MVT::i32);
280 isPPC64 ? MVT::i64 : MVT::i32);
327 if (Subtarget.isISA3_0()) {
362 if (!Subtarget.hasSPE()) {
367 if (Subtarget.hasVSX()) {
372 if (Subtarget.hasFSQRT()) {
377 if (Subtarget.hasFPRND()) {
418 if (Subtarget.hasSPE()) {
426 if (Subtarget.hasSPE())
432 if (!Subtarget.hasFSQRT() &&
433 !(
TM.Options.UnsafeFPMath && Subtarget.hasFRSQRTE() &&
437 if (!Subtarget.hasFSQRT() &&
438 !(
TM.Options.UnsafeFPMath && Subtarget.hasFRSQRTES() &&
439 Subtarget.hasFRES()))
442 if (Subtarget.hasFCPSGN()) {
450 if (Subtarget.hasFPRND()) {
464 if (Subtarget.isISA3_1()) {
475 if (Subtarget.isISA3_0()) {
495 if (!Subtarget.useCRBits()) {
508 if (!Subtarget.useCRBits())
511 if (Subtarget.hasFPU()) {
522 if (!Subtarget.useCRBits())
527 if (Subtarget.hasSPE()) {
551 if (Subtarget.hasDirectMove() && isPPC64) {
556 if (
TM.Options.UnsafeFPMath) {
659 if (Subtarget.hasSPE()) {
681 if (Subtarget.has64BitSupport()) {
696 if (Subtarget.hasLFIWAX() || Subtarget.
isPPC64()) {
702 if (Subtarget.hasSPE()) {
712 if (Subtarget.hasFPCVT()) {
713 if (Subtarget.has64BitSupport()) {
734 if (Subtarget.use64BitRegs()) {
752 if (Subtarget.has64BitSupport()) {
759 if (Subtarget.hasVSX()) {
766 if (Subtarget.hasAltivec()) {
767 for (
MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
782 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
795 if (Subtarget.hasVSX()) {
801 if (Subtarget.hasP8Altivec() && (VT.SimpleTy != MVT::v1i128)) {
811 if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
885 if (!Subtarget.hasP8Vector()) {
927 if (Subtarget.hasAltivec())
928 for (
auto VT : {MVT::v4i32, MVT::v8i16, MVT::v16i8})
931 if (Subtarget.hasP8Altivec())
942 if (Subtarget.hasVSX()) {
948 if (Subtarget.hasP8Altivec())
953 if (Subtarget.isISA3_1()) {
991 if (Subtarget.hasVSX()) {
994 if (Subtarget.hasP8Vector()) {
998 if (Subtarget.hasDirectMove() && isPPC64) {
1012 if (
TM.Options.UnsafeFPMath) {
1049 if (Subtarget.hasP8Vector())
1058 if (Subtarget.hasP8Altivec()) {
1085 if (Subtarget.isISA3_1())
1188 if (Subtarget.hasP8Altivec()) {
1193 if (Subtarget.hasP9Vector()) {
1198 if (Subtarget.useCRBits()) {
1257 }
else if (Subtarget.hasVSX()) {
1282 for (
MVT VT : {MVT::f32, MVT::f64}) {
1301 if (Subtarget.hasP9Altivec()) {
1302 if (Subtarget.isISA3_1()) {
1325 if (Subtarget.hasP10Vector()) {
1330 if (Subtarget.pairedVectorMemops()) {
1335 if (Subtarget.hasMMA()) {
1336 if (Subtarget.isISAFuture())
1345 if (Subtarget.has64BitSupport())
1348 if (Subtarget.isISA3_1())
1366 if (Subtarget.hasAltivec()) {
1393 if (Subtarget.hasFPCVT())
1396 if (Subtarget.useCRBits())
1405 if (Subtarget.useCRBits()) {
1436 setLibcallName(RTLIB::MEMCPY, isPPC64 ?
"___memmove64" :
"___memmove");
1437 setLibcallName(RTLIB::MEMMOVE, isPPC64 ?
"___memmove64" :
"___memmove");
1438 setLibcallName(RTLIB::MEMSET, isPPC64 ?
"___memset64" :
"___memset");
1439 setLibcallName(RTLIB::BZERO, isPPC64 ?
"___bzero64" :
"___bzero");
1444 if (Subtarget.useCRBits()) {
1547void PPCTargetLowering::initializeAddrModeMap() {
1598 if (MaxAlign == MaxMaxAlign)
1600 if (
VectorType *VTy = dyn_cast<VectorType>(Ty)) {
1601 if (MaxMaxAlign >= 32 &&
1602 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1603 MaxAlign =
Align(32);
1604 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1606 MaxAlign =
Align(16);
1607 }
else if (
ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
1610 if (EltAlign > MaxAlign)
1611 MaxAlign = EltAlign;
1612 }
else if (
StructType *STy = dyn_cast<StructType>(Ty)) {
1613 for (
auto *EltTy : STy->elements()) {
1616 if (EltAlign > MaxAlign)
1617 MaxAlign = EltAlign;
1618 if (MaxAlign == MaxMaxAlign)
1631 if (Subtarget.hasAltivec())
1633 return Alignment.
value();
1641 return Subtarget.hasSPE();
1649 Type *VectorTy,
unsigned ElemSizeInBits,
unsigned &
Index)
const {
1650 if (!Subtarget.
isPPC64() || !Subtarget.hasVSX())
1653 if (
auto *VTy = dyn_cast<VectorType>(VectorTy)) {
1654 if (VTy->getScalarType()->isIntegerTy()) {
1656 if (ElemSizeInBits == 32) {
1660 if (ElemSizeInBits == 64) {
1686 return "PPCISD::FTSQRT";
1688 return "PPCISD::FSQRT";
1693 return "PPCISD::XXSPLTI_SP_TO_DP";
1695 return "PPCISD::XXSPLTI32DX";
1699 return "PPCISD::XXPERM";
1719 return "PPCISD::CALL_RM";
1721 return "PPCISD::CALL_NOP_RM";
1723 return "PPCISD::CALL_NOTOC_RM";
1728 return "PPCISD::BCTRL_RM";
1730 return "PPCISD::BCTRL_LOAD_TOC_RM";
1742 return "PPCISD::SCALAR_TO_VECTOR_PERMUTED";
1744 return "PPCISD::ANDI_rec_1_EQ_BIT";
1746 return "PPCISD::ANDI_rec_1_GT_BIT";
1761 return "PPCISD::ST_VSR_SCAL_INT";
1790 return "PPCISD::PADDI_DTPREL";
1806 return "PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR";
1808 return "PPCISD::TLS_LOCAL_EXEC_MAT_ADDR";
1818 return "PPCISD::STRICT_FADDRTZ";
1820 return "PPCISD::STRICT_FCTIDZ";
1822 return "PPCISD::STRICT_FCTIWZ";
1824 return "PPCISD::STRICT_FCTIDUZ";
1826 return "PPCISD::STRICT_FCTIWUZ";
1828 return "PPCISD::STRICT_FCFID";
1830 return "PPCISD::STRICT_FCFIDU";
1832 return "PPCISD::STRICT_FCFIDS";
1834 return "PPCISD::STRICT_FCFIDUS";
1837 return "PPCISD::STORE_COND";
1845 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1862 return CFP->getValueAPF().isZero();
1866 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
1867 return CFP->getValueAPF().isZero();
1875 return Op < 0 ||
Op == Val;
1887 if (ShuffleKind == 0) {
1890 for (
unsigned i = 0; i != 16; ++i)
1893 }
else if (ShuffleKind == 2) {
1896 for (
unsigned i = 0; i != 16; ++i)
1899 }
else if (ShuffleKind == 1) {
1900 unsigned j = IsLE ? 0 : 1;
1901 for (
unsigned i = 0; i != 8; ++i)
1918 if (ShuffleKind == 0) {
1921 for (
unsigned i = 0; i != 16; i += 2)
1925 }
else if (ShuffleKind == 2) {
1928 for (
unsigned i = 0; i != 16; i += 2)
1932 }
else if (ShuffleKind == 1) {
1933 unsigned j = IsLE ? 0 : 2;
1934 for (
unsigned i = 0; i != 8; i += 2)
1955 if (!Subtarget.hasP8Vector())
1959 if (ShuffleKind == 0) {
1962 for (
unsigned i = 0; i != 16; i += 4)
1968 }
else if (ShuffleKind == 2) {
1971 for (
unsigned i = 0; i != 16; i += 4)
1977 }
else if (ShuffleKind == 1) {
1978 unsigned j = IsLE ? 0 : 4;
1979 for (
unsigned i = 0; i != 8; i += 4)
1996 unsigned LHSStart,
unsigned RHSStart) {
1997 if (
N->getValueType(0) != MVT::v16i8)
1999 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
2000 "Unsupported merge size!");
2002 for (
unsigned i = 0; i != 8/UnitSize; ++i)
2003 for (
unsigned j = 0; j != UnitSize; ++j) {
2005 LHSStart+j+i*UnitSize) ||
2007 RHSStart+j+i*UnitSize))
2022 if (ShuffleKind == 1)
2024 else if (ShuffleKind == 2)
2029 if (ShuffleKind == 1)
2031 else if (ShuffleKind == 0)
2047 if (ShuffleKind == 1)
2049 else if (ShuffleKind == 2)
2054 if (ShuffleKind == 1)
2056 else if (ShuffleKind == 0)
2106 unsigned RHSStartValue) {
2107 if (
N->getValueType(0) != MVT::v16i8)
2110 for (
unsigned i = 0; i < 2; ++i)
2111 for (
unsigned j = 0; j < 4; ++j)
2113 i*RHSStartValue+j+IndexOffset) ||
2115 i*RHSStartValue+j+IndexOffset+8))
2137 unsigned indexOffset = CheckEven ? 4 : 0;
2138 if (ShuffleKind == 1)
2140 else if (ShuffleKind == 2)
2146 unsigned indexOffset = CheckEven ? 0 : 4;
2147 if (ShuffleKind == 1)
2149 else if (ShuffleKind == 0)
2165 if (
N->getValueType(0) != MVT::v16i8)
2172 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2175 if (i == 16)
return -1;
2180 if (ShiftAmt < i)
return -1;
2185 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2187 for (++i; i != 16; ++i)
2190 }
else if (ShuffleKind == 1) {
2192 for (++i; i != 16; ++i)
2199 ShiftAmt = 16 - ShiftAmt;
2208 EVT VT =
N->getValueType(0);
2209 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2210 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2213 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2217 if (
N->getMaskElt(0) % EltSize != 0)
2222 unsigned ElementBase =
N->getMaskElt(0);
2225 if (ElementBase >= 16)
2230 for (
unsigned i = 1; i != EltSize; ++i)
2231 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2234 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2235 if (
N->getMaskElt(i) < 0)
continue;
2236 for (
unsigned j = 0; j != EltSize; ++j)
2237 if (
N->getMaskElt(i+j) !=
N->getMaskElt(j))
2254 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2255 "Unexpected element width.");
2256 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2258 unsigned NumOfElem = 16 / Width;
2259 unsigned MaskVal[16];
2260 for (
unsigned i = 0; i < NumOfElem; ++i) {
2261 MaskVal[0] =
N->getMaskElt(i * Width);
2262 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2264 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2268 for (
unsigned int j = 1; j < Width; ++j) {
2269 MaskVal[j] =
N->getMaskElt(i * Width + j);
2270 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2280 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2285 unsigned M0 =
N->getMaskElt(0) / 4;
2286 unsigned M1 =
N->getMaskElt(4) / 4;
2287 unsigned M2 =
N->getMaskElt(8) / 4;
2288 unsigned M3 =
N->getMaskElt(12) / 4;
2289 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2290 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2295 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2296 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2297 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2298 InsertAtByte = IsLE ? 12 : 0;
2303 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2304 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2305 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2306 InsertAtByte = IsLE ? 8 : 4;
2311 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2312 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2313 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2314 InsertAtByte = IsLE ? 4 : 8;
2319 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2320 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2321 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2322 InsertAtByte = IsLE ? 0 : 12;
2329 if (
N->getOperand(1).isUndef()) {
2332 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2333 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2334 InsertAtByte = IsLE ? 12 : 0;
2337 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2338 InsertAtByte = IsLE ? 8 : 4;
2341 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2342 InsertAtByte = IsLE ? 4 : 8;
2345 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2346 InsertAtByte = IsLE ? 0 : 12;
2355 bool &Swap,
bool IsLE) {
2356 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2362 unsigned M0 =
N->getMaskElt(0) / 4;
2363 unsigned M1 =
N->getMaskElt(4) / 4;
2364 unsigned M2 =
N->getMaskElt(8) / 4;
2365 unsigned M3 =
N->getMaskElt(12) / 4;
2369 if (
N->getOperand(1).isUndef()) {
2370 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2371 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2374 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2380 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2384 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2389 ShiftElts = (8 -
M0) % 8;
2390 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2395 ShiftElts = (4 -
M0) % 4;
2400 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2405 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2417 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2422 for (
int i = 0; i < 16; i += Width)
2423 if (
N->getMaskElt(i) != i + Width - 1)
2454 bool &Swap,
bool IsLE) {
2455 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2461 unsigned M0 =
N->getMaskElt(0) / 8;
2462 unsigned M1 =
N->getMaskElt(8) / 8;
2463 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2467 if (
N->getOperand(1).isUndef()) {
2468 if ((
M0 |
M1) < 2) {
2469 DM = IsLE ? (((~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2477 if (
M0 > 1 &&
M1 < 2) {
2479 }
else if (M0 < 2 && M1 > 1) {
2487 DM = (((~M1) & 1) << 1) + ((~
M0) & 1);
2490 if (M0 < 2 && M1 > 1) {
2492 }
else if (
M0 > 1 &&
M1 < 2) {
2500 DM = (
M0 << 1) + (
M1 & 1);
2515 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2520 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2536 unsigned EltSize = 16/
N->getNumOperands();
2537 if (EltSize < ByteSize) {
2538 unsigned Multiple = ByteSize/EltSize;
2540 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2543 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2544 if (
N->getOperand(i).isUndef())
continue;
2546 if (!isa<ConstantSDNode>(
N->getOperand(i)))
return SDValue();
2548 if (!UniquedVals[i&(Multiple-1)].getNode())
2549 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2550 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2560 bool LeadingZero =
true;
2561 bool LeadingOnes =
true;
2562 for (
unsigned i = 0; i != Multiple-1; ++i) {
2563 if (!UniquedVals[i].getNode())
continue;
2570 if (!UniquedVals[Multiple-1].getNode())
2577 if (!UniquedVals[Multiple-1].getNode())
2579 int Val =cast<ConstantSDNode>(UniquedVals[Multiple-1])->getSExtValue();
2588 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2589 if (
N->getOperand(i).isUndef())
continue;
2591 OpVal =
N->getOperand(i);
2592 else if (OpVal !=
N->getOperand(i))
2598 unsigned ValSizeInBytes = EltSize;
2601 Value = CN->getZExtValue();
2603 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2604 Value = llvm::bit_cast<uint32_t>(CN->getValueAPF().convertToFloat());
2610 if (ValSizeInBytes < ByteSize)
return SDValue();
2621 if (MaskVal == 0)
return SDValue();
2624 if (SignExtend32<5>(MaskVal) == MaskVal)
2638 if (!isa<ConstantSDNode>(
N))
2641 Imm = (int16_t)
N->getAsZExtVal();
2642 if (
N->getValueType(0) == MVT::i32)
2643 return Imm == (int32_t)
N->getAsZExtVal();
2645 return Imm == (int64_t)
N->getAsZExtVal();
2663 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2672 if (
MemSDNode *Memop = dyn_cast<MemSDNode>(U)) {
2673 if (Memop->getMemoryVT() == MVT::f64) {
2674 Base =
N.getOperand(0);
2687 if (!isa<ConstantSDNode>(
N))
2690 Imm = (int64_t)
N->getAsZExtVal();
2691 return isInt<34>(Imm);
2718 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2723 Base =
N.getOperand(0);
2726 }
else if (
N.getOpcode() ==
ISD::OR) {
2728 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2740 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2741 Base =
N.getOperand(0);
2812 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2818 Base =
N.getOperand(0);
2821 }
else if (
N.getOperand(1).getOpcode() ==
PPCISD::Lo) {
2823 assert(!
N.getOperand(1).getConstantOperandVal(1) &&
2824 "Cannot handle constant offsets yet!");
2825 Disp =
N.getOperand(1).getOperand(0);
2830 Base =
N.getOperand(0);
2833 }
else if (
N.getOpcode() ==
ISD::OR) {
2836 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2846 dyn_cast<FrameIndexSDNode>(
N.getOperand(0))) {
2850 Base =
N.getOperand(0);
2863 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm))) {
2866 CN->getValueType(0));
2871 if ((CN->getValueType(0) == MVT::i32 ||
2872 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2873 (!EncodingAlignment ||
2874 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2875 int Addr = (int)CN->getZExtValue();
2882 unsigned Opc = CN->
getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2903 if (
N.getValueType() != MVT::i64)
2916 Base =
N.getOperand(0);
2932 Base =
N.getOperand(0);
2965 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2966 Base =
N.getOperand(0);
2979 Ty *PCRelCand = dyn_cast<Ty>(
N);
2991 if (isValidPCRelNode<ConstantPoolSDNode>(
N) ||
2992 isValidPCRelNode<GlobalAddressSDNode>(
N) ||
2993 isValidPCRelNode<JumpTableSDNode>(
N) ||
2994 isValidPCRelNode<BlockAddressSDNode>(
N))
3010 EVT MemVT = LD->getMemoryVT();
3017 if (!ST.hasP8Vector())
3022 if (!ST.hasP9Vector())
3035 if (UI.getUse().get().getResNo() == 0 &&
3057 Ptr = LD->getBasePtr();
3058 VT = LD->getMemoryVT();
3059 Alignment = LD->getAlign();
3060 }
else if (
StoreSDNode *ST = dyn_cast<StoreSDNode>(
N)) {
3061 Ptr = ST->getBasePtr();
3062 VT = ST->getMemoryVT();
3063 Alignment = ST->getAlign();
3086 if (isa<FrameIndexSDNode>(
Base) || isa<RegisterSDNode>(
Base))
3089 SDValue Val = cast<StoreSDNode>(
N)->getValue();
3102 if (VT != MVT::i64) {
3107 if (Alignment <
Align(4))
3117 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
3119 isa<ConstantSDNode>(
Offset))
3134 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3176 const bool Is64Bit = Subtarget.
isPPC64();
3177 EVT VT = Is64Bit ? MVT::i64 : MVT::i32;
3191 EVT PtrVT =
Op.getValueType();
3207 return getTOCEntry(DAG,
SDLoc(CP), GA);
3210 unsigned MOHiFlag, MOLoFlag;
3217 return getTOCEntry(DAG,
SDLoc(CP), GA);
3277 EVT PtrVT =
Op.getValueType();
3295 return getTOCEntry(DAG,
SDLoc(JT), GA);
3298 unsigned MOHiFlag, MOLoFlag;
3305 return getTOCEntry(DAG,
SDLoc(GA), GA);
3315 EVT PtrVT =
Op.getValueType();
3334 return getTOCEntry(DAG,
SDLoc(BASDN), GA);
3343 unsigned MOHiFlag, MOLoFlag;
3354 return LowerGlobalTLSAddressAIX(
Op, DAG);
3356 return LowerGlobalTLSAddressLinux(
Op, DAG);
3369 bool Is64Bit = Subtarget.
isPPC64();
3370 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3377 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3395 if (HasAIXSmallLocalExecTLS && IsTLSLocalExecModel) {
3414 if (HasAIXSmallLocalExecTLS)
3416 "currently only supported on AIX (64-bit mode).");
3428 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3432 dyn_cast_or_null<GlobalVariable>(
M->getOrInsertGlobal(
3435 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3438 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3442 return DAG.
getNode(
ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
3455 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3456 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3474 bool is64bit = Subtarget.
isPPC64();
3521 if (!
TM.isPositionIndependent())
3580 PtrVT, GOTPtr, TGA, TGA);
3582 PtrVT, TLSAddr, TGA);
3591 EVT PtrVT =
Op.getValueType();
3616 return getTOCEntry(DAG,
DL, GA);
3619 unsigned MOHiFlag, MOLoFlag;
3627 return getTOCEntry(DAG,
DL, GA);
3639 bool IsStrict =
Op->isStrictFPOpcode();
3641 cast<CondCodeSDNode>(
Op.getOperand(IsStrict ? 3 : 2))->get();
3645 EVT LHSVT =
LHS.getValueType();
3649 if (LHSVT == MVT::f128) {
3650 assert(!Subtarget.hasP9Vector() &&
3651 "SETCC for f128 is already legal under Power9!");
3662 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3664 if (
Op.getValueType() == MVT::v2i64) {
3667 if (
LHS.getValueType() == MVT::v2i64) {
3675 int ShuffV[] = {1, 0, 3, 2};
3680 dl, MVT::v4i32, Shuff, SetCC32));
3697 if (
C->isAllOnes() ||
C->isZero())
3707 EVT VT =
Op.getValueType();
3716 EVT VT =
Node->getValueType(0);
3720 const Value *SV = cast<SrcValueSDNode>(
Node->getOperand(2))->getValue();
3730 if (VT == MVT::i64) {
3761 InChain = OverflowArea.
getValue(1);
3807 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3814 assert(!Subtarget.
isPPC64() &&
"LowerVACOPY is PPC32 only");
3829 return Op.getOperand(0);
3838 "Expecting Inline ASM node.");
3848 if (
Op.getOperand(NumOps - 1).getValueType() == MVT::Glue)
3854 unsigned NumVals =
Flags.getNumOperandRegisters();
3857 switch (
Flags.getKind()) {
3868 for (; NumVals; --NumVals, ++i) {
3869 Register Reg = cast<RegisterSDNode>(
Op.getOperand(i))->getReg();
3870 if (Reg != PPC::LR && Reg != PPC::LR8)
3895 bool isPPC64 = (PtrVT == MVT::i64);
3901 Entry.Ty = IntPtrTy;
3902 Entry.Node = Trmp;
Args.push_back(Entry);
3905 Entry.Node = DAG.
getConstant(isPPC64 ? 48 : 40, dl,
3906 isPPC64 ? MVT::i64 : MVT::i32);
3907 Args.push_back(Entry);
3909 Entry.Node = FPtr;
Args.push_back(Entry);
3910 Entry.Node = Nest;
Args.push_back(Entry);
3914 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3918 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
3919 return CallResult.second;
3933 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
3934 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
3969 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
3978 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
3993 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
3996 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
3998 nextOffset += FrameOffset;
3999 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
4002 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
4008static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
4009 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
4010 PPC::F11, PPC::F12, PPC::F13};
4015 unsigned PtrByteSize) {
4017 if (Flags.isByVal())
4018 ArgSize = Flags.getByValSize();
4022 if (!Flags.isInConsecutiveRegs())
4023 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4032 unsigned PtrByteSize) {
4033 Align Alignment(PtrByteSize);
4036 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4037 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4038 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4039 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4040 Alignment =
Align(16);
4043 if (Flags.isByVal()) {
4044 auto BVAlign = Flags.getNonZeroByValAlign();
4045 if (BVAlign > PtrByteSize) {
4046 if (BVAlign.value() % PtrByteSize != 0)
4048 "ByVal alignment is not a multiple of the pointer size");
4050 Alignment = BVAlign;
4055 if (Flags.isInConsecutiveRegs()) {
4059 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4073 unsigned PtrByteSize,
unsigned LinkageSize,
4074 unsigned ParamAreaSize,
unsigned &ArgOffset,
4075 unsigned &AvailableFPRs,
4076 unsigned &AvailableVRs) {
4077 bool UseMemory =
false;
4082 ArgOffset =
alignTo(ArgOffset, Alignment);
4085 if (ArgOffset >= LinkageSize + ParamAreaSize)
4090 if (Flags.isInConsecutiveRegsLast())
4091 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4094 if (ArgOffset > LinkageSize + ParamAreaSize)
4099 if (!Flags.isByVal()) {
4100 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4101 if (AvailableFPRs > 0) {
4105 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4106 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4107 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4108 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4109 if (AvailableVRs > 0) {
4121 unsigned NumBytes) {
4125SDValue PPCTargetLowering::LowerFormalArguments(
4130 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4133 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4136 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4140SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4182 const Align PtrAlign(4);
4191 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4193 CCInfo.PreAnalyzeFormalArguments(Ins);
4196 CCInfo.clearWasPPCF128();
4198 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4211 RC = &PPC::GPRCRegClass;
4214 if (Subtarget.hasP8Vector())
4215 RC = &PPC::VSSRCRegClass;
4216 else if (Subtarget.hasSPE())
4217 RC = &PPC::GPRCRegClass;
4219 RC = &PPC::F4RCRegClass;
4222 if (Subtarget.hasVSX())
4223 RC = &PPC::VSFRCRegClass;
4224 else if (Subtarget.hasSPE())
4226 RC = &PPC::GPRCRegClass;
4228 RC = &PPC::F8RCRegClass;
4233 RC = &PPC::VRRCRegClass;
4236 RC = &PPC::VRRCRegClass;
4240 RC = &PPC::VRRCRegClass;
4247 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4248 assert(i + 1 < e &&
"No second half of double precision argument");
4260 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4261 if (ValVT == MVT::i1)
4276 ArgOffset += ArgSize - ObjSize;
4294 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4299 unsigned MinReservedArea = CCByValInfo.getStackSize();
4300 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4316 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4317 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4319 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4322 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4325 unsigned NumFPArgRegs = std::size(FPArgRegs);
4334 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4338 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4347 for (
unsigned GPRIndex = 0; GPRIndex != NumGPArgRegs; ++GPRIndex) {
4351 VReg = MF.
addLiveIn(GPArgRegs[GPRIndex], &PPC::GPRCRegClass);
4366 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4370 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4383 if (!MemOps.
empty())
4394 const SDLoc &dl)
const {
4398 else if (
Flags.isZExt())
4405SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4418 "fastcc not supported on varargs functions");
4424 unsigned PtrByteSize = 8;
4428 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4429 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4432 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4433 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4436 const unsigned Num_GPR_Regs = std::size(GPR);
4438 const unsigned Num_VR_Regs = std::size(VR);
4446 bool HasParameterArea = !isELFv2ABI || isVarArg;
4447 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4448 unsigned NumBytes = LinkageSize;
4449 unsigned AvailableFPRs = Num_FPR_Regs;
4450 unsigned AvailableVRs = Num_VR_Regs;
4451 for (
unsigned i = 0, e =
Ins.size(); i != e; ++i) {
4452 if (Ins[i].
Flags.isNest())
4456 PtrByteSize, LinkageSize, ParamAreaSize,
4457 NumBytes, AvailableFPRs, AvailableVRs))
4458 HasParameterArea =
true;
4465 unsigned ArgOffset = LinkageSize;
4466 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4469 unsigned CurArgIdx = 0;
4470 for (
unsigned ArgNo = 0, e =
Ins.size(); ArgNo != e; ++ArgNo) {
4472 bool needsLoad =
false;
4473 EVT ObjectVT =
Ins[ArgNo].VT;
4474 EVT OrigVT =
Ins[ArgNo].ArgVT;
4476 unsigned ArgSize = ObjSize;
4478 if (Ins[ArgNo].isOrigArg()) {
4479 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4480 CurArgIdx =
Ins[ArgNo].getOrigArgIndex();
4485 unsigned CurArgOffset;
4487 auto ComputeArgOffset = [&]() {
4491 ArgOffset =
alignTo(ArgOffset, Alignment);
4492 CurArgOffset = ArgOffset;
4499 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4500 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4505 if (
Flags.isByVal()) {
4506 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4512 ObjSize =
Flags.getByValSize();
4513 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4535 if (HasParameterArea ||
4536 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4543 if (ObjSize < PtrByteSize) {
4547 if (!isLittleEndian) {
4553 if (GPR_idx != Num_GPR_Regs) {
4565 ArgOffset += PtrByteSize;
4574 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4575 if (GPR_idx == Num_GPR_Regs)
4586 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4594 ArgOffset += ArgSize;
4603 if (
Flags.isNest()) {
4608 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4609 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4617 if (GPR_idx != Num_GPR_Regs) {
4622 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4625 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4631 ArgSize = PtrByteSize;
4642 if (FPR_idx != Num_FPR_Regs) {
4645 if (ObjectVT == MVT::f32)
4647 Subtarget.hasP8Vector()
4648 ? &PPC::VSSRCRegClass
4649 : &PPC::F4RCRegClass);
4652 ? &PPC::VSFRCRegClass
4653 : &PPC::F8RCRegClass);
4668 if (ObjectVT == MVT::f32) {
4669 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4687 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4688 ArgOffset += ArgSize;
4689 if (
Flags.isInConsecutiveRegsLast())
4690 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4704 if (VR_idx != Num_VR_Regs) {
4721 if (ObjSize < ArgSize && !isLittleEndian)
4722 CurArgOffset += ArgSize - ObjSize;
4732 unsigned MinReservedArea;
4733 if (HasParameterArea)
4734 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4736 MinReservedArea = LinkageSize;
4753 int Depth = ArgOffset;
4762 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4763 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4775 if (!MemOps.
empty())
4784 unsigned ParamSize) {
4786 if (!isTailCall)
return 0;
4790 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4792 if (SPDiff < FI->getTailCallSPDelta())
4808 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4821 if (!
TM.shouldAssumeDSOLocal(CalleeGV))
4827 const Function *
F = dyn_cast<Function>(CalleeGV);
4828 const GlobalAlias *Alias = dyn_cast<GlobalAlias>(CalleeGV);
4833 F = dyn_cast<Function>(GlobalObj);
4866 if (
TM.getFunctionSections() || CalleeGV->
hasComdat() ||
4867 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
4869 if (
const auto *
F = dyn_cast<Function>(CalleeGV)) {
4870 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4882 const unsigned PtrByteSize = 8;
4886 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4887 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4890 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4891 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4894 const unsigned NumGPRs = std::size(GPR);
4895 const unsigned NumFPRs = 13;
4896 const unsigned NumVRs = std::size(VR);
4897 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4899 unsigned NumBytes = LinkageSize;
4900 unsigned AvailableFPRs = NumFPRs;
4901 unsigned AvailableVRs = NumVRs;
4904 if (Param.Flags.isNest())
continue;
4907 LinkageSize, ParamAreaSize, NumBytes,
4908 AvailableFPRs, AvailableVRs))
4919 auto CalleeArgEnd = CB.
arg_end();
4922 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
4923 const Value* CalleeArg = *CalleeArgIter;
4924 const Value* CallerArg = &(*CallerArgIter);
4925 if (CalleeArg == CallerArg)
4933 isa<UndefValue>(CalleeArg))
4951 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
4961bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
4966 bool isCalleeExternalSymbol)
const {
4969 if (
DisableSCO && !TailCallOpt)
return false;
4972 if (isVarArg)
return false;
5048bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5082 if (!
C)
return nullptr;
5084 int Addr =
C->getZExtValue();
5085 if ((
Addr & 3) != 0 ||
5091 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5098struct TailCallArgumentInfo {
5103 TailCallArgumentInfo() =
default;
5113 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5114 SDValue Arg = TailCallArgs[i].Arg;
5115 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5116 int FI = TailCallArgs[i].FrameIdx;
5119 Chain, dl, Arg, FIN,
5128 int SPDiff,
const SDLoc &dl) {
5134 bool isPPC64 = Subtarget.
isPPC64();
5135 int SlotSize = isPPC64 ? 8 : 4;
5136 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5138 NewRetAddrLoc,
true);
5139 EVT VT = isPPC64 ? MVT::i64 : MVT::i32;
5141 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5151 SDValue Arg,
int SPDiff,
unsigned ArgOffset,
5153 int Offset = ArgOffset + SPDiff;
5156 EVT VT = isPPC64 ? MVT::i64 : MVT::i32;
5158 TailCallArgumentInfo
Info;
5160 Info.FrameIdxOp = FIN;
5168SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5173 EVT VT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
5174 LROpOut = getReturnAddrFrameIndex(DAG);
5191 return DAG.
getMemcpy(Chain, dl, Dst, Src, SizeNode,
5192 Flags.getNonZeroByValAlign(),
false,
false,
false,
5200 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5223 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5233 if (!MemOpChains2.
empty())
5257SDValue PPCTargetLowering::LowerCallResult(
5265 CCRetInfo.AnalyzeCallResult(
5271 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5277 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5280 Chain =
Lo.getValue(1);
5281 InGlue =
Lo.getValue(2);
5285 Chain =
Hi.getValue(1);
5286 InGlue =
Hi.getValue(2);
5323 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5355 bool IsStrictFPCall =
false) {
5359 unsigned RetOpc = 0;
5384 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5390 if (IsStrictFPCall) {
5421 auto isLocalCallee = [&]() {
5426 !isa_and_nonnull<GlobalIFunc>(GV);
5437 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5447 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5450 const GlobalValue *GV = cast<GlobalAddressSDNode>(Callee)->getGlobal();
5453 assert(!isa<GlobalIFunc>(GV) &&
"IFunc is not supported on AIX.");
5454 return getAIXFuncEntryPointSymbolSDNode(GV);
5461 const char *SymName = S->getSymbol();
5467 dyn_cast_or_null<Function>(
Mod->getNamedValue(SymName)))
5468 return getAIXFuncEntryPointSymbolSDNode(
F);
5474 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5482 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5489 assert(Callee.getNode() &&
"What no callee?");
5495 "Expected a CALLSEQ_STARTSDNode.");
5512 SDValue MTCTROps[] = {Chain, Callee, Glue};
5513 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5554 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5569 const MVT RegVT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
5573 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5574 Alignment, MMOFlags);
5581 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5588 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5600 "Nest parameter is not supported on AIX.");
5616 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5619 const bool IsPPC64 = Subtarget.
isPPC64();
5621 const MVT RegVT = IsPPC64 ? MVT::i64 : MVT::i32;
5668 for (
unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
5670 RegsToPass[i].second.getValueType()));
5687 assert(Mask &&
"Missing call preserved mask for calling convention");
5695SDValue PPCTargetLowering::FinishCall(
5710 if (!CFlags.IsIndirect)
5714 dl, CFlags.HasNest, Subtarget);
5724 if (CFlags.IsTailCall) {
5728 cast<RegisterSDNode>(Callee)->getReg() == PPC::CTR) ||
5731 isa<ConstantSDNode>(Callee) ||
5733 "Expecting a global address, external symbol, absolute value, "
5734 "register or an indirect tail call when PC Relative calls are "
5738 "Unexpected call opcode for a tail call.");
5745 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5746 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes, Ops);
5758 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5761 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5772 const GlobalValue *CalleeGV = dyn_cast<GlobalValue>(CalleeFunc);
5781 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5782 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5786bool PPCTargetLowering::isEligibleForTCO(
5791 bool isCalleeExternalSymbol)
const {
5796 return IsEligibleForTailCallOptimization_64SVR4(
5797 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5798 isCalleeExternalSymbol);
5800 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5823 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5825 bool IsCalleeExternalSymbol = isa<ExternalSymbolSDNode>(Callee);
5828 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5842 isa<GlobalAddressSDNode>(Callee)) &&
5843 "Callee should be an llvm::Function object.");
5846 <<
"\nTCO callee: ");
5853 "site marked musttail");
5858 if (Subtarget.useLongCalls() && isa<GlobalAddressSDNode>(Callee) &&
5860 Callee = LowerGlobalAddress(Callee, DAG);
5863 CallConv, isTailCall, isVarArg, isPatchPoint,
5871 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5876 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5878 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5882SDValue PPCTargetLowering::LowerCall_32SVR4(
5893 const bool IsVarArg = CFlags.IsVarArg;
5894 const bool IsTailCall = CFlags.IsTailCall;
5900 const Align PtrAlign(4);
5925 CCInfo.PreAnalyzeCallOperands(Outs);
5931 unsigned NumArgs = Outs.
size();
5933 for (
unsigned i = 0; i != NumArgs; ++i) {
5934 MVT ArgVT = Outs[i].VT;
5938 if (Outs[i].IsFixed) {
5948 errs() <<
"Call operand #" << i <<
" has unhandled type "
5958 CCInfo.clearWasPPCF128();
5965 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
5972 unsigned NumBytes = CCByValInfo.getStackSize();
5986 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
5997 bool seenFloatArg =
false;
6002 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
6004 ++i, ++RealArgIdx) {
6006 SDValue Arg = OutVals[RealArgIdx];
6009 if (
Flags.isByVal()) {
6014 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
6037 Chain = CallSeqStart = NewCallSeqStart;
6056 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6063 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6087 if (!MemOpChains.
empty())
6093 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
6094 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
6095 RegsToPass[i].second, InGlue);
6103 SDValue Ops[] = { Chain, InGlue };
6115 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6116 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6121SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6133 return NewCallSeqStart;
6136SDValue PPCTargetLowering::LowerCall_64SVR4(
6145 unsigned NumOps = Outs.
size();
6146 bool IsSibCall =
false;
6150 unsigned PtrByteSize = 8;
6165 assert(!(IsFastCall && CFlags.IsVarArg) &&
6166 "fastcc not supported on varargs functions");
6173 unsigned NumBytes = LinkageSize;
6174 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6177 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6178 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6181 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6182 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6185 const unsigned NumGPRs = std::size(GPR);
6187 const unsigned NumVRs = std::size(VR);
6193 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6194 if (!HasParameterArea) {
6195 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6196 unsigned AvailableFPRs = NumFPRs;
6197 unsigned AvailableVRs = NumVRs;
6198 unsigned NumBytesTmp = NumBytes;
6199 for (
unsigned i = 0; i != NumOps; ++i) {
6200 if (Outs[i].
Flags.isNest())
continue;
6202 PtrByteSize, LinkageSize, ParamAreaSize,
6203 NumBytesTmp, AvailableFPRs, AvailableVRs))
6204 HasParameterArea =
true;
6210 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6215 HasParameterArea =
false;
6218 for (
unsigned i = 0; i != NumOps; ++i) {
6220 EVT ArgVT = Outs[i].VT;
6221 EVT OrigVT = Outs[i].ArgVT;
6227 if (
Flags.isByVal()) {
6228 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6229 if (NumGPRsUsed > NumGPRs)
6230 HasParameterArea =
true;
6237 if (++NumGPRsUsed <= NumGPRs)
6247 if (++NumVRsUsed <= NumVRs)
6251 if (++NumVRsUsed <= NumVRs)
6256 if (++NumFPRsUsed <= NumFPRs)
6260 HasParameterArea =
true;
6267 NumBytes =
alignTo(NumBytes, Alignement);
6270 if (
Flags.isInConsecutiveRegsLast())
6271 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6274 unsigned NumBytesActuallyUsed = NumBytes;
6284 if (HasParameterArea)
6285 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6287 NumBytes = LinkageSize;
6302 if (CFlags.IsTailCall)
6314 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6325 unsigned ArgOffset = LinkageSize;
6331 for (
unsigned i = 0; i != NumOps; ++i) {
6334 EVT ArgVT = Outs[i].VT;
6335 EVT OrigVT = Outs[i].ArgVT;
6344 auto ComputePtrOff = [&]() {
6348 ArgOffset =
alignTo(ArgOffset, Alignment);
6359 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6360 GPR_idx = std::min(GPR_idx, NumGPRs);
6367 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6373 if (
Flags.isByVal()) {
6391 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6392 if (GPR_idx != NumGPRs) {
6396 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6398 ArgOffset += PtrByteSize;
6403 if (GPR_idx == NumGPRs &&
Size < 8) {
6405 if (!isLittleEndian) {
6410 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6413 ArgOffset += PtrByteSize;
6422 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6423 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6428 if (
Size < 8 && GPR_idx != NumGPRs) {
6438 if (!isLittleEndian) {
6442 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6450 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6453 ArgOffset += PtrByteSize;
6459 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6462 if (GPR_idx != NumGPRs) {
6463 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6469 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6470 ArgOffset += PtrByteSize;
6472 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6484 if (
Flags.isNest()) {
6486 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6493 if (GPR_idx != NumGPRs) {
6494 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6499 assert(HasParameterArea &&
6500 "Parameter area must exist to pass an argument in memory.");
6502 true, CFlags.IsTailCall,
false, MemOpChains,
6503 TailCallArguments, dl);
6505 ArgOffset += PtrByteSize;
6508 ArgOffset += PtrByteSize;
6521 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6522 bool NeededLoad =
false;
6525 if (FPR_idx != NumFPRs)
6526 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6529 if (!NeedGPROrStack)
6531 else if (GPR_idx != NumGPRs && !IsFastCall) {
6545 }
else if (!
Flags.isInConsecutiveRegs()) {
6551 }
else if (ArgOffset % PtrByteSize != 0) {
6555 if (!isLittleEndian)
6560 }
else if (
Flags.isInConsecutiveRegsLast()) {
6563 if (!isLittleEndian)
6573 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6581 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6586 assert(HasParameterArea &&
6587 "Parameter area must exist to pass an argument in memory.");
6589 true, CFlags.IsTailCall,
false, MemOpChains,
6590 TailCallArguments, dl);
6597 if (!IsFastCall || NeededLoad) {
6599 Flags.isInConsecutiveRegs()) ? 4 : 8;
6600 if (
Flags.isInConsecutiveRegsLast())
6601 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6621 if (CFlags.IsVarArg) {
6622 assert(HasParameterArea &&
6623 "Parameter area must exist if we have a varargs call.");
6629 if (VR_idx != NumVRs) {
6633 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6636 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6637 if (GPR_idx == NumGPRs)
6644 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6650 if (VR_idx != NumVRs) {
6651 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6656 assert(HasParameterArea &&
6657 "Parameter area must exist to pass an argument in memory.");
6659 true, CFlags.IsTailCall,
true, MemOpChains,
6660 TailCallArguments, dl);
6671 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6672 "mismatch in size of parameter area");
6673 (void)NumBytesActuallyUsed;
6675 if (!MemOpChains.
empty())
6681 if (CFlags.IsIndirect) {
6685 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6700 if (isELFv2ABI && !CFlags.IsPatchPoint)
6701 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6707 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
6708 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
6709 RegsToPass[i].second, InGlue);
6713 if (CFlags.IsTailCall && !IsSibCall)
6717 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6718 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6725 "Required alignment greater than stack alignment.");
6745 return RequiredAlign <= 8;
6750 return RequiredAlign <= 4;
6760 const bool IsPPC64 = Subtarget.
isPPC64();
6762 const MVT RegVT = IsPPC64 ? MVT::i64 : MVT::i32;
6764 if (ValVT == MVT::f128)
6771 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6772 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6774 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6775 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6778 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6779 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6780 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6785 "register width are not supported.");
6791 if (ByValSize == 0) {
6797 const unsigned StackSize =
alignTo(ByValSize, PtrAlign);
6799 for (
const unsigned E =
Offset + StackSize;
Offset < E;
6801 if (
unsigned Reg = State.
AllocateReg(IsPPC64 ? GPR_64 : GPR_32))
6819 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6828 if (
unsigned Reg = State.
AllocateReg(IsPPC64 ? GPR_64 : GPR_32))
6848 for (
unsigned I = 0;
I < StoreSize;
I += PtrAlign.
value()) {
6849 if (
unsigned Reg = State.
AllocateReg(IsPPC64 ? GPR_64 : GPR_32)) {
6850 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
6883 const unsigned VecSize = 16;
6884 const Align VecAlign(VecSize);
6901 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6907 while (NextRegIndex != GPRs.
size() &&
6912 assert(Reg &&
"Allocating register unexpectedly failed.");
6925 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
6937 if (NextRegIndex == GPRs.
size()) {
6946 if (GPRs[NextRegIndex] == PPC::R9) {
6951 const unsigned FirstReg = State.
AllocateReg(PPC::R9);
6952 const unsigned SecondReg = State.
AllocateReg(PPC::R10);
6953 assert(FirstReg && SecondReg &&
6954 "Allocating R9 or R10 unexpectedly failed.");
6968 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
6970 assert(Reg &&
"Failed to allocated register for vararg vector argument");
6985 assert((IsPPC64 || SVT != MVT::i64) &&
6986 "i64 should have been split for 32-bit codegen.");
6994 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
6996 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
6998 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
7006 return &PPC::VRRCRegClass;
7019 else if (Flags.isZExt())
7029 if (PPC::GPRCRegClass.
contains(Reg)) {
7030 assert(Reg >= PPC::R3 && Reg <= PPC::R10 &&
7031 "Reg must be a valid argument register!");
7032 return LASize + 4 * (Reg - PPC::R3);
7035 if (PPC::G8RCRegClass.
contains(Reg)) {
7036 assert(Reg >= PPC::X3 && Reg <= PPC::X10 &&
7037 "Reg must be a valid argument register!");
7038 return LASize + 8 * (Reg - PPC::X3);
7084SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7091 "Unexpected calling convention!");
7101 const bool IsPPC64 = Subtarget.
isPPC64();
7102 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7114 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7115 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7133 auto HandleMemLoc = [&]() {
7136 assert((ValSize <= LocSize) &&
7137 "Object size is larger than size of MemLoc");
7140 if (LocSize > ValSize)
7141 CurArgOffset += LocSize - ValSize;
7143 const bool IsImmutable =
7158 assert(isVarArg &&
"Only use custom memloc for vararg.");
7161 const unsigned OriginalValNo = VA.
getValNo();
7162 (void)OriginalValNo;
7164 auto HandleCustomVecRegLoc = [&]() {
7165 assert(
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7166 "Missing custom RegLoc.");
7169 "Unexpected Val type for custom RegLoc.");
7171 "ValNo mismatch between custom MemLoc and RegLoc.");
7175 Subtarget.hasVSX()));
7182 HandleCustomVecRegLoc();
7183 HandleCustomVecRegLoc();
7187 if (
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7189 "Only 2 custom RegLocs expected for 64-bit codegen.");
7190 HandleCustomVecRegLoc();
7191 HandleCustomVecRegLoc();
7235 const unsigned Size =
7247 if (
Flags.isByVal()) {
7253 if (
Flags.getNonZeroByValAlign() > PtrByteSize)
7256 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7265 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7267 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7280 CopyFrom.
getValue(1), dl, CopyFrom,
7290 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7293 "RegLocs should be for ByVal argument.");
7300 if (
Offset != StackSize) {
7302 "Expected MemLoc for remaining bytes.");
7303 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7317 Subtarget.hasVSX()));
7334 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7336 unsigned CallerReservedArea = std::max<unsigned>(
7337 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7343 CallerReservedArea =
7352 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7353 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7355 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7356 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7357 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7362 for (
unsigned GPRIndex =
7363 (CCInfo.getStackSize() - LinkageSize) / PtrByteSize;
7364 GPRIndex < NumGPArgRegs; ++GPRIndex) {
7367 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7368 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7380 if (!MemOps.
empty())
7386SDValue PPCTargetLowering::LowerCall_AIX(
7399 "Unexpected calling convention!");
7401 if (CFlags.IsPatchPoint)
7408 AIXCCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7416 const bool IsPPC64 = Subtarget.
isPPC64();
7418 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7419 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7420 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7428 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7429 const unsigned NumBytes = std::max<unsigned>(
7430 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7446 for (
unsigned I = 0, E = ArgLocs.
size();
I != E;) {
7447 const unsigned ValNo = ArgLocs[
I].getValNo();
7451 if (
Flags.isByVal()) {
7452 const unsigned ByValSize =
Flags.getByValSize();
7460 auto GetLoad = [&](
EVT VT,
unsigned LoadOffset) {
7469 unsigned LoadOffset = 0;
7472 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7475 LoadOffset += PtrByteSize;
7478 "Unexpected location for pass-by-value argument.");
7482 if (LoadOffset == ByValSize)
7486 assert(ArgLocs[
I].getValNo() == ValNo &&
7487 "Expected additional location for by-value argument.");
7489 if (ArgLocs[
I].isMemLoc()) {
7490 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7495 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7501 CallSeqStart, MemcpyFlags, DAG, dl);
7510 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7511 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7512 "Unexpected register residue for by-value argument.");
7514 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7518 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7528 "Unexpected load emitted during handling of pass-by-value "
7536 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7571 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7579 const unsigned OriginalValNo = VA.
getValNo();
7581 unsigned LoadOffset = 0;
7582 auto HandleCustomVecRegLoc = [&]() {
7583 assert(
I != E &&
"Unexpected end of CCvalAssigns.");
7584 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7585 "Expected custom RegLoc.");
7588 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7594 LoadOffset += PtrByteSize;
7600 HandleCustomVecRegLoc();
7601 HandleCustomVecRegLoc();
7603 if (
I != E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7604 ArgLocs[
I].getValNo() == OriginalValNo) {
7606 "Only 2 custom RegLocs expected for 64-bit codegen.");
7607 HandleCustomVecRegLoc();
7608 HandleCustomVecRegLoc();
7626 "Unexpected register handling for calling convention.");
7632 "Custom register handling only expected for VarArg.");
7650 "Unexpected custom register for argument!");
7671 if (!MemOpChains.
empty())
7676 if (CFlags.IsIndirect) {
7677 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7680 const MVT PtrVT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
7681 const unsigned TOCSaveOffset =
7697 for (
auto Reg : RegsToPass) {
7702 const int SPDiff = 0;
7703 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7704 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7713 CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
7714 return CCInfo.CheckReturn(
7729 CCInfo.AnalyzeReturn(Outs,
7738 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7742 SDValue Arg = OutVals[RealResIdx];
7757 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7780 RetOps.push_back(Glue);
7786PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7791 EVT IntVT =
Op.getValueType();
7795 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7797 SDValue Ops[2] = {Chain, FPSIdx};
7811 bool isPPC64 = Subtarget.
isPPC64();
7812 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7832 bool isPPC64 = Subtarget.
isPPC64();
7853PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
7855 bool isPPC64 = Subtarget.
isPPC64();
7889 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7890 SDValue Ops[3] = { Chain, NegSize, FPSIdx };
7901 bool isPPC64 = Subtarget.
isPPC64();
7913 Op.getOperand(0),
Op.getOperand(1));
7920 Op.getOperand(0),
Op.getOperand(1));
7924 if (
Op.getValueType().isVector())
7925 return LowerVectorLoad(
Op, DAG);
7927 assert(
Op.getValueType() == MVT::i1 &&
7928 "Custom lowering only for i1 loads");
7941 BasePtr, MVT::i8, MMO);
7949 if (
Op.getOperand(1).getValueType().isVector())
7950 return LowerVectorStore(
Op, DAG);
7952 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
7953 "Custom lowering only for i1 stores");
7972 assert(
Op.getValueType() == MVT::i1 &&
7973 "Custom lowering only for i1 results");
8001 EVT TrgVT =
Op.getValueType();
8014 !llvm::has_single_bit<uint32_t>(
8025 if (SrcSize == 256) {
8036 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8044 for (
unsigned i = 0; i < TrgNumElts; ++i)
8047 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8051 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8064 EVT ResVT =
Op.getValueType();
8065 EVT CmpVT =
Op.getOperand(0).getValueType();
8067 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8073 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8090 if (Subtarget.hasP9Vector() && LHS == TV && RHS == FV) {
8122 if (
LHS.getValueType() == MVT::f32)
8135 if (
LHS.getValueType() == MVT::f32)
8144 if (
LHS.getValueType() == MVT::f32)
8158 if (
Cmp.getValueType() == MVT::f32)
8168 if (
Cmp.getValueType() == MVT::f32)
8174 if (
Cmp.getValueType() == MVT::f32)
8180 if (
Cmp.getValueType() == MVT::f32)
8186 if (
Cmp.getValueType() == MVT::f32)
8219 bool IsStrict =
Op->isStrictFPOpcode();
8225 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8228 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8230 MVT DestTy =
Op.getSimpleValueType();
8231 assert(Src.getValueType().isFloatingPoint() &&
8232 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8233 DestTy == MVT::i64) &&
8234 "Invalid FP_TO_INT types");
8235 if (Src.getValueType() == MVT::f32) {
8239 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8240 Chain = Src.getValue(1);
8244 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8245 DestTy = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
8254 assert((IsSigned || Subtarget.hasFPCVT()) &&
8255 "i64 FP_TO_UINT is supported only with FPCVT");
8258 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8262 Conv = DAG.
getNode(Opc, dl, DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src},
8265 Conv = DAG.
getNode(Opc, dl, ConvTy, Src);
8270void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8272 const SDLoc &dl)
const {
8276 bool IsStrict =
Op->isStrictFPOpcode();
8279 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8280 (IsSigned || Subtarget.hasFPCVT());
8282 int FI = cast<FrameIndexSDNode>(FIPtr)->getIndex();
8291 Alignment =
Align(4);
8294 SDValue Ops[] = { Chain, Tmp, FIPtr };
8296 DAG.
getVTList(MVT::Other), Ops, MVT::i32, MMO);
8298 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8302 if (
Op.getValueType() == MVT::i32 && !i32Stack) {
8311 RLI.Alignment = Alignment;
8319 const SDLoc &dl)
const {
8322 if (
Op->isStrictFPOpcode())
8329 const SDLoc &dl)
const {
8330 bool IsStrict =
Op->isStrictFPOpcode();
8333 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8334 EVT SrcVT = Src.getValueType();
8335 EVT DstVT =
Op.getValueType();
8338 if (SrcVT == MVT::f128)
8339 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8343 if (SrcVT == MVT::ppcf128) {
8344 if (DstVT == MVT::i32) {
8349 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8360 {Op.getOperand(0), Lo, Hi}, Flags);
8363 {Res.getValue(1), Res}, Flags);
8369 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8393 {Chain, Src, FltOfs}, Flags);
8397 {Chain, Val}, Flags);
8400 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8418 if (Subtarget.hasDirectMove() && Subtarget.
isPPC64())
8419 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8422 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8424 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8425 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8436bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8441 if (
Op->isStrictFPOpcode())
8446 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8450 Op.getOperand(0).getValueType())) {
8452 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8457 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8458 LD->isNonTemporal())
8460 if (
LD->getMemoryVT() != MemVT)
8470 RLI.Ptr =
LD->getBasePtr();
8471 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8473 "Non-pre-inc AM on PPC?");
8478 RLI.Chain =
LD->getChain();
8479 RLI.MPI =
LD->getPointerInfo();
8480 RLI.IsDereferenceable =
LD->isDereferenceable();
8481 RLI.IsInvariant =
LD->isInvariant();
8482 RLI.Alignment =
LD->getAlign();
8483 RLI.AAInfo =
LD->getAAInfo();
8484 RLI.Ranges =
LD->getRanges();
8486 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8494void PPCTargetLowering::spliceIntoChain(
SDValue ResChain,
8500 SDLoc dl(NewResChain);
8503 NewResChain, DAG.
getUNDEF(MVT::Other));
8505 "A new TF really is required here");
8514bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8515 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8522 if (!Subtarget.hasP9Vector() &&
8531 if (UI.getUse().get().getResNo() != 0)
8553 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8557 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8560 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8561 if (
Op->isStrictFPOpcode()) {
8563 Chain =
Op.getOperand(0);
8565 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8567 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8575 const SDLoc &dl)
const {
8576 assert((
Op.getValueType() == MVT::f32 ||
8577 Op.getValueType() == MVT::f64) &&
8578 "Invalid floating point type as target of conversion");
8579 assert(Subtarget.hasFPCVT() &&
8580 "Int to FP conversions with direct moves require FPCVT");
8581 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8582 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8604 for (
unsigned i = 1; i < NumConcat; ++i)
8611 const SDLoc &dl)
const {
8612 bool IsStrict =
Op->isStrictFPOpcode();
8613 unsigned Opc =
Op.getOpcode();
8614 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8617 "Unexpected conversion type");
8618 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8619 "Supports conversions to v2f64/v4f32 only.");
8623 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8626 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8631 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8634 for (
unsigned i = 0; i < WideNumElts; ++i)
8637 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8638 int SaveElts = FourEltRes ? 4 : 2;
8640 for (
int i = 0; i < SaveElts; i++)
8641 ShuffV[i * Stride] = i;
8643 for (
int i = 1; i <= SaveElts; i++)
8644 ShuffV[i * Stride - 1] = i - 1;
8652 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8653 EVT ExtVT = Src.getValueType();
8654 if (Subtarget.hasP9Altivec())
8665 {Op.getOperand(0), Extend}, Flags);
8667 return DAG.
getNode(Opc, dl,
Op.getValueType(), Extend);
8675 bool IsStrict =
Op->isStrictFPOpcode();
8676 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8681 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8683 EVT InVT = Src.getValueType();
8684 EVT OutVT =
Op.getValueType();
8687 return LowerINT_TO_FPVector(
Op, DAG, dl);
8690 if (
Op.getValueType() == MVT::f128)
8691 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8694 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8697 if (Src.getValueType() == MVT::i1) {
8709 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8710 Subtarget.
isPPC64() && Subtarget.hasFPCVT())
8711 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8713 assert((IsSigned || Subtarget.hasFPCVT()) &&
8714 "UINT_TO_FP is supported only with FPCVT");
8716 if (Src.getValueType() == MVT::i64) {
8728 if (
Op.getValueType() == MVT::f32 &&
8729 !Subtarget.hasFPCVT() &&
8770 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8771 Bits = DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8772 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8773 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8774 }
else if (Subtarget.hasLFIWAX() &&
8775 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8778 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8779 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8782 Ops, MVT::i32, MMO);
8783 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8784 }
else if (Subtarget.hasFPCVT() &&
8785 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8788 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8789 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8792 Ops, MVT::i32, MMO);
8793 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8794 }
else if (((Subtarget.hasLFIWAX() &&
8796 (Subtarget.hasFPCVT() &&
8810 assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
8811 "Expected an i32 store");
8817 RLI.Alignment =
Align(4);
8821 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8822 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8825 dl, DAG.
getVTList(MVT::f64, MVT::Other),
8826 Ops, MVT::i32, MMO);
8827 Chain =
Bits.getValue(1);
8833 Chain =
FP.getValue(1);
8835 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8839 {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
8847 assert(Src.getValueType() == MVT::i32 &&
8848 "Unhandled INT_TO_FP type in custom expander!");
8858 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
8861 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
8870 assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
8871 "Expected an i32 store");
8877 RLI.Alignment =
Align(4);
8882 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8883 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8885 DAG.
getVTList(MVT::f64, MVT::Other), Ops,
8889 spliceIntoChain(RLI.ResChain, Ld.
getValue(1), DAG);
8892 "i32->FP without LFIWAX supported only on PPC64");
8901 Chain, dl, Ext64, FIdx,
8907 MVT::f64, dl, Chain, FIdx,
8915 Chain =
FP.getValue(1);
8916 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8920 {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
8951 EVT VT =
Op.getValueType();
8957 Chain =
MFFS.getValue(1);
8971 "Stack slot adjustment is valid only on big endian subtargets!");
9001 EVT VT =
Op.getValueType();
9005 VT ==
Op.getOperand(1).getValueType() &&
9025 SDValue OutOps[] = { OutLo, OutHi };
9030 EVT VT =
Op.getValueType();
9034 VT ==
Op.getOperand(1).getValueType() &&
9054 SDValue OutOps[] = { OutLo, OutHi };
9060 EVT VT =
Op.getValueType();
9063 VT ==
Op.getOperand(1).getValueType() &&
9083 SDValue OutOps[] = { OutLo, OutHi };
9090 EVT VT =
Op.getValueType();
9097 EVT AmtVT =
Z.getValueType();
9120 static const MVT VTys[] = {
9121 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9124 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9127 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9132 EVT CanonicalVT = VTys[SplatSize-1];
9141 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9142 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9151 EVT DestVT = MVT::Other) {
9152 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9161 EVT DestVT = MVT::Other) {
9164 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9176 for (
unsigned i = 0; i != 16; ++i)
9197 EVT VecVT = V->getValueType(0);
9198 bool RightType = VecVT == MVT::v2f64 ||
9199 (HasP8Vector && VecVT == MVT::v4f32) ||
9200 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9204 bool IsSplat =
true;
9205 bool IsLoad =
false;
9206 SDValue Op0 = V->getOperand(0);
9211 if (V->isConstant())
9213 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9214 if (V->getOperand(i).isUndef())
9218 if (V->getOperand(i).getOpcode() ==
ISD::LOAD ||
9220 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9222 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9224 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD))
9228 if (V->getOperand(i) != Op0 ||
9229 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9232 return !(IsSplat && IsLoad);
9241 if ((
Op.getValueType() != MVT::f128) ||
9262 LoadSDNode *LD = cast<LoadSDNode>(*InputLoad);
9270 APFloat APFloatToConvert = ArgAPFloat;
9271 bool LosesInfo =
true;
9276 ArgAPFloat = APFloatToConvert;
9298 APFloat APFloatToConvert = ArgAPFloat;
9299 bool LosesInfo =
true;
9303 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9308 LoadSDNode *InputNode = dyn_cast<LoadSDNode>(
Op.getOperand(0));
9312 EVT Ty =
Op->getValueType(0);
9315 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9324 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9328 if (Ty == MVT::v2i64) {
9331 if (MemVT == MVT::i32) {
9351 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9354 APInt APSplatBits, APSplatUndef;
9355 unsigned SplatBitSize;
9357 bool BVNIsConstantSplat =
9365 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9366 Subtarget.hasPrefixInstrs()) {
9369 if ((
Op->getValueType(0) == MVT::v2f64) &&
9404 if (!BVNIsConstantSplat || SplatBitSize > 32) {
9411 const SDValue *InputLoad = &
Op.getOperand(0);
9416 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9417 unsigned ElementSize =
9420 assert(((ElementSize == 2 * MemorySize)
9424 "Unmatched element size and opcode!\n");
9429 unsigned NumUsesOfInputLD = 128 / ElementSize;
9431 if (BVInOp.isUndef())
9446 if (NumUsesOfInputLD == 1 &&
9449 Subtarget.hasLFIWAX()))
9458 Subtarget.isISA3_1() && ElementSize <= 16)
9461 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9463 Subtarget.hasVSX()) {
9470 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other), Ops,
9471 LD->getMemoryVT(),
LD->getMemOperand());
9483 if (Subtarget.hasVSX() && Subtarget.
isPPC64() &&
9485 Subtarget.hasP8Vector()))
9492 unsigned SplatSize = SplatBitSize / 8;
9497 if (SplatBits == 0) {
9499 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9511 if (Subtarget.hasPrefixInstrs() && SplatSize == 2)
9513 Op.getValueType(), DAG, dl);
9515 if (Subtarget.hasPrefixInstrs() && SplatSize == 4)
9520 if (Subtarget.hasP9Vector() && SplatSize == 1)
9525 int32_t SextVal= (int32_t(SplatBits << (32-SplatBitSize)) >>
9527 if (SextVal >= -16 && SextVal <= 15)
9540 if (SextVal >= -32 && SextVal <= 31) {
9545 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9546 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9549 if (VT ==
Op.getValueType())
9558 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9572 static const signed char SplatCsts[] = {
9573 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9574 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9577 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9580 int i = SplatCsts[idx];
9584 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9587 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9589 static const unsigned IIDs[] = {
9590 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9591 Intrinsic::ppc_altivec_vslw
9598 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9600 static const unsigned IIDs[] = {
9601 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9602 Intrinsic::ppc_altivec_vsrw
9609 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9610 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9612 static const unsigned IIDs[] = {
9613 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
9614 Intrinsic::ppc_altivec_vrlw
9621 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
9627 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
9633 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
9648 unsigned OpNum = (PFEntry >> 26) & 0x0F;
9649 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
9650 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
9666 if (LHSID == (1*9+2)*9+3)
return LHS;
9667 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
9679 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
9680 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
9681 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
9682 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
9685 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
9686 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
9687 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
9688 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
9691 for (
unsigned i = 0; i != 16; ++i)
9692 ShufIdxs[i] = (i&3)+0;
9695 for (
unsigned i = 0; i != 16; ++i)
9696 ShufIdxs[i] = (i&3)+4;
9699 for (
unsigned i = 0; i != 16; ++i)
9700 ShufIdxs[i] = (i&3)+8;
9703 for (
unsigned i = 0; i != 16; ++i)
9704 ShufIdxs[i] = (i&3)+12;
9725 const unsigned BytesInVector = 16;
9730 unsigned ShiftElts = 0, InsertAtByte = 0;
9734 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
9735 0, 15, 14, 13, 12, 11, 10, 9};
9736 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
9737 1, 2, 3, 4, 5, 6, 7, 8};
9740 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
9752 bool FoundCandidate =
false;
9756 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
9759 for (
unsigned i = 0; i < BytesInVector; ++i) {
9760 unsigned CurrentElement =
Mask[i];
9763 if (
V2.isUndef() && CurrentElement != VINSERTBSrcElem)
9766 bool OtherElementsInOrder =
true;
9769 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
9776 (!
V2.isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
9777 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
9778 OtherElementsInOrder =
false;
9785 if (OtherElementsInOrder) {
9792 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
9793 : BigEndianShifts[CurrentElement & 0xF];
9794 Swap = CurrentElement < BytesInVector;
9796 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
9797 FoundCandidate =
true;
9802 if (!FoundCandidate)
9826 const unsigned NumHalfWords = 8;
9827 const unsigned BytesInVector = NumHalfWords * 2;
9836 unsigned ShiftElts = 0, InsertAtByte = 0;
9840 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
9841 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
9844 uint32_t OriginalOrderLow = 0x1234567;
9845 uint32_t OriginalOrderHigh = 0x89ABCDEF;
9848 for (
unsigned i = 0; i < NumHalfWords; ++i) {
9849 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
9850 Mask |= ((
uint32_t)(
N->getMaskElt(i * 2) / 2) << MaskShift);
9866 bool FoundCandidate =
false;
9869 for (
unsigned i = 0; i < NumHalfWords; ++i) {
9870 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
9872 uint32_t MaskOtherElts = ~(0xF << MaskShift);
9880 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
9881 TargetOrder = OriginalOrderLow;
9885 if (MaskOneElt == VINSERTHSrcElem &&
9886 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
9887 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
9888 FoundCandidate =
true;
9894 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
9896 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
9898 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
9899 : BigEndianShifts[MaskOneElt & 0x7];
9900 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
9901 Swap = MaskOneElt < NumHalfWords;
9902 FoundCandidate =
true;
9908 if (!FoundCandidate)
9943 auto ShuffleMask = SVN->
getMask();
9958 ShuffleMask = CommutedSV->
getMask();
9967 APInt APSplatValue, APSplatUndef;
9968 unsigned SplatBitSize;
9984 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
9985 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
9986 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
9988 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
9989 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
9990 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
9998 for (; SplatBitSize < 32; SplatBitSize <<= 1)
9999 SplatVal |= (SplatVal << SplatBitSize);
10013 assert(
Op.getValueType() == MVT::v1i128 &&
10014 "Only set v1i128 as custom, other type shouldn't reach here!");
10019 if (SHLAmt % 8 == 0) {
10020 std::array<int, 16>
Mask;
10021 std::iota(
Mask.begin(),
Mask.end(), 0);
10022 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10051 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10052 if (!isa<ShuffleVectorSDNode>(NewShuffle))
10055 SVOp = cast<ShuffleVectorSDNode>(
Op);
10056 V1 =
Op.getOperand(0);
10057 V2 =
Op.getOperand(1);
10059 EVT VT =
Op.getValueType();
10062 unsigned ShiftElts, InsertAtByte;
10068 bool IsPermutedLoad =
false;
10070 if (InputLoad && Subtarget.hasVSX() &&
V2.isUndef() &&
10080 if (IsPermutedLoad) {
10081 assert((isLittleEndian || IsFourByte) &&
10082 "Unexpected size for permuted load on big endian target");
10083 SplatIdx += IsFourByte ? 2 : 1;
10084 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10085 "Splat of a value outside of the loaded memory");
10090 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10093 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10095 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10099 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10112 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10115 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10124 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10127 if (Subtarget.hasP9Vector() &&
10146 if (Subtarget.hasPrefixInstrs()) {
10148 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10149 return SplatInsertNode;
10152 if (Subtarget.hasP9Altivec()) {
10154 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10157 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10161 if (Subtarget.hasVSX() &&
10174 if (Subtarget.hasVSX() &&
10187 if (Subtarget.hasP9Vector()) {
10207 if (Subtarget.hasVSX()) {
10228 if (
V2.isUndef()) {
10241 (Subtarget.hasP8Altivec() && (
10252 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10262 (Subtarget.hasP8Altivec() && (
10273 unsigned PFIndexes[4];
10274 bool isFourElementShuffle =
true;
10275 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10277 unsigned EltNo = 8;
10278 for (
unsigned j = 0;
j != 4; ++
j) {
10279 if (PermMask[i * 4 + j] < 0)
10282 unsigned ByteSource = PermMask[i * 4 +
j];
10283 if ((ByteSource & 3) != j) {
10284 isFourElementShuffle =
false;
10289 EltNo = ByteSource / 4;
10290 }
else if (EltNo != ByteSource / 4) {
10291 isFourElementShuffle =
false;
10295 PFIndexes[i] = EltNo;
10303 if (isFourElementShuffle) {
10305 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10306 PFIndexes[2] * 9 + PFIndexes[3];
10309 unsigned Cost = (PFEntry >> 30);
10329 if (
V2.isUndef())
V2 = V1;
10331 return LowerVPERM(
Op, DAG, PermMask, VT, V1, V2);
10340 bool NeedSwap =
false;
10342 bool isPPC64 = Subtarget.
isPPC64();
10344 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10346 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10347 "XXPERM instead\n");
10353 if ((!isLittleEndian && !
V2->hasOneUse() && V1->
hasOneUse()) ||
10354 (isLittleEndian && !V1->
hasOneUse() &&
V2->hasOneUse())) {
10356 NeedSwap = !NeedSwap;
10391 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10393 if (V1HasXXSWAPD) {
10396 else if (SrcElt < 16)
10399 if (V2HasXXSWAPD) {
10402 else if (SrcElt > 15)
10411 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10412 if (isLittleEndian)
10414 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10417 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10420 if (V1HasXXSWAPD) {
10424 if (V2HasXXSWAPD) {
10425 dl =
SDLoc(
V2->getOperand(0));
10426 V2 =
V2->getOperand(0)->getOperand(1);
10429 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10430 if (ValType != MVT::v2f64)
10432 if (
V2.getValueType() != MVT::v2f64)
10436 ShufflesHandledWithVPERM++;
10441 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10443 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10446 dbgs() <<
"With the following permute control vector:\n";
10451 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10455 if (isLittleEndian)
10461 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10473 switch (IntrinsicID) {
10477 case Intrinsic::ppc_altivec_vcmpbfp_p:
10481 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10485 case Intrinsic::ppc_altivec_vcmpequb_p:
10489 case Intrinsic::ppc_altivec_vcmpequh_p:
10493 case Intrinsic::ppc_altivec_vcmpequw_p:
10497 case Intrinsic::ppc_altivec_vcmpequd_p:
10498 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10504 case Intrinsic::ppc_altivec_vcmpneb_p:
10505 case Intrinsic::ppc_altivec_vcmpneh_p:
10506 case Intrinsic::ppc_altivec_vcmpnew_p:
10507 case Intrinsic::ppc_altivec_vcmpnezb_p:
10508 case Intrinsic::ppc_altivec_vcmpnezh_p:
10509 case Intrinsic::ppc_altivec_vcmpnezw_p:
10510 if (Subtarget.hasP9Altivec()) {
10511 switch (IntrinsicID) {
10514 case Intrinsic::ppc_altivec_vcmpneb_p:
10517 case Intrinsic::ppc_altivec_vcmpneh_p:
10520 case Intrinsic::ppc_altivec_vcmpnew_p:
10523 case Intrinsic::ppc_altivec_vcmpnezb_p:
10526 case Intrinsic::ppc_altivec_vcmpnezh_p:
10529 case Intrinsic::ppc_altivec_vcmpnezw_p:
10537 case Intrinsic::ppc_altivec_vcmpgefp_p:
10541 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10545 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10549 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10553 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10557 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10558 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10564 case Intrinsic::ppc_altivec_vcmpgtub_p:
10568 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10572 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10576 case Intrinsic::ppc_altivec_vcmpgtud_p:
10577 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10584 case Intrinsic::ppc_altivec_vcmpequq:
10585 case Intrinsic::ppc_altivec_vcmpgtsq:
10586 case Intrinsic::ppc_altivec_vcmpgtuq:
10587 if (!Subtarget.isISA3_1())
10589 switch (IntrinsicID) {
10592 case Intrinsic::ppc_altivec_vcmpequq:
10595 case Intrinsic::ppc_altivec_vcmpgtsq:
10598 case Intrinsic::ppc_altivec_vcmpgtuq:
10605 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10606 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10607 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10608 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10609 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10610 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10611 if (Subtarget.hasVSX()) {
10612 switch (IntrinsicID) {
10613 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10616 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10619 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10622 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10625 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10628 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10638 case Intrinsic::ppc_altivec_vcmpbfp:
10641 case Intrinsic::ppc_altivec_vcmpeqfp:
10644 case Intrinsic::ppc_altivec_vcmpequb:
10647 case Intrinsic::ppc_altivec_vcmpequh:
10650 case Intrinsic::ppc_altivec_vcmpequw:
10653 case Intrinsic::ppc_altivec_vcmpequd:
10654 if (Subtarget.hasP8Altivec())
10659 case Intrinsic::ppc_altivec_vcmpneb:
10660 case Intrinsic::ppc_altivec_vcmpneh:
10661 case Intrinsic::ppc_altivec_vcmpnew:
10662 case Intrinsic::ppc_altivec_vcmpnezb:
10663 case Intrinsic::ppc_altivec_vcmpnezh:
10664 case Intrinsic::ppc_altivec_vcmpnezw:
10665 if (Subtarget.hasP9Altivec())
10666 switch (IntrinsicID) {
10669 case Intrinsic::ppc_altivec_vcmpneb:
10672 case Intrinsic::ppc_altivec_vcmpneh:
10675 case Intrinsic::ppc_altivec_vcmpnew:
10678 case Intrinsic::ppc_altivec_vcmpnezb:
10681 case Intrinsic::ppc_altivec_vcmpnezh:
10684 case Intrinsic::ppc_altivec_vcmpnezw:
10691 case Intrinsic::ppc_altivec_vcmpgefp:
10694 case Intrinsic::ppc_altivec_vcmpgtfp:
10697 case Intrinsic::ppc_altivec_vcmpgtsb:
10700 case Intrinsic::ppc_altivec_vcmpgtsh:
10703 case Intrinsic::ppc_altivec_vcmpgtsw:
10706 case Intrinsic::ppc_altivec_vcmpgtsd:
10707 if (Subtarget.hasP8Altivec())
10712 case Intrinsic::ppc_altivec_vcmpgtub:
10715 case Intrinsic::ppc_altivec_vcmpgtuh:
10718 case Intrinsic::ppc_altivec_vcmpgtuw:
10721 case Intrinsic::ppc_altivec_vcmpgtud:
10722 if (Subtarget.hasP8Altivec())
10727 case Intrinsic::ppc_altivec_vcmpequq_p:
10728 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10729 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10730 if (!Subtarget.isISA3_1())
10732 switch (IntrinsicID) {
10735 case Intrinsic::ppc_altivec_vcmpequq_p:
10738 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10741 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10755 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
10759 switch (IntrinsicID) {
10760 case Intrinsic::thread_pointer:
10766 case Intrinsic::ppc_rldimi: {
10767 assert(Subtarget.
isPPC64() &&
"rldimi is only available in 64-bit!");
10771 return Op.getOperand(2);
10772 if (
Mask.isAllOnes())
10775 unsigned MB = 0, ME = 0;
10779 if (ME < 63 - SH) {
10782 }
else if (ME > 63 - SH) {
10788 {Op.getOperand(2), Src,
10789 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
10790 DAG.getTargetConstant(MB, dl, MVT::i32)}),
10794 case Intrinsic::ppc_rlwimi: {
10797 return Op.getOperand(2);
10798 if (
Mask.isAllOnes())
10801 unsigned MB = 0, ME = 0;
10805 PPC::RLWIMI, dl, MVT::i32,
10806 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
10807 DAG.getTargetConstant(MB, dl, MVT::i32),
10808 DAG.getTargetConstant(ME, dl, MVT::i32)}),
10812 case Intrinsic::ppc_rlwnm: {
10813 if (
Op.getConstantOperandVal(3) == 0)
10815 unsigned MB = 0, ME = 0;
10820 {Op.getOperand(1), Op.getOperand(2),
10821 DAG.getTargetConstant(MB, dl, MVT::i32),
10822 DAG.getTargetConstant(ME, dl, MVT::i32)}),
10826 case Intrinsic::ppc_mma_disassemble_acc: {
10827 if (Subtarget.isISAFuture()) {
10828 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
10866 case Intrinsic::ppc_vsx_disassemble_pair: {
10869 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
10874 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
10885 case Intrinsic::ppc_mma_xxmfacc:
10886 case Intrinsic::ppc_mma_xxmtacc: {
10888 if (!Subtarget.isISAFuture())
10899 case Intrinsic::ppc_unpack_longdouble: {
10900 auto *
Idx = dyn_cast<ConstantSDNode>(
Op.getOperand(2));
10901 assert(
Idx && (
Idx->getSExtValue() == 0 ||
Idx->getSExtValue() == 1) &&
10902 "Argument of long double unpack must be 0 or 1!");
10905 Idx->getValueType(0)));
10908 case Intrinsic::ppc_compare_exp_lt:
10909 case Intrinsic::ppc_compare_exp_gt:
10910 case Intrinsic::ppc_compare_exp_eq:
10911 case Intrinsic::ppc_compare_exp_uo: {
10913 switch (IntrinsicID) {
10914 case Intrinsic::ppc_compare_exp_lt:
10917 case Intrinsic::ppc_compare_exp_gt:
10920 case Intrinsic::ppc_compare_exp_eq:
10923 case Intrinsic::ppc_compare_exp_uo:
10929 PPC::SELECT_CC_I4, dl, MVT::i32,
10930 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
10931 Op.getOperand(1), Op.getOperand(2)),
10933 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
10934 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
10937 case Intrinsic::ppc_test_data_class: {
10938 EVT OpVT =
Op.getOperand(1).getValueType();
10939 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
10940 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
10944 PPC::SELECT_CC_I4, dl, MVT::i32,
10945 {SDValue(DAG.getMachineNode(CmprOpc, dl, MVT::i32, Op.getOperand(2),
10948 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
10949 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
10952 case Intrinsic::ppc_fnmsub: {
10953 EVT VT =
Op.getOperand(1).getValueType();
10954 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
10960 Op.getOperand(2),
Op.getOperand(3));
10962 case Intrinsic::ppc_convert_f128_to_ppcf128:
10963 case Intrinsic::ppc_convert_ppcf128_to_f128: {
10964 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
10965 ? RTLIB::CONVERT_PPCF128_F128
10966 : RTLIB::CONVERT_F128_PPCF128;
10967 MakeLibCallOptions CallOptions;
10968 std::pair<SDValue, SDValue>
Result =
10969 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
10973 case Intrinsic::ppc_maxfe:
10974 case Intrinsic::ppc_maxfl:
10975 case Intrinsic::ppc_maxfs:
10976 case Intrinsic::ppc_minfe:
10977 case Intrinsic::ppc_minfl:
10978 case Intrinsic::ppc_minfs: {
10979 EVT VT =
Op.getValueType();
10982 [VT](
const SDUse &
Use) { return Use.getValueType() == VT; }) &&
10983 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
10986 if (IntrinsicID == Intrinsic::ppc_minfe ||
10987 IntrinsicID == Intrinsic::ppc_minfl ||
10988 IntrinsicID == Intrinsic::ppc_minfs)
11010 Op.getOperand(1),
Op.getOperand(2),
11021 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11033 switch (
Op.getConstantOperandVal(1)) {
11036 BitNo = 0; InvertBit =
false;
11039 BitNo = 0; InvertBit =
true;
11042 BitNo = 2; InvertBit =
false;
11045 BitNo = 2; InvertBit =
true;
11067 int ArgStart = isa<ConstantSDNode>(
Op.getOperand(0)) ? 0 : 1;
11069 switch (
Op.getConstantOperandVal(ArgStart)) {
11070 case Intrinsic::ppc_cfence: {
11071 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11072 SDValue Val =
Op.getOperand(ArgStart + 1);
11074 if (Ty == MVT::i128) {
11079 unsigned Opcode = Subtarget.
isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11080 EVT FTy = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
11104 int VectorIndex = 0;
11117 "Expecting an atomic compare-and-swap here.");
11119 auto *AtomicNode = cast<AtomicSDNode>(
Op.getNode());
11120 EVT MemVT = AtomicNode->getMemoryVT();
11138 for (
int i = 0, e = AtomicNode->getNumOperands(); i <
e; i++)
11139 Ops.
push_back(AtomicNode->getOperand(i));
11151 EVT MemVT =
N->getMemoryVT();
11153 "Expect quadword atomic operations");
11155 unsigned Opc =
N->getOpcode();
11163 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11164 for (
int I = 1, E =
N->getNumOperands();
I < E; ++
I)
11167 Ops, MemVT,
N->getMemOperand());
11174 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11184 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11194 N->getMemOperand());
11206 enum DataClassMask {
11208 DC_NEG_INF = 1 << 4,
11209 DC_POS_INF = 1 << 5,
11210 DC_NEG_ZERO = 1 << 2,
11211 DC_POS_ZERO = 1 << 3,
11212 DC_NEG_SUBNORM = 1,
11213 DC_POS_SUBNORM = 1 << 1,
11216 EVT VT =
Op.getValueType();
11218 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11219 : VT == MVT::f64 ? PPC::XSTSTDCDP
11230 return DAG.
getNOT(Dl, Rev, MVT::i1);
11237 TestOp, Dl, MVT::i32,
11239 DC_NEG_ZERO | DC_POS_ZERO |
11240 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11246 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11252 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11257 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11270 bool IsQuiet = Mask &
fcQNan;
11276 if (VT == MVT::f128) {
11280 QuietMask = 0x8000;
11281 }
else if (VT == MVT::f64) {
11293 QuietMask = 0x80000;
11294 }
else if (VT == MVT::f32) {
11296 QuietMask = 0x400000;
11312 unsigned NativeMask = 0;
11314 NativeMask |= DC_NAN;
11316 NativeMask |= DC_NEG_INF;
11318 NativeMask |= DC_POS_INF;
11320 NativeMask |= DC_NEG_ZERO;
11322 NativeMask |= DC_POS_ZERO;
11324 NativeMask |= DC_NEG_SUBNORM;
11326 NativeMask |= DC_POS_SUBNORM;
11329 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11331 TestOp, Dl, MVT::i32,
11340 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11342 uint64_t RHSC =
Op.getConstantOperandVal(1);
11367 "Should only be called for ISD::INSERT_VECTOR_ELT");
11371 EVT VT =
Op.getValueType();
11376 if (VT == MVT::v2f64 &&
C)
11379 if (Subtarget.hasP9Vector()) {
11388 if ((VT == MVT::v4f32) && (
V2.getValueType() == MVT::f32) &&
11389 (isa<LoadSDNode>(V2))) {
11394 BitcastLoad,
Op.getOperand(2));
11395 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
11399 if (Subtarget.isISA3_1()) {
11400 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.
isPPC64())
11404 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
11405 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
11415 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
11418 unsigned InsertAtElement =
C->getZExtValue();
11419 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
11421 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
11435 EVT VT =
Op.getValueType();
11437 if (VT != MVT::v256i1 && VT != MVT::v512i1)
11443 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
11444 "Type unsupported without MMA");
11445 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
11446 "Type unsupported without paired vector support");
11451 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
11453 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
11463 std::reverse(Loads.
begin(), Loads.
end());
11464 std::reverse(LoadChains.
begin(), LoadChains.
end());
11482 EVT StoreVT =
Value.getValueType();
11484 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
11490 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
11491 "Type unsupported without MMA");
11492 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
11493 "Type unsupported without paired vector support");
11496 unsigned NumVecs = 2;
11497 if (StoreVT == MVT::v512i1) {
11498 if (Subtarget.isISAFuture()) {
11499 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11501 PPC::DMXXEXTFDMR512, dl,
ArrayRef(ReturnTypes, 2),
Op.getOperand(1));
11504 Value2 =
SDValue(ExtNode, 1);
11509 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
11512 if (Subtarget.isISAFuture()) {
11522 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
11536 if (
Op.getValueType() == MVT::v4i32) {
11553 LHS, RHS, DAG, dl, MVT::v4i32);
11556 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
11561 }
else if (
Op.getValueType() == MVT::v16i8) {
11567 LHS, RHS, DAG, dl, MVT::v8i16);
11572 LHS, RHS, DAG, dl, MVT::v8i16);
11580 for (
unsigned i = 0; i != 8; ++i) {
11581 if (isLittleEndian) {
11583 Ops[i*2+1] = 2*i+16;
11586 Ops[i*2+1] = 2*i+1+16;
11589 if (isLittleEndian)
11599 bool IsStrict =
Op->isStrictFPOpcode();
11600 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
11601 !Subtarget.hasP9Vector())
11611 "Should only be called for ISD::FP_EXTEND");
11615 if (
Op.getValueType() != MVT::v2f64 ||
11616 Op.getOperand(0).getValueType() != MVT::v2f32)
11628 "Node should have 2 operands with second one being a constant!");
11640 int DWord =
Idx >> 1;
11663 LD->getMemoryVT(),
LD->getMemOperand());
11676 LD->getMemoryVT(),
LD->getMemOperand());
11687 switch (
Op.getOpcode()) {
11716 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
11742 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
11743 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
11755 return LowerFP_ROUND(
Op, DAG);
11768 return LowerINTRINSIC_VOID(
Op, DAG);
11770 return LowerBSWAP(
Op, DAG);
11772 return LowerATOMIC_CMP_SWAP(
Op, DAG);
11774 return LowerATOMIC_LOAD_STORE(
Op, DAG);
11776 return LowerIS_FPCLASS(
Op, DAG);
11784 switch (
N->getOpcode()) {
11786 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
11803 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
11806 assert(
N->getValueType(0) == MVT::i1 &&
11807 "Unexpected result type for CTR decrement intrinsic");
11809 N->getValueType(0));
11819 switch (
N->getConstantOperandVal(0)) {
11820 case Intrinsic::ppc_pack_longdouble:
11822 N->getOperand(2),
N->getOperand(1)));
11824 case Intrinsic::ppc_maxfe:
11825 case Intrinsic::ppc_minfe:
11826 case Intrinsic::ppc_fnmsub:
11827 case Intrinsic::ppc_convert_f128_to_ppcf128:
11837 EVT VT =
N->getValueType(0);
11839 if (VT == MVT::i64) {
11852 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
11856 Results.push_back(LoweredValue);
11857 if (
N->isStrictFPOpcode())
11862 if (!
N->getValueType(0).isVector())
11913 if (isa<LoadInst>(Inst))
11917 Intrinsic::ppc_cfence, {Inst->getType()}),
11927 unsigned AtomicSize,
11928 unsigned BinOpcode,
11929 unsigned CmpOpcode,
11930 unsigned CmpPred)
const {
11934 auto LoadMnemonic = PPC::LDARX;
11935 auto StoreMnemonic = PPC::STDCX;
11936 switch (AtomicSize) {
11940 LoadMnemonic = PPC::LBARX;
11941 StoreMnemonic = PPC::STBCX;
11942 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
11945 LoadMnemonic = PPC::LHARX;
11946 StoreMnemonic = PPC::STHCX;
11947 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
11950 LoadMnemonic = PPC::LWARX;
11951 StoreMnemonic = PPC::STWCX;
11954 LoadMnemonic = PPC::LDARX;
11955 StoreMnemonic = PPC::STDCX;
11971 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
11973 F->insert(It, loopMBB);
11975 F->insert(It, loop2MBB);
11976 F->insert(It, exitMBB);
11982 Register TmpReg = (!BinOpcode) ? incr :
11984 : &PPC::GPRCRegClass);
12009 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
12016 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
12018 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
12046 switch(
MI.getOpcode()) {
12050 return TII->isSignExtended(
MI.getOperand(1).getReg(),
12051 &
MI.getMF()->getRegInfo());
12075 case PPC::EXTSB8_32_64:
12076 case PPC::EXTSB8_rec:
12077 case PPC::EXTSB_rec:
12080 case PPC::EXTSH8_32_64:
12081 case PPC::EXTSH8_rec:
12082 case PPC::EXTSH_rec:
12084 case PPC::EXTSWSLI:
12085 case PPC::EXTSWSLI_32_64:
12086 case PPC::EXTSWSLI_32_64_rec:
12087 case PPC::EXTSWSLI_rec:
12088 case PPC::EXTSW_32:
12089 case PPC::EXTSW_32_64:
12090 case PPC::EXTSW_32_64_rec:
12091 case PPC::EXTSW_rec:
12094 case PPC::SRAWI_rec:
12095 case PPC::SRAW_rec:
12104 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
12114 bool IsSignExtended =
12117 if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
12119 BuildMI(*BB,
MI, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
12120 .
addReg(
MI.getOperand(3).getReg());
12121 MI.getOperand(3).setReg(ValueReg);
12125 if (Subtarget.hasPartwordAtomics())
12133 bool is64bit = Subtarget.
isPPC64();
12135 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
12146 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12148 F->insert(It, loopMBB);
12150 F->insert(It, loop2MBB);
12151 F->insert(It, exitMBB);
12157 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12202 if (ptrA != ZeroReg) {
12204 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
12212 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
12213 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
12216 .
addImm(is8bit ? 28 : 27);
12217 if (!isLittleEndian)
12218 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
12220 .
addImm(is8bit ? 24 : 16);
12222 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
12227 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
12237 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
12241 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
12246 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
12250 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
12253 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
12265 unsigned ValueReg = SReg;
12266 unsigned CmpReg = Incr2Reg;
12267 if (CmpOpcode == PPC::CMPW) {
12269 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
12273 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
12275 ValueReg = ValueSReg;
12307 .
addImm(is8bit ? 24 : 16)
12328 Register DstReg =
MI.getOperand(0).getReg();
12330 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
12331 Register mainDstReg =
MRI.createVirtualRegister(RC);
12332 Register restoreDstReg =
MRI.createVirtualRegister(RC);
12335 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
12336 "Invalid Pointer Size!");
12384 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
12385 Register BufReg =
MI.getOperand(1).getReg();
12400 BaseReg = Subtarget.
isPPC64() ? PPC::X1 : PPC::R1;
12402 BaseReg = Subtarget.
isPPC64() ? PPC::BP8 : PPC::BP;
12405 TII->get(Subtarget.
isPPC64() ? PPC::STD : PPC::STW))
12428 TII->get(Subtarget.
isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
12449 TII->get(PPC::PHI), DstReg)
12453 MI.eraseFromParent();
12467 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
12468 "Invalid Pointer Size!");
12471 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12474 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
12475 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
12489 Register BufReg =
MI.getOperand(0).getReg();
12494 if (PVT == MVT::i64) {
12506 if (PVT == MVT::i64) {
12518 if (PVT == MVT::i64) {
12530 if (PVT == MVT::i64) {
12542 if (PVT == MVT::i64 && Subtarget.
isSVR4ABI()) {
12552 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
12555 MI.eraseFromParent();
12571 "Unexpected stack alignment");
12575 unsigned StackProbeSize =
12578 StackProbeSize &= ~(StackAlign - 1);
12579 return StackProbeSize ? StackProbeSize : StackAlign;
12591 const bool isPPC64 = Subtarget.
isPPC64();
12623 MF->
insert(MBBIter, TestMBB);
12624 MF->
insert(MBBIter, BlockMBB);
12625 MF->
insert(MBBIter, TailMBB);
12630 Register DstReg =
MI.getOperand(0).getReg();
12631 Register NegSizeReg =
MI.getOperand(1).getReg();
12632 Register SPReg = isPPC64 ? PPC::X1 : PPC::R1;
12633 Register FinalStackPtr =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12634 Register FramePointer =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12635 Register ActualNegSizeReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12641 if (!
MRI.hasOneNonDBGUse(NegSizeReg))
12643 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
12649 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
12650 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
12652 .
addDef(ActualNegSizeReg)
12654 .
add(
MI.getOperand(2))
12655 .
add(
MI.getOperand(3));
12661 .
addReg(ActualNegSizeReg);
12664 int64_t NegProbeSize = -(int64_t)ProbeSize;
12665 assert(isInt<32>(NegProbeSize) &&
"Unhandled probe size!");
12666 Register ScratchReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12667 if (!isInt<16>(NegProbeSize)) {
12668 Register TempReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12670 .
addImm(NegProbeSize >> 16);
12674 .
addImm(NegProbeSize & 0xFFFF);
12681 Register Div =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12683 .
addReg(ActualNegSizeReg)
12685 Register Mul =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12689 Register NegMod =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12692 .
addReg(ActualNegSizeReg);
12701 Register CmpResult =
MRI.createVirtualRegister(&PPC::CRRCRegClass);
12702 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
12716 BuildMI(BlockMBB,
DL,
TII->get(isPPC64 ? PPC::STDUX : PPC::STWUX), SPReg)
12727 MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12729 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
12730 MaxCallFrameSizeReg)
12731 .
add(
MI.getOperand(2))
12732 .
add(
MI.getOperand(3));
12733 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
12735 .
addReg(MaxCallFrameSizeReg);
12744 MI.eraseFromParent();
12746 ++NumDynamicAllocaProbed;
12751 switch (
MI.getOpcode()) {
12752 case PPC::SELECT_CC_I4:
12753 case PPC::SELECT_CC_I8:
12754 case PPC::SELECT_CC_F4:
12755 case PPC::SELECT_CC_F8:
12756 case PPC::SELECT_CC_F16:
12757 case PPC::SELECT_CC_VRRC:
12758 case PPC::SELECT_CC_VSFRC:
12759 case PPC::SELECT_CC_VSSRC:
12760 case PPC::SELECT_CC_VSRC:
12761 case PPC::SELECT_CC_SPE4:
12762 case PPC::SELECT_CC_SPE:
12770 switch (
MI.getOpcode()) {
12771 case PPC::SELECT_I4:
12772 case PPC::SELECT_I8:
12773 case PPC::SELECT_F4:
12774 case PPC::SELECT_F8:
12775 case PPC::SELECT_F16:
12776 case PPC::SELECT_SPE:
12777 case PPC::SELECT_SPE4:
12778 case PPC::SELECT_VRRC:
12779 case PPC::SELECT_VSFRC:
12780 case PPC::SELECT_VSSRC:
12781 case PPC::SELECT_VSRC:
12791 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
12792 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
12794 MI.getOpcode() == TargetOpcode::PATCHPOINT &&
12807 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
12808 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
12810 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
12811 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
12825 if (Subtarget.hasISEL() &&
12826 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
12827 MI.getOpcode() == PPC::SELECT_CC_I8 ||
12828 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
12830 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
12831 MI.getOpcode() == PPC::SELECT_CC_I8)
12832 Cond.push_back(
MI.getOperand(4));
12835 Cond.push_back(
MI.getOperand(1));
12838 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
12839 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
12855 F->insert(It, copy0MBB);
12856 F->insert(It, sinkMBB);
12860 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
12875 .
addReg(
MI.getOperand(1).getReg())
12878 unsigned SelectPred =
MI.getOperand(4).getImm();
12881 .
addReg(
MI.getOperand(1).getReg())
12898 .
addReg(
MI.getOperand(3).getReg())
12900 .
addReg(
MI.getOperand(2).getReg())
12902 }
else if (
MI.getOpcode() == PPC::ReadTB) {
12918 F->insert(It, readMBB);
12919 F->insert(It, sinkMBB);
12940 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
12950 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
12952 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
12954 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
12956 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
12959 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
12961 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
12963 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
12965 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
12968 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
12970 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
12972 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
12974 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
12977 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
12979 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
12981 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
12983 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
12986 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
12988 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
12990 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
12992 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
12995 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
12997 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
12999 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
13001 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
13004 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
13006 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
13008 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
13010 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
13013 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
13015 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
13017 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
13019 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
13022 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
13024 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
13026 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
13028 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
13031 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
13033 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
13035 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
13037 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
13040 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
13042 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
13044 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
13046 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
13048 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
13049 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
13050 (Subtarget.hasPartwordAtomics() &&
13051 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
13052 (Subtarget.hasPartwordAtomics() &&
13053 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
13054 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
13056 auto LoadMnemonic = PPC::LDARX;
13057 auto StoreMnemonic = PPC::STDCX;
13058 switch (
MI.getOpcode()) {
13061 case PPC::ATOMIC_CMP_SWAP_I8:
13062 LoadMnemonic = PPC::LBARX;
13063 StoreMnemonic = PPC::STBCX;
13064 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13066 case PPC::ATOMIC_CMP_SWAP_I16:
13067 LoadMnemonic = PPC::LHARX;
13068 StoreMnemonic = PPC::STHCX;
13069 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13071 case PPC::ATOMIC_CMP_SWAP_I32:
13072 LoadMnemonic = PPC::LWARX;
13073 StoreMnemonic = PPC::STWCX;
13075 case PPC::ATOMIC_CMP_SWAP_I64:
13076 LoadMnemonic = PPC::LDARX;
13077 StoreMnemonic = PPC::STDCX;
13085 Register oldval =
MI.getOperand(3).getReg();
13086 Register newval =
MI.getOperand(4).getReg();
13092 F->insert(It, loop1MBB);
13093 F->insert(It, loop2MBB);
13094 F->insert(It, exitMBB);
13115 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
13141 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
13142 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
13146 bool is64bit = Subtarget.
isPPC64();
13148 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
13153 Register oldval =
MI.getOperand(3).getReg();
13154 Register newval =
MI.getOperand(4).getReg();
13160 F->insert(It, loop1MBB);
13161 F->insert(It, loop2MBB);
13162 F->insert(It, exitMBB);
13169 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13188 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13220 if (ptrA != ZeroReg) {
13222 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13231 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13232 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
13235 .
addImm(is8bit ? 28 : 27);
13236 if (!isLittleEndian)
13237 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13239 .
addImm(is8bit ? 24 : 16);
13241 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13246 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13251 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
13254 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
13261 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13265 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13268 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
13271 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
13276 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13293 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13317 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
13342 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
13350 }
else if (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
13351 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT ||
13352 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
13353 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
13354 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
13355 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
13358 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
13359 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
13363 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
13367 .
addReg(
MI.getOperand(1).getReg())
13370 MI.getOperand(0).getReg())
13371 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
13372 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
13378 MI.getOperand(0).getReg())
13380 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
13382 unsigned Imm =
MI.getOperand(1).getImm();
13385 MI.getOperand(0).getReg())
13387 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
13389 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13392 if (
MRI.use_empty(OldFPSCRReg))
13393 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
13395 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13406 unsigned Mode =
MI.getOperand(1).getImm();
13407 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
13411 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
13414 }
else if (
MI.getOpcode() == PPC::SETRND) {
13422 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
13423 if (Subtarget.hasDirectMove()) {
13424 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
13428 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
13431 if (RC == &PPC::F8RCRegClass) {
13434 "Unsupported RegClass.");
13436 StoreOp = PPC::STFD;
13441 (RegInfo.
getRegClass(DestReg) == &PPC::F8RCRegClass) &&
13442 "Unsupported RegClass.");
13475 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13478 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13492 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
13500 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
13501 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
13507 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
13514 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
13523 }
else if (
MI.getOpcode() == PPC::SETFLM) {
13527 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13528 if (
MRI.use_empty(OldFPSCRReg))
13529 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
13531 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13534 Register NewFPSCRReg =
MI.getOperand(1).getReg();
13540 }
else if (
MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
13541 MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
13543 }
else if (
MI.getOpcode() == PPC::SPLIT_QUADWORD) {
13550 .
addUse(Src, 0, PPC::sub_gp8_x1);
13553 .
addUse(Src, 0, PPC::sub_gp8_x0);
13554 }
else if (
MI.getOpcode() == PPC::LQX_PSEUDO ||
13555 MI.getOpcode() == PPC::STQX_PSEUDO) {
13561 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
13567 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
13568 :
TII->get(PPC::STQ))
13576 MI.eraseFromParent();
13589 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
13592 return RefinementSteps;
13598 EVT VT =
Op.getValueType();
13601 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
13625PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
13628 EVT VT =
Op.getValueType();
13629 if (VT != MVT::f64 &&
13630 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
13637 int Enabled,
int &RefinementSteps,
13638 bool &UseOneConstNR,
13639 bool Reciprocal)
const {
13641 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
13642 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
13643 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
13644 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
13650 UseOneConstNR = !Subtarget.needsTwoConstNR();
13658 int &RefinementSteps)
const {
13660 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
13661 (VT == MVT::f64 && Subtarget.hasFRE()) ||
13662 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
13663 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
13671unsigned PPCTargetLowering::combineRepeatedFPDivisors()
const {
13709 unsigned Bytes,
int Dist,
13719 int FI = cast<FrameIndexSDNode>(Loc)->getIndex();
13720 int BFI = cast<FrameIndexSDNode>(BaseLoc)->getIndex();
13723 if (FS != BFS || FS != (
int)Bytes)
return false;
13727 SDValue Base1 = Loc, Base2 = BaseLoc;
13728 int64_t Offset1 = 0, Offset2 = 0;
13731 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
13741 if (isGA1 && isGA2 && GV1 == GV2)
13742 return Offset1 == (Offset2 + Dist*Bytes);
13749 unsigned Bytes,
int Dist,
13752 EVT VT = LS->getMemoryVT();
13753 SDValue Loc = LS->getBasePtr();
13759 switch (
N->getConstantOperandVal(1)) {
13760 default:
return false;
13761 case Intrinsic::ppc_altivec_lvx:
13762 case Intrinsic::ppc_altivec_lvxl:
13763 case Intrinsic::ppc_vsx_lxvw4x:
13764 case Intrinsic::ppc_vsx_lxvw4x_be:
13767 case Intrinsic::ppc_vsx_lxvd2x:
13768 case Intrinsic::ppc_vsx_lxvd2x_be:
13771 case Intrinsic::ppc_altivec_lvebx:
13774 case Intrinsic::ppc_altivec_lvehx:
13777 case Intrinsic::ppc_altivec_lvewx:
13787 switch (
N->getConstantOperandVal(1)) {
13788 default:
return false;
13789 case Intrinsic::ppc_altivec_stvx:
13790 case Intrinsic::ppc_altivec_stvxl:
13791 case Intrinsic::ppc_vsx_stxvw4x:
13794 case Intrinsic::ppc_vsx_stxvd2x:
13797 case Intrinsic::ppc_vsx_stxvw4x_be:
13800 case Intrinsic::ppc_vsx_stxvd2x_be:
13803 case Intrinsic::ppc_altivec_stvebx:
13806 case Intrinsic::ppc_altivec_stvehx:
13809 case Intrinsic::ppc_altivec_stvewx:
13826 SDValue Chain = LD->getChain();
13827 EVT VT = LD->getMemoryVT();
13836 while (!Queue.empty()) {
13837 SDNode *ChainNext = Queue.pop_back_val();
13838 if (!Visited.
insert(ChainNext).second)
13841 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(ChainNext)) {
13845 if (!Visited.
count(ChainLD->getChain().getNode()))
13846 Queue.push_back(ChainLD->getChain().getNode());
13848 for (
const SDUse &O : ChainNext->
ops())
13849 if (!Visited.
count(O.getNode()))
13850 Queue.push_back(O.getNode());
13852 LoadRoots.
insert(ChainNext);
13863 for (
SDNode *
I : LoadRoots) {
13864 Queue.push_back(
I);
13866 while (!Queue.empty()) {
13867 SDNode *LoadRoot = Queue.pop_back_val();
13868 if (!Visited.
insert(LoadRoot).second)
13871 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(LoadRoot))
13876 if (((isa<MemSDNode>(U) &&
13877 cast<MemSDNode>(U)->getChain().getNode() == LoadRoot) ||
13880 Queue.push_back(U);
13913 auto Final = Shifted;
13924 DAGCombinerInfo &DCI)
const {
13932 if (!DCI.isAfterLegalizeDAG())
13937 for (
const SDNode *U :
N->uses())
13942 auto OpSize =
N->getOperand(0).getValueSizeInBits();
13946 if (OpSize <
Size) {
13964 DAGCombinerInfo &DCI)
const {
13968 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
13979 N->getValueType(0) != MVT::i1)
13982 if (
N->getOperand(0).getValueType() != MVT::i32 &&
13983 N->getOperand(0).getValueType() != MVT::i64)
13991 cast<CondCodeSDNode>(
N->getOperand(
13993 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
14004 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
14027 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
14028 N->getOperand(0).getOpcode() !=
ISD::OR &&
14029 N->getOperand(0).getOpcode() !=
ISD::XOR &&
14039 N->getOperand(1).getOpcode() !=
ISD::AND &&
14040 N->getOperand(1).getOpcode() !=
ISD::OR &&
14041 N->getOperand(1).getOpcode() !=
ISD::XOR &&
14054 for (
unsigned i = 0; i < 2; ++i) {
14058 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
14059 isa<ConstantSDNode>(
N->getOperand(i)))
14070 while (!BinOps.
empty()) {
14078 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
14112 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14113 if (isa<ConstantSDNode>(Inputs[i]))
14136 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
14158 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14161 if (isa<ConstantSDNode>(Inputs[i]))
14167 std::list<HandleSDNode> PromOpHandles;
14168 for (
auto &PromOp : PromOps)
14169 PromOpHandles.emplace_back(PromOp);
14176 while (!PromOpHandles.empty()) {
14178 PromOpHandles.pop_back();
14184 if (!isa<ConstantSDNode>(PromOp.
getOperand(0)) &&
14187 PromOpHandles.emplace_front(PromOp);
14192 if (isa<ConstantSDNode>(RepValue))
14201 default:
C = 0;
break;
14206 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
14214 PromOpHandles.emplace_front(PromOp);
14222 for (
unsigned i = 0; i < 2; ++i)
14223 if (isa<ConstantSDNode>(Ops[
C+i]))
14232 return N->getOperand(0);
14240 DAGCombinerInfo &DCI)
const {
14258 if (
N->getValueType(0) != MVT::i32 &&
14259 N->getValueType(0) != MVT::i64)
14262 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
14263 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.
isPPC64())))
14266 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
14267 N->getOperand(0).getOpcode() !=
ISD::OR &&
14268 N->getOperand(0).getOpcode() !=
ISD::XOR &&
14279 while (!BinOps.
empty()) {
14287 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
14318 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14319 if (isa<ConstantSDNode>(Inputs[i]))
14330 SelectTruncOp[0].
insert(std::make_pair(
User,
14334 SelectTruncOp[0].
insert(std::make_pair(
User,
14337 SelectTruncOp[1].
insert(std::make_pair(
User,
14343 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
14352 SelectTruncOp[0].
insert(std::make_pair(
User,
14356 SelectTruncOp[0].
insert(std::make_pair(
User,
14359 SelectTruncOp[1].
insert(std::make_pair(
User,
14365 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
14366 bool ReallyNeedsExt =
false;
14370 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14371 if (isa<ConstantSDNode>(Inputs[i]))
14375 Inputs[i].getOperand(0).getValueSizeInBits();
14376 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
14381 OpBits-PromBits))) ||
14384 (OpBits-(PromBits-1)))) {
14385 ReallyNeedsExt =
true;
14393 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14397 if (isa<ConstantSDNode>(Inputs[i]))
14400 SDValue InSrc = Inputs[i].getOperand(0);
14414 std::list<HandleSDNode> PromOpHandles;
14415 for (
auto &PromOp : PromOps)
14416 PromOpHandles.emplace_back(PromOp);
14422 while (!PromOpHandles.empty()) {
14424 PromOpHandles.pop_back();
14428 default:
C = 0;
break;
14433 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
14441 PromOpHandles.emplace_front(PromOp);
14451 (SelectTruncOp[1].count(PromOp.
getNode()) &&
14453 PromOpHandles.emplace_front(PromOp);
14462 for (
unsigned i = 0; i < 2; ++i) {
14463 if (!isa<ConstantSDNode>(Ops[
C+i]))
14480 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
14481 if (SI0 != SelectTruncOp[0].
end())
14483 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
14484 if (SI1 != SelectTruncOp[1].
end())
14493 if (!ReallyNeedsExt)
14494 return N->getOperand(0);
14501 N->getValueSizeInBits(0), PromBits),
14502 dl,
N->getValueType(0)));
14505 "Invalid extension type");
14508 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
14516 DAGCombinerInfo &DCI)
const {
14518 "Should be called with a SETCC node");
14536 EVT VT =
N->getValueType(0);
14537 EVT OpVT =
LHS.getValueType();
14543 return DAGCombineTruncBoolExt(
N, DCI);
14548 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(
Op.getNode()))
14550 Op.getValueType() == MVT::f64;
14562combineElementTruncationToVectorTruncation(
SDNode *
N,
14563 DAGCombinerInfo &DCI)
const {
14565 "Should be called with a BUILD_VECTOR node");
14570 SDValue FirstInput =
N->getOperand(0);
14572 "The input operand must be an fp-to-int conversion.");
14581 bool IsSplat =
true;
14586 EVT TargetVT =
N->getValueType(0);
14587 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
14588 SDValue NextOp =
N->getOperand(i);
14592 if (NextConversion != FirstConversion)
14600 if (
N->getOperand(i) != FirstInput)
14611 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
14612 SDValue In =
N->getOperand(i).getOperand(0);
14635 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
14637 return DAG.
getNode(Opcode, dl, TargetVT, BV);
14650 "Should be called with a BUILD_VECTOR node");
14655 if (!
N->getValueType(0).getVectorElementType().isByteSized())
14658 bool InputsAreConsecutiveLoads =
true;
14659 bool InputsAreReverseConsecutive =
true;
14660 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
14661 SDValue FirstInput =
N->getOperand(0);
14662 bool IsRoundOfExtLoad =
false;
14667 FirstLoad = cast<LoadSDNode>(FirstInput.
getOperand(0));
14672 N->getNumOperands() == 1)
14675 if (!IsRoundOfExtLoad)
14676 FirstLoad = cast<LoadSDNode>(FirstInput);
14680 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
14682 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
14685 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
14691 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
14692 LoadSDNode *LD1 = cast<LoadSDNode>(PreviousInput);
14693 LoadSDNode *LD2 = cast<LoadSDNode>(NextInput);
14702 InputsAreConsecutiveLoads =
false;
14704 InputsAreReverseConsecutive =
false;
14707 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
14712 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
14713 "The loads cannot be both consecutive and reverse consecutive.");
14717 if (InputsAreConsecutiveLoads) {
14718 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
14722 ReturnSDVal = WideLoad;
14723 }
else if (InputsAreReverseConsecutive) {
14725 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
14730 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
14734 DAG.
getUNDEF(
N->getValueType(0)), Ops);
14738 for (
auto *LD : InputLoads)
14740 return ReturnSDVal;
14757 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
14759 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
14761 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
14762 CorrectElems = CorrectElems >> 8;
14763 Elems = Elems >> 8;
14770 EVT VT =
N->getValueType(0);
14808 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
14828 if (Input && Input != Extract.
getOperand(0))
14834 Elems = Elems << 8;
14843 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
14844 if (!isSExtOfVecExtract(
N->getOperand(i))) {
14851 int TgtElemArrayIdx;
14853 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
14854 if (InputSize + OutputSize == 40)
14855 TgtElemArrayIdx = 0;
14856 else if (InputSize + OutputSize == 72)
14857 TgtElemArrayIdx = 1;
14858 else if (InputSize + OutputSize == 48)
14859 TgtElemArrayIdx = 2;
14860 else if (InputSize + OutputSize == 80)
14861 TgtElemArrayIdx = 3;
14862 else if (InputSize + OutputSize == 96)
14863 TgtElemArrayIdx = 4;
14867 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
14869 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
14870 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
14871 if (Elems != CorrectElems) {
14887 if (
N->getValueType(0) != MVT::v1i128)
14890 SDValue Operand =
N->getOperand(0);
14896 auto *LD = cast<LoadSDNode>(Operand);
14897 EVT MemoryType = LD->getMemoryVT();
14901 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
14902 MemoryType == MVT::i32 || MemoryType == MVT::i64;
14905 if (!ValidLDType ||
14911 LD->getChain(), LD->getBasePtr(),
14915 DAG.
getVTList(MVT::v1i128, MVT::Other),
14916 LoadOps, MemoryType, LD->getMemOperand());
14920 DAGCombinerInfo &DCI)
const {
14922 "Should be called with a BUILD_VECTOR node");
14927 if (!Subtarget.hasVSX())
14933 SDValue FirstInput =
N->getOperand(0);
14935 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
14950 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
14959 if (Subtarget.isISA3_1()) {
14965 if (
N->getValueType(0) != MVT::v2f64)
14976 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
14980 SDValue Ext2 =
N->getOperand(1).getOperand(0);
14987 if (!Ext1Op || !Ext2Op)
14996 if (FirstElem == 0 && SecondElem == 1)
14998 else if (FirstElem == 2 && SecondElem == 3)
15006 return DAG.
getNode(NodeType, dl, MVT::v2f64,
15011 DAGCombinerInfo &DCI)
const {
15014 "Need an int -> FP conversion node here");
15025 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
15027 if (!
Op.getOperand(0).getValueType().isSimple())
15029 if (
Op.getOperand(0).getValueType().getSimpleVT() <=
MVT(MVT::i1) ||
15030 Op.getOperand(0).getValueType().getSimpleVT() >
MVT(MVT::i64))
15033 SDValue FirstOperand(
Op.getOperand(0));
15034 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
15035 (FirstOperand.getValueType() == MVT::i8 ||
15036 FirstOperand.getValueType() == MVT::i16);
15037 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
15039 bool DstDouble =
Op.getValueType() == MVT::f64;
15040 unsigned ConvOp =
Signed ?
15046 LoadSDNode *LDN = cast<LoadSDNode>(FirstOperand.getNode());
15055 SDValue ExtOps[] = { Ld, WidthConst };
15057 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
15059 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
15067 if (
Op.getOperand(0).getValueType() == MVT::i32)
15071 "UINT_TO_FP is supported only with FPCVT");
15075 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
15080 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
15087 Subtarget.hasFPCVT()) ||
15089 SDValue Src =
Op.getOperand(0).getOperand(0);
15090 if (Src.getValueType() == MVT::f32) {
15092 DCI.AddToWorklist(Src.getNode());
15093 }
else if (Src.getValueType() != MVT::f64) {
15105 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
15108 DCI.AddToWorklist(
FP.getNode());
15132 switch (
N->getOpcode()) {
15137 Chain = LD->getChain();
15138 Base = LD->getBasePtr();
15139 MMO = LD->getMemOperand();
15158 MVT VecTy =
N->getValueType(0).getSimpleVT();
15166 Chain = Load.getValue(1);
15172 if (VecTy != MVT::v2f64) {
15199 switch (
N->getOpcode()) {
15204 Chain = ST->getChain();
15205 Base = ST->getBasePtr();
15206 MMO = ST->getMemOperand();
15226 SDValue Src =
N->getOperand(SrcOpnd);
15227 MVT VecTy = Src.getValueType().getSimpleVT();
15230 if (VecTy != MVT::v2f64) {
15236 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
15242 StoreOps, VecTy, MMO);
15249 DAGCombinerInfo &DCI)
const {
15252 unsigned Opcode =
N->getOperand(1).getOpcode();
15254 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
15258 &&
"Not a FP_TO_INT Instruction!");
15260 SDValue Val =
N->getOperand(1).getOperand(Strict ? 1 : 0);
15261 EVT Op1VT =
N->getOperand(1).getValueType();
15264 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
15268 bool ValidTypeForStoreFltAsInt =
15269 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.
isPPC64()) ||
15270 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
15273 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
15276 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
15277 cast<StoreSDNode>(
N)->isTruncatingStore() || !ValidTypeForStoreFltAsInt)
15284 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
15290 cast<StoreSDNode>(
N)->getMemoryVT(),
15291 cast<StoreSDNode>(
N)->getMemOperand());
15299 bool PrevElemFromFirstVec = Mask[0] < NumElts;
15300 for (
int i = 1, e = Mask.size(); i < e; i++) {
15301 if (PrevElemFromFirstVec && Mask[i] < NumElts)
15303 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
15305 PrevElemFromFirstVec = !PrevElemFromFirstVec;
15317 FirstOp =
Op.getOperand(i);
15324 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
15334 Op =
Op.getOperand(0);
15349 int LHSMaxIdx,
int RHSMinIdx,
15350 int RHSMaxIdx,
int HalfVec,
15351 unsigned ValidLaneWidth,
15353 for (
int i = 0, e = ShuffV.
size(); i < e; i++) {
15354 int Idx = ShuffV[i];
15355 if ((
Idx >= 0 &&
Idx < LHSMaxIdx) || (
Idx >= RHSMinIdx &&
Idx < RHSMaxIdx))
15357 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - ValidLaneWidth;
15368 SDLoc dl(OrigSToV);
15371 "Expecting a SCALAR_TO_VECTOR here");
15384 "Cannot produce a permuted scalar_to_vector for one element vector");
15386 unsigned ResultInElt = NumElts / 2;
15388 NewMask[ResultInElt] =
Idx->getZExtValue();
15413 int NumElts =
LHS.getValueType().getVectorNumElements();
15423 if (!Subtarget.hasDirectMove())
15433 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
15442 if (SToVLHS || SToVRHS) {
15449 if (SToVLHS && SToVRHS &&
15456 int NumEltsOut = ShuffV.
size();
15461 unsigned ValidLaneWidth =
15463 LHS.getValueType().getScalarSizeInBits()
15465 RHS.getValueType().getScalarSizeInBits();
15469 int LHSMaxIdx = -1;
15470 int RHSMinIdx = -1;
15471 int RHSMaxIdx = -1;
15472 int HalfVec =
LHS.getValueType().getVectorNumElements() / 2;
15484 LHSMaxIdx = NumEltsOut / NumEltsIn;
15493 RHSMinIdx = NumEltsOut;
15494 RHSMaxIdx = NumEltsOut / NumEltsIn + RHSMinIdx;
15507 HalfVec, ValidLaneWidth, Subtarget);
15512 if (!isa<ShuffleVectorSDNode>(Res))
15514 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
15533 if (IsLittleEndian) {
15536 if (Mask[0] < NumElts)
15537 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
15541 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
15546 for (
int i = 0, e =
Mask.size(); i <
e; i += 2) {
15550 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
15555 if (Mask[0] < NumElts)
15556 for (
int i = 0, e =
Mask.size(); i <
e; i += 2) {
15560 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
15565 for (
int i = 1, e =
Mask.size(); i <
e; i += 2) {
15569 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
15576 cast<BuildVectorSDNode>(TheSplat.
getNode())->getSplatValue();
15579 if (IsLittleEndian)
15588 DAGCombinerInfo &DCI)
const {
15590 "Not a reverse memop pattern!");
15595 auto I =
Mask.rbegin();
15596 auto E =
Mask.rend();
15598 for (;
I != E; ++
I) {
15615 if (!Subtarget.hasP9Vector())
15618 if(!IsElementReverse(SVN))
15657 if (IntrinsicID == Intrinsic::ppc_stdcx)
15659 else if (IntrinsicID == Intrinsic::ppc_stwcx)
15661 else if (IntrinsicID == Intrinsic::ppc_sthcx)
15663 else if (IntrinsicID == Intrinsic::ppc_stbcx)
15674 switch (
N->getOpcode()) {
15677 return combineADD(
N, DCI);
15686 !isa<ConstantSDNode>(Op2) ||
N->getValueType(0) != MVT::i64 ||
15696 if (!isUInt<32>(Imm))
15703 return combineSHL(
N, DCI);
15705 return combineSRA(
N, DCI);
15707 return combineSRL(
N, DCI);
15709 return combineMUL(
N, DCI);
15712 return combineFMALike(
N, DCI);
15715 return N->getOperand(0);
15719 return N->getOperand(0);
15725 return N->getOperand(0);
15731 return DAGCombineExtBoolTrunc(
N, DCI);
15733 return combineTRUNCATE(
N, DCI);
15735 if (
SDValue CSCC = combineSetCC(
N, DCI))
15739 return DAGCombineTruncBoolExt(
N, DCI);
15742 return combineFPToIntToFP(
N, DCI);
15745 LSBaseSDNode* LSBase = cast<LSBaseSDNode>(
N->getOperand(0));
15746 return combineVReverseMemOP(cast<ShuffleVectorSDNode>(
N), LSBase, DCI);
15748 return combineVectorShuffle(cast<ShuffleVectorSDNode>(
N), DCI.
DAG);
15751 EVT Op1VT =
N->getOperand(1).getValueType();
15752 unsigned Opcode =
N->getOperand(1).getOpcode();
15756 SDValue Val = combineStoreFPToInt(
N, DCI);
15763 SDValue Val= combineVReverseMemOP(SVN, cast<LSBaseSDNode>(
N), DCI);
15769 if (cast<StoreSDNode>(
N)->isUnindexed() && Opcode ==
ISD::BSWAP &&
15770 N->getOperand(1).getNode()->hasOneUse() &&
15771 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
15772 (Subtarget.hasLDBRX() && Subtarget.
isPPC64() && Op1VT == MVT::i64))) {
15776 EVT mVT = cast<StoreSDNode>(
N)->getMemoryVT();
15780 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
15787 if (Op1VT.
bitsGT(mVT)) {
15792 if (Op1VT == MVT::i64)
15797 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
15801 Ops, cast<StoreSDNode>(
N)->getMemoryVT(),
15802 cast<StoreSDNode>(
N)->getMemOperand());
15808 isa<ConstantSDNode>(
N->getOperand(1)) && Op1VT == MVT::i32) {
15810 EVT MemVT = cast<StoreSDNode>(
N)->getMemoryVT();
15820 cast<StoreSDNode>(
N)->setTruncatingStore(
true);
15829 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
15830 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
15837 EVT VT = LD->getValueType(0);
15844 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
15845 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
15856 auto ReplaceTwoFloatLoad = [&]() {
15857 if (VT != MVT::i64)
15872 if (!LD->hasNUsesOfValue(2, 0))
15875 auto UI = LD->use_begin();
15876 while (UI.getUse().getResNo() != 0) ++UI;
15878 while (UI.getUse().getResNo() != 0) ++UI;
15879 SDNode *RightShift = *UI;
15887 if (RightShift->getOpcode() !=
ISD::SRL ||
15888 !isa<ConstantSDNode>(RightShift->getOperand(1)) ||
15889 RightShift->getConstantOperandVal(1) != 32 ||
15890 !RightShift->hasOneUse())
15893 SDNode *Trunc2 = *RightShift->use_begin();
15903 Bitcast->getValueType(0) != MVT::f32)
15915 SDValue BasePtr = LD->getBasePtr();
15916 if (LD->isIndexed()) {
15918 "Non-pre-inc AM on PPC?");
15926 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
15927 LD->getPointerInfo(), LD->getAlign(),
15928 MMOFlags, LD->getAAInfo());
15934 LD->getPointerInfo().getWithOffset(4),
15937 if (LD->isIndexed()) {
15951 if (ReplaceTwoFloatLoad())
15954 EVT MemVT = LD->getMemoryVT();
15957 if (LD->isUnindexed() && VT.
isVector() &&
15960 !Subtarget.hasP8Vector() &&
15961 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
15962 VT == MVT::v4f32))) &&
15963 LD->getAlign() < ABIAlignment) {
15965 SDValue Chain = LD->getChain();
15994 MVT PermCntlTy, PermTy, LDTy;
15995 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
15996 : Intrinsic::ppc_altivec_lvsl;
15997 IntrLD = Intrinsic::ppc_altivec_lvx;
15998 IntrPerm = Intrinsic::ppc_altivec_vperm;
15999 PermCntlTy = MVT::v16i8;
16000 PermTy = MVT::v4i32;
16019 SDValue BaseLoadOps[] = { Chain, LDXIntID,
Ptr };
16023 BaseLoadOps, LDTy, BaseMMO);
16032 int IncValue = IncOffset;
16049 SDValue ExtraLoadOps[] = { Chain, LDXIntID,
Ptr };
16053 ExtraLoadOps, LDTy, ExtraMMO);
16064 if (isLittleEndian)
16066 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
16069 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
16072 Perm = Subtarget.hasAltivec()
16088 unsigned IID =
N->getConstantOperandVal(0);
16090 : Intrinsic::ppc_altivec_lvsl);
16091 if (IID ==
Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
16098 .
zext(
Add.getScalarValueSizeInBits()))) {
16099 SDNode *BasePtr =
Add->getOperand(0).getNode();
16100 for (
SDNode *U : BasePtr->uses()) {
16102 U->getConstantOperandVal(0) == IID) {
16112 if (isa<ConstantSDNode>(
Add->getOperand(1))) {
16113 SDNode *BasePtr =
Add->getOperand(0).getNode();
16114 for (
SDNode *U : BasePtr->uses()) {
16116 isa<ConstantSDNode>(U->getOperand(1)) &&
16117 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
16123 V->getConstantOperandVal(0) == IID) {
16135 (IID == Intrinsic::ppc_altivec_vmaxsw ||
16136 IID == Intrinsic::ppc_altivec_vmaxsh ||
16137 IID == Intrinsic::ppc_altivec_vmaxsb)) {
16153 V2.getOperand(1) == V1) {
16168 switch (
N->getConstantOperandVal(1)) {
16171 case Intrinsic::ppc_altivec_vsum4sbs:
16172 case Intrinsic::ppc_altivec_vsum4shs:
16173 case Intrinsic::ppc_altivec_vsum4ubs: {
16179 dyn_cast<BuildVectorSDNode>(
N->getOperand(3))) {
16180 APInt APSplatBits, APSplatUndef;
16181 unsigned SplatBitSize;
16184 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
16187 if (BVNIsConstantSplat && APSplatBits == 0)
16192 case Intrinsic::ppc_vsx_lxvw4x:
16193 case Intrinsic::ppc_vsx_lxvd2x:
16205 switch (
N->getConstantOperandVal(1)) {
16208 case Intrinsic::ppc_vsx_stxvw4x:
16209 case Intrinsic::ppc_vsx_stxvd2x:
16218 bool Is64BitBswapOn64BitTgt =
16219 Subtarget.
isPPC64() &&
N->getValueType(0) == MVT::i64;
16221 N->getOperand(0).hasOneUse();
16222 if (IsSingleUseNormalLd &&
16223 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
16224 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
16235 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
16236 MVT::i64 : MVT::i32, MVT::Other),
16237 Ops, LD->getMemoryVT(), LD->getMemOperand());
16241 if (
N->getValueType(0) == MVT::i16)
16258 !IsSingleUseNormalLd)
16260 LoadSDNode *LD = cast<LoadSDNode>(
N->getOperand(0));
16263 if (!LD->isSimple())
16265 SDValue BasePtr = LD->getBasePtr();
16267 LD->getPointerInfo(), LD->getAlign());
16272 LD->getMemOperand(), 4, 4);
16282 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
16291 if (!
N->getOperand(0).hasOneUse() &&
16292 !
N->getOperand(1).hasOneUse() &&
16293 !
N->getOperand(2).hasOneUse()) {
16296 SDNode *VCMPrecNode =
nullptr;
16298 SDNode *LHSN =
N->getOperand(0).getNode();
16302 UI->getOperand(1) ==
N->getOperand(1) &&
16303 UI->getOperand(2) ==
N->getOperand(2) &&
16304 UI->getOperand(0) ==
N->getOperand(0)) {
16317 SDNode *FlagUser =
nullptr;
16319 FlagUser ==
nullptr; ++UI) {
16320 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
16333 return SDValue(VCMPrecNode, 0);
16355 auto RHSAPInt =
RHS->getAsAPIntVal();
16356 if (!RHSAPInt.isIntN(64))
16359 unsigned Val = RHSAPInt.getZExtValue();
16360 auto isImpossibleCompare = [&]() {
16363 if (Val != 0 && Val != 1) {
16365 return N->getOperand(0);
16368 N->getOperand(0),
N->getOperand(4));
16373 unsigned StoreWidth = 0;
16376 if (
SDValue Impossible = isImpossibleCompare())
16390 auto *MemNode = cast<MemSDNode>(
LHS);
16393 DAG.
getVTList(MVT::i32, MVT::Other, MVT::Glue), Ops,
16394 MemNode->getMemoryVT(), MemNode->getMemOperand());
16398 if (
N->getOperand(0) ==
LHS.getValue(1))
16399 InChain =
LHS.getOperand(0);
16411 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
16417 assert(isDot &&
"Can't compare against a vector result!");
16419 if (
SDValue Impossible = isImpossibleCompare())
16422 bool BranchOnWhenPredTrue = (
CC ==
ISD::SETEQ) ^ (Val == 0);
16429 EVT VTs[] = {
LHS.getOperand(2).getValueType(), MVT::Glue };
16434 switch (
LHS.getConstantOperandVal(1)) {
16453 N->getOperand(4), CompNode.
getValue(1));
16458 return DAGCombineBuildVector(
N, DCI);
16469 EVT VT =
N->getValueType(0);
16470 if (VT == MVT::i64 && !Subtarget.
isPPC64())
16472 if ((VT != MVT::i32 && VT != MVT::i64) ||
16480 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
16500 const APInt &DemandedElts,
16502 unsigned Depth)
const {
16504 switch (
Op.getOpcode()) {
16508 if (cast<VTSDNode>(
Op.getOperand(2))->getVT() == MVT::i16)
16509 Known.
Zero = 0xFFFF0000;
16513 switch (
Op.getConstantOperandVal(0)) {
16515 case Intrinsic::ppc_altivec_vcmpbfp_p:
16516 case Intrinsic::ppc_altivec_vcmpeqfp_p:
16517 case Intrinsic::ppc_altivec_vcmpequb_p:
16518 case Intrinsic::ppc_altivec_vcmpequh_p:
16519 case Intrinsic::ppc_altivec_vcmpequw_p:
16520 case Intrinsic::ppc_altivec_vcmpequd_p:
16521 case Intrinsic::ppc_altivec_vcmpequq_p:
16522 case Intrinsic::ppc_altivec_vcmpgefp_p:
16523 case Intrinsic::ppc_altivec_vcmpgtfp_p:
16524 case Intrinsic::ppc_altivec_vcmpgtsb_p:
16525 case Intrinsic::ppc_altivec_vcmpgtsh_p:
16526 case Intrinsic::ppc_altivec_vcmpgtsw_p:
16527 case Intrinsic::ppc_altivec_vcmpgtsd_p:
16528 case Intrinsic::ppc_altivec_vcmpgtsq_p:
16529 case Intrinsic::ppc_altivec_vcmpgtub_p:
16530 case Intrinsic::ppc_altivec_vcmpgtuh_p:
16531 case Intrinsic::ppc_altivec_vcmpgtuw_p:
16532 case Intrinsic::ppc_altivec_vcmpgtud_p:
16533 case Intrinsic::ppc_altivec_vcmpgtuq_p:
16540 switch (
Op.getConstantOperandVal(1)) {
16543 case Intrinsic::ppc_load2r:
16545 Known.
Zero = 0xFFFF0000;
16575 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
16584 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
16586 LoopSize +=
TII->getInstSizeInBytes(J);
16591 if (LoopSize > 16 && LoopSize <= 32)
16605 if (Constraint.
size() == 1) {
16606 switch (Constraint[0]) {
16624 }
else if (Constraint ==
"wc") {
16626 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
16627 Constraint ==
"wf" || Constraint ==
"ws" ||
16628 Constraint ==
"wi" || Constraint ==
"ww") {
16641 Value *CallOperandVal =
info.CallOperandVal;
16644 if (!CallOperandVal)
16651 else if ((
StringRef(constraint) ==
"wa" ||
16663 switch (*constraint) {
16693std::pair<unsigned, const TargetRegisterClass *>
16697 if (Constraint.
size() == 1) {
16699 switch (Constraint[0]) {
16701 if (VT == MVT::i64 && Subtarget.
isPPC64())
16702 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
16703 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
16705 if (VT == MVT::i64 && Subtarget.
isPPC64())
16706 return std::make_pair(0U, &PPC::G8RCRegClass);
16707 return std::make_pair(0U, &PPC::GPRCRegClass);
16713 if (Subtarget.hasSPE()) {
16714 if (VT == MVT::f32 || VT == MVT::i32)
16715 return std::make_pair(0U, &PPC::GPRCRegClass);
16716 if (VT == MVT::f64 || VT == MVT::i64)
16717 return std::make_pair(0U, &PPC::SPERCRegClass);
16719 if (VT == MVT::f32 || VT == MVT::i32)
16720 return std::make_pair(0U, &PPC::F4RCRegClass);
16721 if (VT == MVT::f64 || VT == MVT::i64)
16722 return std::make_pair(0U, &PPC::F8RCRegClass);
16726 if (Subtarget.hasAltivec() && VT.
isVector())
16727 return std::make_pair(0U, &PPC::VRRCRegClass);
16728 else if (Subtarget.hasVSX())
16730 return std::make_pair(0U, &PPC::VFRCRegClass);
16733 return std::make_pair(0U, &PPC::CRRCRegClass);
16735 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
16737 return std::make_pair(0U, &PPC::CRBITRCRegClass);
16738 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
16739 Constraint ==
"wf" || Constraint ==
"wi") &&
16740 Subtarget.hasVSX()) {
16744 return std::make_pair(0U, &PPC::VSRCRegClass);
16745 if (VT == MVT::f32 && Subtarget.hasP8Vector())
16746 return std::make_pair(0U, &PPC::VSSRCRegClass);
16747 return std::make_pair(0U, &PPC::VSFRCRegClass);
16748 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
16749 if (VT == MVT::f32 && Subtarget.hasP8Vector())
16750 return std::make_pair(0U, &PPC::VSSRCRegClass);
16752 return std::make_pair(0U, &PPC::VSFRCRegClass);
16753 }
else if (Constraint ==
"lr") {
16754 if (VT == MVT::i64)
16755 return std::make_pair(0U, &PPC::LR8RCRegClass);
16757 return std::make_pair(0U, &PPC::LRRCRegClass);
16762 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
16766 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
16767 int VSNum = atoi(Constraint.
data() + 3);
16768 assert(VSNum >= 0 && VSNum <= 63 &&
16769 "Attempted to access a vsr out of range");
16771 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
16772 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
16777 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
16778 int RegNum = atoi(Constraint.
data() + 2);
16779 if (RegNum > 31 || RegNum < 0)
16781 if (VT == MVT::f32 || VT == MVT::i32)
16782 return Subtarget.hasSPE()
16783 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
16784 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
16785 if (VT == MVT::f64 || VT == MVT::i64)
16786 return Subtarget.hasSPE()
16787 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
16788 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
16792 std::pair<unsigned, const TargetRegisterClass *> R =
16801 if (R.first && VT == MVT::i64 && Subtarget.
isPPC64() &&
16802 PPC::GPRCRegClass.contains(R.first))
16803 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
16804 PPC::sub_32, &PPC::G8RCRegClass),
16805 &PPC::G8RCRegClass);
16808 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
16809 R.first = PPC::CR0;
16810 R.second = &PPC::CRRCRegClass;
16814 if (Subtarget.
isAIXABI() && !
TM.getAIXExtendedAltivecABI()) {
16815 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
16816 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
16817 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
16818 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
16819 "default AIX AltiVec ABI and cannot be used\n";
16829 std::vector<SDValue> &Ops,
16834 if (Constraint.
size() > 1)
16837 char Letter = Constraint[0];
16852 EVT TCVT = MVT::i64;
16857 if (isInt<16>(
Value))
16861 if (isShiftedUInt<16, 16>(
Value))
16865 if (isShiftedInt<16, 16>(
Value))
16869 if (isUInt<16>(
Value))
16885 if (isInt<16>(-
Value))
16893 if (Result.getNode()) {
16894 Ops.push_back(Result);
16905 if (
I.getNumOperands() <= 1)
16907 if (!isa<ConstantSDNode>(Ops[1].getNode()))
16909 auto IntrinsicID = Ops[1].getNode()->getAsZExtVal();
16910 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
16911 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
16914 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
16942 switch (AM.
Scale) {
16973 unsigned Depth =
Op.getConstantOperandVal(0);
16979 bool isPPC64 = Subtarget.
isPPC64();
16991 isPPC64 ? MVT::i64 : MVT::i32);
16998 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
17006 unsigned Depth =
Op.getConstantOperandVal(0);
17013 bool isPPC64 = PtrVT == MVT::i64;
17019 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
17021 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
17035 bool isPPC64 = Subtarget.
isPPC64();
17069 if (isa<JumpTableSDNode>(GA) || isa<BlockAddressSDNode>(GA))
17087 unsigned Intrinsic)
const {
17088 switch (Intrinsic) {
17089 case Intrinsic::ppc_atomicrmw_xchg_i128:
17090 case Intrinsic::ppc_atomicrmw_add_i128:
17091 case Intrinsic::ppc_atomicrmw_sub_i128:
17092 case Intrinsic::ppc_atomicrmw_nand_i128:
17093 case Intrinsic::ppc_atomicrmw_and_i128:
17094 case Intrinsic::ppc_atomicrmw_or_i128:
17095 case Intrinsic::ppc_atomicrmw_xor_i128:
17096 case Intrinsic::ppc_cmpxchg_i128:
17098 Info.memVT = MVT::i128;
17099 Info.ptrVal =
I.getArgOperand(0);
17105 case Intrinsic::ppc_atomic_load_i128:
17107 Info.memVT = MVT::i128;
17108 Info.ptrVal =
I.getArgOperand(0);
17113 case Intrinsic::ppc_atomic_store_i128:
17115 Info.memVT = MVT::i128;
17116 Info.ptrVal =
I.getArgOperand(2);
17121 case Intrinsic::ppc_altivec_lvx:
17122 case Intrinsic::ppc_altivec_lvxl:
17123 case Intrinsic::ppc_altivec_lvebx:
17124 case Intrinsic::ppc_altivec_lvehx:
17125 case Intrinsic::ppc_altivec_lvewx:
17126 case Intrinsic::ppc_vsx_lxvd2x:
17127 case Intrinsic::ppc_vsx_lxvw4x:
17128 case Intrinsic::ppc_vsx_lxvd2x_be:
17129 case Intrinsic::ppc_vsx_lxvw4x_be:
17130 case Intrinsic::ppc_vsx_lxvl:
17131 case Intrinsic::ppc_vsx_lxvll: {
17133 switch (Intrinsic) {
17134 case Intrinsic::ppc_altivec_lvebx:
17137 case Intrinsic::ppc_altivec_lvehx:
17140 case Intrinsic::ppc_altivec_lvewx:
17143 case Intrinsic::ppc_vsx_lxvd2x:
17144 case Intrinsic::ppc_vsx_lxvd2x_be:
17154 Info.ptrVal =
I.getArgOperand(0);
17161 case Intrinsic::ppc_altivec_stvx:
17162 case Intrinsic::ppc_altivec_stvxl:
17163 case Intrinsic::ppc_altivec_stvebx:
17164 case Intrinsic::ppc_altivec_stvehx:
17165 case Intrinsic::ppc_altivec_stvewx:
17166 case Intrinsic::ppc_vsx_stxvd2x:
17167 case Intrinsic::ppc_vsx_stxvw4x:
17168 case Intrinsic::ppc_vsx_stxvd2x_be:
17169 case Intrinsic::ppc_vsx_stxvw4x_be:
17170 case Intrinsic::ppc_vsx_stxvl:
17171 case Intrinsic::ppc_vsx_stxvll: {
17173 switch (Intrinsic) {
17174 case Intrinsic::ppc_altivec_stvebx:
17177 case Intrinsic::ppc_altivec_stvehx:
17180 case Intrinsic::ppc_altivec_stvewx:
17183 case Intrinsic::ppc_vsx_stxvd2x:
17184 case Intrinsic::ppc_vsx_stxvd2x_be:
17194 Info.ptrVal =
I.getArgOperand(1);
17201 case Intrinsic::ppc_stdcx:
17202 case Intrinsic::ppc_stwcx:
17203 case Intrinsic::ppc_sthcx:
17204 case Intrinsic::ppc_stbcx: {
17206 auto Alignment =
Align(8);
17207 switch (Intrinsic) {
17208 case Intrinsic::ppc_stdcx:
17211 case Intrinsic::ppc_stwcx:
17213 Alignment =
Align(4);
17215 case Intrinsic::ppc_sthcx:
17217 Alignment =
Align(2);
17219 case Intrinsic::ppc_stbcx:
17221 Alignment =
Align(1);
17226 Info.ptrVal =
I.getArgOperand(0);
17228 Info.align = Alignment;
17246 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
17247 if (
Op.isMemset() && Subtarget.hasVSX()) {
17252 if (TailSize > 2 && TailSize <= 4) {
17257 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
17276 return !(BitSize == 0 || BitSize > 64);
17284 return NumBits1 == 64 && NumBits2 == 32;
17292 return NumBits1 == 64 && NumBits2 == 32;
17298 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(Val)) {
17299 EVT MemVT = LD->getMemoryVT();
17300 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
17301 (Subtarget.
isPPC64() && MemVT == MVT::i32)) &&
17317 "invalid fpext types");
17319 if (DestVT == MVT::f128)
17325 return isInt<16>(Imm) || isUInt<16>(Imm);
17329 return isInt<16>(Imm) || isUInt<16>(Imm);
17334 unsigned *
Fast)
const {
17348 !Subtarget.allowsUnalignedFPAccess())
17352 if (Subtarget.hasVSX()) {
17353 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
17354 VT != MVT::v4f32 && VT != MVT::v4i32)
17361 if (VT == MVT::ppcf128)
17375 if (
auto *ConstNode = dyn_cast<ConstantSDNode>(
C.getNode())) {
17376 if (!ConstNode->getAPIntValue().isSignedIntN(64))
17384 int64_t Imm = ConstNode->getSExtValue();
17385 unsigned Shift = llvm::countr_zero<uint64_t>(Imm);
17387 if (isInt<16>(Imm))
17412 return Subtarget.hasP9Vector();
17420 if (!
I->hasOneUse())
17424 assert(
User &&
"A single use instruction with no uses.");
17426 switch (
I->getOpcode()) {
17427 case Instruction::FMul: {
17429 if (
User->getOpcode() != Instruction::FSub &&
17430 User->getOpcode() != Instruction::FAdd)
17443 case Instruction::Load: {
17456 if (
User->getOpcode() != Instruction::Store)
17476 static const MCPhysReg ScratchRegs[] = {
17477 PPC::X12, PPC::LR8, PPC::CTR8, 0
17480 return ScratchRegs;
17484 const Constant *PersonalityFn)
const {
17485 return Subtarget.
isPPC64() ? PPC::X3 : PPC::R3;
17489 const Constant *PersonalityFn)
const {
17490 return Subtarget.
isPPC64() ? PPC::X4 : PPC::R4;
17495 EVT VT ,
unsigned DefinedValues)
const {
17496 if (VT == MVT::v2i64)
17497 return Subtarget.hasDirectMove();
17499 if (Subtarget.hasVSX())
17533 bool LegalOps,
bool OptForSize,
17535 unsigned Depth)
const {
17539 unsigned Opc =
Op.getOpcode();
17540 EVT VT =
Op.getValueType();
17565 if (Flags.hasNoSignedZeros() ||
Options.NoSignedZerosFPMath) {
17569 N0Cost,
Depth + 1);
17573 N1Cost,
Depth + 1);
17575 if (NegN0 && N0Cost <= N1Cost) {
17576 Cost = std::min(N0Cost, N2Cost);
17577 return DAG.
getNode(Opc, Loc, VT, NegN0, N1, NegN2, Flags);
17578 }
else if (NegN1) {
17579 Cost = std::min(N1Cost, N2Cost);
17580 return DAG.
getNode(Opc, Loc, VT, N0, NegN1, NegN2, Flags);
17623 bool ForCodeSize)
const {
17624 if (!VT.
isSimple() || !Subtarget.hasVSX())
17634 if (Subtarget.hasPrefixInstrs()) {
17639 APSInt IntResult(16,
false);
17644 if (IsExact && IntResult <= 15 && IntResult >= -16)
17646 return Imm.isZero();
17649 return Imm.isPosZero();
17661 unsigned Opcode =
N->getOpcode();
17662 unsigned TargetOpcode;
17681 if (Mask->getZExtValue() == OpSizeInBits - 1)
17687SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17693 if (!Subtarget.isISA3_0() || !Subtarget.
isPPC64() ||
17696 N->getValueType(0) != MVT::i64)
17711 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
17717SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17724SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17743 auto isZextOfCompareWithConstant = [](
SDValue Op) {
17745 Op.getValueType() != MVT::i64)
17749 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
17750 Cmp.getOperand(0).getValueType() != MVT::i64)
17753 if (
auto *
Constant = dyn_cast<ConstantSDNode>(Cmp.getOperand(1))) {
17754 int64_t NegConstant = 0 -
Constant->getSExtValue();
17757 return isInt<16>(NegConstant);
17763 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
17764 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
17767 if (LHSHasPattern && !RHSHasPattern)
17769 else if (!LHSHasPattern && !RHSHasPattern)
17775 SDValue Z = Cmp.getOperand(0);
17776 auto *
Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
17777 int64_t NegConstant = 0 -
Constant->getSExtValue();
17779 switch(cast<CondCodeSDNode>(Cmp.getOperand(2))->get()) {
17790 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
17805 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
17842 if (!GSDN || !ConstNode)
17849 if (!isInt<34>(NewOffset))
17862SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17882 DAGCombinerInfo &DCI)
const {
17884 if (Subtarget.useCRBits()) {
17886 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
17887 return CRTruncValue;
17894 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
17897 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
17907 EltToExtract = EltToExtract ? 0 : 1;
17917 return DCI.DAG.getNode(
17919 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
17924SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17928 if (!ConstOpOrElement)
17936 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne,
EVT VT) ->
bool {
17959 return IsAddOne && IsNeg ? VT.
isVector() :
true;
17963 EVT VT =
N->getValueType(0);
17970 if ((MulAmtAbs - 1).isPowerOf2()) {
17974 if (!IsProfitable(IsNeg,
true, VT))
17987 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
17991 if (!IsProfitable(IsNeg,
false, VT))
18012 DAGCombinerInfo &DCI)
const {
18017 EVT VT =
N->getValueType(0);
18020 unsigned Opc =
N->getOpcode();
18022 bool LegalOps = !DCI.isBeforeLegalizeOps();
18030 if (!
Flags.hasNoSignedZeros() && !
Options.NoSignedZerosFPMath)
18046bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
18063 if (!Callee ||
Callee->isVarArg())
18076bool PPCTargetLowering::
18077isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
18080 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(Mask)) {
18082 if (CI->getBitWidth() > 64)
18084 int64_t ConstVal = CI->getZExtValue();
18085 return isUInt<16>(ConstVal) ||
18086 (isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
18095PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
18101 if ((Flags & FlagSet) == FlagSet)
18104 if ((Flags & FlagSet) == FlagSet)
18107 if ((Flags & FlagSet) == FlagSet)
18110 if ((Flags & FlagSet) == FlagSet)
18131 if ((FrameIndexAlign % 4) != 0)
18132 FlagSet &= ~PPC::MOF_RPlusSImm16Mult4;
18133 if ((FrameIndexAlign % 16) != 0)
18134 FlagSet &= ~PPC::MOF_RPlusSImm16Mult16;
18138 if ((FrameIndexAlign % 4) == 0)
18140 if ((FrameIndexAlign % 16) == 0)
18153 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
18154 if ((Imm & 0x3) == 0)
18156 if ((Imm & 0xf) == 0)
18162 const APInt &ConstImm = CN->getAPIntValue();
18181 const APInt &ConstImm = CN->getAPIntValue();
18191 }
else if (
RHS.getOpcode() ==
PPCISD::Lo && !
RHS.getConstantOperandVal(1))
18203 isValidPCRelNode<ConstantPoolSDNode>(
N) ||
18204 isValidPCRelNode<GlobalAddressSDNode>(
N) ||
18205 isValidPCRelNode<JumpTableSDNode>(
N) ||
18206 isValidPCRelNode<BlockAddressSDNode>(
N));
18211unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
18216 if (!Subtarget.hasP9Vector())
18220 if (Subtarget.hasPrefixInstrs())
18223 if (Subtarget.hasSPE())
18232 unsigned ParentOp = Parent->
getOpcode();
18236 if ((
ID == Intrinsic::ppc_vsx_lxvp) || (
ID == Intrinsic::ppc_vsx_stxvp)) {
18237 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
18248 if (
const LSBaseSDNode *LSB = dyn_cast<LSBaseSDNode>(Parent))
18249 if (LSB->isIndexed())
18254 const MemSDNode *MN = dyn_cast<MemSDNode>(Parent);
18255 assert(MN &&
"Parent should be a MemSDNode!");
18260 "Not expecting scalar integers larger than 16 bytes!");
18263 else if (
Size == 32)
18270 else if (
Size == 256) {
18271 assert(Subtarget.pairedVectorMemops() &&
18272 "256-bit vectors are only available when paired vector memops is "
18280 else if (MemVT == MVT::f128 || MemVT.
isVector())
18290 if (
const LoadSDNode *LN = dyn_cast<LoadSDNode>(Parent)) {
18311 FlagSet &= ~PPC::MOF_NoExt;
18316 bool IsNonP1034BitConst =
18320 IsNonP1034BitConst)
18333 int16_t ForceXFormImm = 0;
18336 Disp =
N.getOperand(0);
18337 Base =
N.getOperand(1);
18348 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
18349 Disp =
N.getOperand(0);
18350 Base =
N.getOperand(1);
18364 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID>
CC)
const {
18370 if (PartVT == MVT::f64 &&
18371 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
18380SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
18384 EVT RetVT =
Op.getValueType();
18392 EVT ArgVT =
N.getValueType();
18397 Entry.IsZExt = !Entry.IsSExt;
18398 Args.push_back(Entry);
18406 (
RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
18412 .setTailCall(isTailCall)
18419SDValue PPCTargetLowering::lowerLibCallBasedOnType(
18420 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
18422 if (
Op.getValueType() == MVT::f32)
18423 return lowerToLibCall(LibCallFloatName,
Op, DAG);
18425 if (
Op.getValueType() == MVT::f64)
18426 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
18431bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
18433 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
18437bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
18438 return Op.getNode()->getFlags().hasApproximateFuncs();
18441bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
18445SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
18446 const char *LibCallFloatName,
18447 const char *LibCallDoubleNameFinite,
18448 const char *LibCallFloatNameFinite,
18451 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
18454 if (!isLowringToMASSFiniteSafe(
Op))
18455 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
18458 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
18459 LibCallDoubleNameFinite,
Op, DAG);
18463 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
18464 "__xl_powf_finite",
Op, DAG);
18468 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
18469 "__xl_sinf_finite",
Op, DAG);
18473 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
18474 "__xl_cosf_finite",
Op, DAG);
18478 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
18479 "__xl_logf_finite",
Op, DAG);
18483 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
18484 "__xl_log10f_finite",
Op, DAG);
18488 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
18489 "__xl_expf_finite",
Op, DAG);
18496 if (!isa<FrameIndexSDNode>(
N))
18514 unsigned Flags = computeMOFlags(Parent,
N, DAG);
18526 "Must be using PC-Relative calls when a valid PC-Relative node is "
18556 Disp =
N.getOperand(1).getOperand(0);
18561 Base =
N.getOperand(0);
18568 auto *CN = cast<ConstantSDNode>(
N);
18569 EVT CNType = CN->getValueType(0);
18570 uint64_t CNImm = CN->getZExtValue();
18581 if ((CNType == MVT::i32 || isInt<32>(CNImm)) &&
18583 int32_t
Addr = (int32_t)CNImm;
18588 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
18604 unsigned Opcode =
N.getOpcode();
18612 Base =
N.getOperand(0);
18631 Base = FI ?
N :
N.getOperand(1);
18643 bool IsVarArg)
const {
18653 return Subtarget.
isPPC64() && Subtarget.hasQuadwordAtomics();
18687 return Intrinsic::ppc_atomicrmw_xchg_i128;
18689 return Intrinsic::ppc_atomicrmw_add_i128;
18691 return Intrinsic::ppc_atomicrmw_sub_i128;
18693 return Intrinsic::ppc_atomicrmw_and_i128;
18695 return Intrinsic::ppc_atomicrmw_or_i128;
18697 return Intrinsic::ppc_atomicrmw_xor_i128;
18699 return Intrinsic::ppc_atomicrmw_nand_i128;
18716 Value *LoHi = Builder.
CreateCall(RMW, {AlignedAddr, IncrLo, IncrHi});
18722 Lo, Builder.
CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
18743 Builder.
CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
18750 Lo, Builder.
CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
unsigned const MachineRegisterInfo * MRI
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall)
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 const unsigned PerfectShuffleTable[6561+1]
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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.
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
Given that RA is a live propagate it s liveness to any other values it uses(according to Uses). void DeadArgumentEliminationPass
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...
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
Module.h This file contains the declarations for the Module class.
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 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 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 bool provablyDisjointOr(SelectionDAG &DAG, const SDValue &N)
Used when computing address flags for selecting loads and stores.
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 bool callsShareTOCBase(const Function *Caller, const GlobalValue *CalleeGV, const TargetMachine &TM)
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 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 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 fixupShuffleMaskForPermutedSToV(SmallVectorImpl< int > &ShuffV, int LHSMaxIdx, int RHSMinIdx, int RHSMaxIdx, int HalfVec, unsigned ValidLaneWidth, const PPCSubtarget &Subtarget)
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 int getEstimateRefinementSteps(EVT VT, const PPCSubtarget &Subtarget)
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 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 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)
const char LLVMTargetMachineRef TM
pre isel intrinsic Pre ISel Intrinsic Lowering
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SI optimize exec mask operations pre RA
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 implements the StringSwitch template, which mimics a switch() statement whose cases are str...
This file describes how to lower LLVM code to machine code.
This defines the Use class.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static bool is64Bit(const char *name)
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.
@ 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 getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP)
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).
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.
Type * getValueType() const
bool hasProtectedVisibility() const
Common base class shared among various IRBuilders.
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="")
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
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)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="", MDNode *FPMathTag=nullptr)
const BasicBlock * getParent() const
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
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.
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.
MachineModuleInfo & getMMI() const
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,.
const MCContext & getContext() const
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.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
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)
int getReturnAddrSaveIndex() const
unsigned getVarArgsNumFPR() const
int getFramePointerSaveIndex() const
void setVarArgsNumGPR(unsigned Num)
void appendParameterType(ParamType Type)
int getVarArgsFrameIndex() const
void setLRStoreRequired()
void setTailCallSPDelta(int size)
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
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.
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.
uint64_t getByValTypeAlignment(Type *Ty, const DataLayout &DL) const override
getByValTypeAlignment - Return the desired alignment for ByVal aggregate function arguments in the ca...
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
bool useLoadStackGuardNode() const override
Override to support customized stack guard loading.
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 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.
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
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 getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS)
Helper function to make it easier to build Select's if you just have operands and don't want to check...
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 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 getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
Align getEVTAlign(EVT MemoryVT) const
Compute the default alignment value for the given type.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
static constexpr unsigned MaxRecursionDepth
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), AAResults *AA=nullptr)
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.
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 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 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 getRegister(unsigned Reg, EVT VT)
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 getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
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 getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
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).
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
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...
virtual bool shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const
Returns true if arguments should be sign-extended in lib calls.
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?...
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.
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL, bool LegalTypes=true) const
Returns the type for the shift amount of a shift opcode.
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...
NegatibleCost
Enum that specifies when a float negation is beneficial.
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
virtual bool useLoadStackGuardNode() const
If this function returns true, SelectionDAGBuilder emits a LOAD_STACK_GUARD node when it is lowering ...
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 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.
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.
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, ptr, val) 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.
@ 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.
@ 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 minimum or maximum 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.
@ ADJUST_TRAMPOLINE
ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
bool isEXTLoad(const SDNode *N)
Returns true if the specified node is a EXTLOAD.
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.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
@ 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 ....
@ 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 ...
@ 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...
@ STBRX
CHAIN = STBRX CHAIN, GPRC, Ptr, Type - This is a byte-swapping store instruction.
@ LD_GOT_TPREL_L
G8RC = LD_GOT_TPREL_L Symbol, G8RReg - Used by the initial-exec TLS model, produces a LD instruction ...
@ MFVSR
Direct move from a VSX register to a GPR.
@ TLS_DYNAMIC_MAT_PCREL_ADDR
TLS_DYNAMIC_MAT_PCREL_ADDR = Materialize a PC Relative address for TLS global address when using dyna...
@ Hi
Hi/Lo - These represent the high and low 16-bit parts of a global address respectively.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
SDValue get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG)
get_VSPLTI_elt - If this is a build_vector of constants which can be formed by using a vspltis[bhw] i...
bool isXXBRDShuffleMask(ShuffleVectorSDNode *N)
isXXBRDShuffleMask - Return true if this is a shuffle mask suitable for a XXBRD instruction.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo)
bool isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for a VRGH* instruction with the ...
bool isVPKUDUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUDUMShuffleMask - Return true if this is the shuffle mask for a VPKUDUM instruction.
bool isVMRGEOShuffleMask(ShuffleVectorSDNode *N, bool CheckEven, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGEOShuffleMask - Return true if this is a shuffle mask suitable for a VMRGEW or VMRGOW instructi...
bool isXXBRQShuffleMask(ShuffleVectorSDNode *N)
isXXBRQShuffleMask - Return true if this is a shuffle mask suitable for a XXBRQ instruction.
bool isXXBRWShuffleMask(ShuffleVectorSDNode *N)
isXXBRWShuffleMask - Return true if this is a shuffle mask suitable for a XXBRW instruction.
bool isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXPERMDIShuffleMask - Return true if this is a shuffle mask suitable for a XXPERMDI instruction.
bool isXXBRHShuffleMask(ShuffleVectorSDNode *N)
isXXBRHShuffleMask - Return true if this is a shuffle mask suitable for a XXBRH instruction.
unsigned getSplatIdxForPPCMnemonics(SDNode *N, unsigned EltSize, SelectionDAG &DAG)
getSplatIdxForPPCMnemonics - Return the splat index as a value that is appropriate for PPC mnemonics ...
bool isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXSLDWIShuffleMask - Return true if this is a shuffle mask suitable for a XXSLDWI instruction.
int isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift amount, otherwise return -1.
bool isVMRGLShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for a VRGL* instruction with the ...
bool isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, unsigned &InsertAtByte, bool &Swap, bool IsLE)
isXXINSERTWMask - Return true if this VECTOR_SHUFFLE can be handled by the XXINSERTW instruction intr...
bool isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize)
isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand specifies a splat of a singl...
bool isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a VPKUWUM instruction.
bool isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a VPKUHUM instruction.
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit.
@ Define
Register definition.
Reg
All possible values of the reg field in the ModR/M byte.
@ XTY_ER
External reference.
initializer< Ty > init(const Ty &Val)
const_iterator end(StringRef path)
Get end iterator over path.
This is an optimization pass for GlobalISel generic memory operations.
static bool isIndirectCall(const MachineInstr &MI)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool checkConvertToNonDenormSingle(APFloat &ArgAPFloat)
void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
bool CC_PPC32_SVR4_ByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
bool isIntS16Immediate(SDNode *N, int16_t &Imm)
isIntS16Immediate - This method tests to see if the node is either a 32-bit or 64-bit immediate,...
bool CC_PPC32_SVR4_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
static bool isRunOfOnes64(uint64_t Val, unsigned &MB, unsigned &ME)
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
unsigned M1(unsigned Val)
bool isReleaseOrStronger(AtomicOrdering AO)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
bool RetCC_PPC_Cold(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
bool convertToNonDenormSingle(APInt &ArgAPInt)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
bool CC_PPC32_SVR4(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
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)
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.
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
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.
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)