71#include "llvm/IR/IntrinsicsPowerPC.h"
106#define DEBUG_TYPE "ppc-lowering"
109 "disable-p10-store-forward",
133 cl::desc(
"disable vector permute decomposition"),
137 "disable-auto-paired-vec-st",
138 cl::desc(
"disable automatically generated 32byte paired vector stores"),
143 cl::desc(
"Set minimum number of entries to use a jump table on PPC"));
147 cl::desc(
"max depth when checking alias info in GatherAllAliases()"));
151 cl::desc(
"Set inclusive limit count of TLS local-dynamic access(es) in a "
152 "function to use initial-exec"));
157 "Number of shuffles lowered to a VPERM or XXPERM");
158STATISTIC(NumDynamicAllocaProbed,
"Number of dynamic stack allocation probed");
181 initializeAddrModeMap();
184 bool isPPC64 = Subtarget.
isPPC64();
193 if (!Subtarget.hasEFPU2())
218 if (Subtarget.isISA3_0()) {
248 if (!Subtarget.hasSPE()) {
256 const MVT ScalarIntVTs[] = { MVT::i32, MVT::i64 };
257 for (
MVT VT : ScalarIntVTs) {
264 if (Subtarget.useCRBits()) {
267 if (isPPC64 || Subtarget.hasFPCVT()) {
270 isPPC64 ? MVT::i64 : MVT::i32);
273 isPPC64 ? MVT::i64 : MVT::i32);
277 isPPC64 ? MVT::i64 : MVT::i32);
280 isPPC64 ? MVT::i64 : MVT::i32);
284 isPPC64 ? MVT::i64 : MVT::i32);
287 isPPC64 ? MVT::i64 : MVT::i32);
291 isPPC64 ? MVT::i64 : MVT::i32);
294 isPPC64 ? MVT::i64 : MVT::i32);
341 if (Subtarget.isISA3_0()) {
376 if (!Subtarget.hasSPE()) {
381 if (Subtarget.hasVSX()) {
386 if (Subtarget.hasFSQRT()) {
391 if (Subtarget.hasFPRND()) {
432 if (Subtarget.hasSPE()) {
440 if (Subtarget.hasSPE())
446 if (!Subtarget.hasFSQRT() &&
447 !(TM.Options.UnsafeFPMath && Subtarget.hasFRSQRTE() &&
451 if (!Subtarget.hasFSQRT() &&
452 !(TM.Options.UnsafeFPMath && Subtarget.hasFRSQRTES() &&
453 Subtarget.hasFRES()))
456 if (Subtarget.hasFCPSGN()) {
464 if (Subtarget.hasFPRND()) {
478 if (Subtarget.isISA3_1()) {
489 if (Subtarget.isISA3_0()) {
509 if (!Subtarget.useCRBits()) {
522 if (!Subtarget.useCRBits())
525 if (Subtarget.hasFPU()) {
536 if (!Subtarget.useCRBits())
541 if (Subtarget.hasSPE()) {
565 if (Subtarget.hasDirectMove() && isPPC64) {
570 if (TM.Options.UnsafeFPMath) {
673 if (Subtarget.hasSPE()) {
695 if (Subtarget.has64BitSupport()) {
710 if (Subtarget.hasLFIWAX() || Subtarget.
isPPC64()) {
716 if (Subtarget.hasSPE()) {
726 if (Subtarget.hasFPCVT()) {
727 if (Subtarget.has64BitSupport()) {
748 if (Subtarget.use64BitRegs()) {
766 if (Subtarget.has64BitSupport()) {
773 if (Subtarget.hasVSX()) {
780 if (Subtarget.hasAltivec()) {
781 for (
MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
796 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
809 if (Subtarget.hasVSX()) {
815 if (Subtarget.hasP8Altivec() && (VT.SimpleTy != MVT::v1i128)) {
825 if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
899 if (!Subtarget.hasP8Vector()) {
941 if (Subtarget.hasAltivec())
942 for (
auto VT : {MVT::v4i32, MVT::v8i16, MVT::v16i8})
945 if (Subtarget.hasP8Altivec())
956 if (Subtarget.hasVSX()) {
962 if (Subtarget.hasP8Altivec())
967 if (Subtarget.isISA3_1()) {
1013 if (Subtarget.hasVSX()) {
1016 if (Subtarget.hasP8Vector()) {
1020 if (Subtarget.hasDirectMove() && isPPC64) {
1034 if (TM.Options.UnsafeFPMath) {
1071 if (Subtarget.hasP8Vector())
1080 if (Subtarget.hasP8Altivec()) {
1107 if (Subtarget.isISA3_1())
1210 if (Subtarget.hasP8Altivec()) {
1215 if (Subtarget.hasP9Vector()) {
1220 if (Subtarget.useCRBits()) {
1279 }
else if (Subtarget.hasVSX()) {
1304 for (
MVT VT : {MVT::f32, MVT::f64}) {
1323 if (Subtarget.hasP9Altivec()) {
1324 if (Subtarget.isISA3_1()) {
1347 if (Subtarget.hasP10Vector()) {
1352 if (Subtarget.pairedVectorMemops()) {
1357 if (Subtarget.hasMMA()) {
1358 if (Subtarget.isISAFuture())
1367 if (Subtarget.has64BitSupport())
1370 if (Subtarget.isISA3_1())
1388 if (Subtarget.hasAltivec()) {
1405 if (Subtarget.hasFPCVT())
1408 if (Subtarget.useCRBits())
1417 if (Subtarget.useCRBits()) {
1448 setLibcallName(RTLIB::MEMCPY, isPPC64 ?
"___memmove64" :
"___memmove");
1449 setLibcallName(RTLIB::MEMMOVE, isPPC64 ?
"___memmove64" :
"___memmove");
1450 setLibcallName(RTLIB::MEMSET, isPPC64 ?
"___memset64" :
"___memset");
1451 setLibcallName(RTLIB::BZERO, isPPC64 ?
"___bzero64" :
"___bzero");
1456 if (Subtarget.useCRBits()) {
1562void PPCTargetLowering::initializeAddrModeMap() {
1613 if (MaxAlign == MaxMaxAlign)
1615 if (
VectorType *VTy = dyn_cast<VectorType>(Ty)) {
1616 if (MaxMaxAlign >= 32 &&
1617 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1618 MaxAlign =
Align(32);
1619 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1621 MaxAlign =
Align(16);
1622 }
else if (
ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
1625 if (EltAlign > MaxAlign)
1626 MaxAlign = EltAlign;
1627 }
else if (
StructType *STy = dyn_cast<StructType>(Ty)) {
1628 for (
auto *EltTy : STy->elements()) {
1631 if (EltAlign > MaxAlign)
1632 MaxAlign = EltAlign;
1633 if (MaxAlign == MaxMaxAlign)
1646 if (Subtarget.hasAltivec())
1648 return Alignment.
value();
1656 return Subtarget.hasSPE();
1664 Type *VectorTy,
unsigned ElemSizeInBits,
unsigned &
Index)
const {
1665 if (!Subtarget.
isPPC64() || !Subtarget.hasVSX())
1668 if (
auto *VTy = dyn_cast<VectorType>(VectorTy)) {
1669 if (VTy->getScalarType()->isIntegerTy()) {
1671 if (ElemSizeInBits == 32) {
1675 if (ElemSizeInBits == 64) {
1701 return "PPCISD::FTSQRT";
1703 return "PPCISD::FSQRT";
1708 return "PPCISD::XXSPLTI_SP_TO_DP";
1710 return "PPCISD::XXSPLTI32DX";
1714 return "PPCISD::XXPERM";
1734 return "PPCISD::CALL_RM";
1736 return "PPCISD::CALL_NOP_RM";
1738 return "PPCISD::CALL_NOTOC_RM";
1743 return "PPCISD::BCTRL_RM";
1745 return "PPCISD::BCTRL_LOAD_TOC_RM";
1757 return "PPCISD::SCALAR_TO_VECTOR_PERMUTED";
1759 return "PPCISD::ANDI_rec_1_EQ_BIT";
1761 return "PPCISD::ANDI_rec_1_GT_BIT";
1776 return "PPCISD::ST_VSR_SCAL_INT";
1805 return "PPCISD::PADDI_DTPREL";
1821 return "PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR";
1823 return "PPCISD::TLS_LOCAL_EXEC_MAT_ADDR";
1833 return "PPCISD::STRICT_FADDRTZ";
1835 return "PPCISD::STRICT_FCTIDZ";
1837 return "PPCISD::STRICT_FCTIWZ";
1839 return "PPCISD::STRICT_FCTIDUZ";
1841 return "PPCISD::STRICT_FCTIWUZ";
1843 return "PPCISD::STRICT_FCFID";
1845 return "PPCISD::STRICT_FCFIDU";
1847 return "PPCISD::STRICT_FCFIDS";
1849 return "PPCISD::STRICT_FCFIDUS";
1852 return "PPCISD::STORE_COND";
1860 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1877 return CFP->getValueAPF().isZero();
1881 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
1882 return CFP->getValueAPF().isZero();
1890 return Op < 0 ||
Op == Val;
1902 if (ShuffleKind == 0) {
1905 for (
unsigned i = 0; i != 16; ++i)
1908 }
else if (ShuffleKind == 2) {
1911 for (
unsigned i = 0; i != 16; ++i)
1914 }
else if (ShuffleKind == 1) {
1915 unsigned j = IsLE ? 0 : 1;
1916 for (
unsigned i = 0; i != 8; ++i)
1933 if (ShuffleKind == 0) {
1936 for (
unsigned i = 0; i != 16; i += 2)
1940 }
else if (ShuffleKind == 2) {
1943 for (
unsigned i = 0; i != 16; i += 2)
1947 }
else if (ShuffleKind == 1) {
1948 unsigned j = IsLE ? 0 : 2;
1949 for (
unsigned i = 0; i != 8; i += 2)
1970 if (!Subtarget.hasP8Vector())
1974 if (ShuffleKind == 0) {
1977 for (
unsigned i = 0; i != 16; i += 4)
1983 }
else if (ShuffleKind == 2) {
1986 for (
unsigned i = 0; i != 16; i += 4)
1992 }
else if (ShuffleKind == 1) {
1993 unsigned j = IsLE ? 0 : 4;
1994 for (
unsigned i = 0; i != 8; i += 4)
2011 unsigned LHSStart,
unsigned RHSStart) {
2012 if (
N->getValueType(0) != MVT::v16i8)
2014 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
2015 "Unsupported merge size!");
2017 for (
unsigned i = 0; i != 8/UnitSize; ++i)
2018 for (
unsigned j = 0; j != UnitSize; ++j) {
2020 LHSStart+j+i*UnitSize) ||
2022 RHSStart+j+i*UnitSize))
2037 if (ShuffleKind == 1)
2039 else if (ShuffleKind == 2)
2044 if (ShuffleKind == 1)
2046 else if (ShuffleKind == 0)
2062 if (ShuffleKind == 1)
2064 else if (ShuffleKind == 2)
2069 if (ShuffleKind == 1)
2071 else if (ShuffleKind == 0)
2121 unsigned RHSStartValue) {
2122 if (
N->getValueType(0) != MVT::v16i8)
2125 for (
unsigned i = 0; i < 2; ++i)
2126 for (
unsigned j = 0; j < 4; ++j)
2128 i*RHSStartValue+j+IndexOffset) ||
2130 i*RHSStartValue+j+IndexOffset+8))
2152 unsigned indexOffset = CheckEven ? 4 : 0;
2153 if (ShuffleKind == 1)
2155 else if (ShuffleKind == 2)
2161 unsigned indexOffset = CheckEven ? 0 : 4;
2162 if (ShuffleKind == 1)
2164 else if (ShuffleKind == 0)
2180 if (
N->getValueType(0) != MVT::v16i8)
2187 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2190 if (i == 16)
return -1;
2195 if (ShiftAmt < i)
return -1;
2200 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2202 for (++i; i != 16; ++i)
2205 }
else if (ShuffleKind == 1) {
2207 for (++i; i != 16; ++i)
2214 ShiftAmt = 16 - ShiftAmt;
2223 EVT VT =
N->getValueType(0);
2224 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2225 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2228 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2232 if (
N->getMaskElt(0) % EltSize != 0)
2237 unsigned ElementBase =
N->getMaskElt(0);
2240 if (ElementBase >= 16)
2245 for (
unsigned i = 1; i != EltSize; ++i)
2246 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2249 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2250 if (
N->getMaskElt(i) < 0)
continue;
2251 for (
unsigned j = 0; j != EltSize; ++j)
2252 if (
N->getMaskElt(i+j) !=
N->getMaskElt(j))
2269 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2270 "Unexpected element width.");
2271 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2273 unsigned NumOfElem = 16 / Width;
2274 unsigned MaskVal[16];
2275 for (
unsigned i = 0; i < NumOfElem; ++i) {
2276 MaskVal[0] =
N->getMaskElt(i * Width);
2277 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2279 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2283 for (
unsigned int j = 1; j < Width; ++j) {
2284 MaskVal[j] =
N->getMaskElt(i * Width + j);
2285 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2295 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2300 unsigned M0 =
N->getMaskElt(0) / 4;
2301 unsigned M1 =
N->getMaskElt(4) / 4;
2302 unsigned M2 =
N->getMaskElt(8) / 4;
2303 unsigned M3 =
N->getMaskElt(12) / 4;
2304 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2305 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2310 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2311 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2312 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2313 InsertAtByte = IsLE ? 12 : 0;
2318 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2319 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2320 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2321 InsertAtByte = IsLE ? 8 : 4;
2326 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2327 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2328 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2329 InsertAtByte = IsLE ? 4 : 8;
2334 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2335 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2336 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2337 InsertAtByte = IsLE ? 0 : 12;
2344 if (
N->getOperand(1).isUndef()) {
2347 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2348 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2349 InsertAtByte = IsLE ? 12 : 0;
2352 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2353 InsertAtByte = IsLE ? 8 : 4;
2356 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2357 InsertAtByte = IsLE ? 4 : 8;
2360 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2361 InsertAtByte = IsLE ? 0 : 12;
2370 bool &Swap,
bool IsLE) {
2371 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2377 unsigned M0 =
N->getMaskElt(0) / 4;
2378 unsigned M1 =
N->getMaskElt(4) / 4;
2379 unsigned M2 =
N->getMaskElt(8) / 4;
2380 unsigned M3 =
N->getMaskElt(12) / 4;
2384 if (
N->getOperand(1).isUndef()) {
2385 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2386 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2389 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2395 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2399 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2404 ShiftElts = (8 -
M0) % 8;
2405 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2410 ShiftElts = (4 -
M0) % 4;
2415 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2420 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2432 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2437 for (
int i = 0; i < 16; i += Width)
2438 if (
N->getMaskElt(i) != i + Width - 1)
2469 bool &Swap,
bool IsLE) {
2470 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2476 unsigned M0 =
N->getMaskElt(0) / 8;
2477 unsigned M1 =
N->getMaskElt(8) / 8;
2478 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2482 if (
N->getOperand(1).isUndef()) {
2483 if ((
M0 |
M1) < 2) {
2484 DM = IsLE ? (((~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2492 if (
M0 > 1 &&
M1 < 2) {
2494 }
else if (M0 < 2 && M1 > 1) {
2502 DM = (((~M1) & 1) << 1) + ((~
M0) & 1);
2505 if (M0 < 2 && M1 > 1) {
2507 }
else if (
M0 > 1 &&
M1 < 2) {
2515 DM = (
M0 << 1) + (
M1 & 1);
2530 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2535 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2551 unsigned EltSize = 16/
N->getNumOperands();
2552 if (EltSize < ByteSize) {
2553 unsigned Multiple = ByteSize/EltSize;
2555 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2558 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2559 if (
N->getOperand(i).isUndef())
continue;
2561 if (!isa<ConstantSDNode>(
N->getOperand(i)))
return SDValue();
2563 if (!UniquedVals[i&(Multiple-1)].
getNode())
2564 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2565 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2575 bool LeadingZero =
true;
2576 bool LeadingOnes =
true;
2577 for (
unsigned i = 0; i != Multiple-1; ++i) {
2578 if (!UniquedVals[i].
getNode())
continue;
2585 if (!UniquedVals[Multiple-1].
getNode())
2592 if (!UniquedVals[Multiple-1].
getNode())
2594 int Val =cast<ConstantSDNode>(UniquedVals[Multiple-1])->getSExtValue();
2603 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2604 if (
N->getOperand(i).isUndef())
continue;
2606 OpVal =
N->getOperand(i);
2607 else if (OpVal !=
N->getOperand(i))
2613 unsigned ValSizeInBytes = EltSize;
2616 Value = CN->getZExtValue();
2618 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2619 Value = llvm::bit_cast<uint32_t>(CN->getValueAPF().convertToFloat());
2625 if (ValSizeInBytes < ByteSize)
return SDValue();
2636 if (MaskVal == 0)
return SDValue();
2639 if (SignExtend32<5>(MaskVal) == MaskVal)
2653 if (!isa<ConstantSDNode>(
N))
2656 Imm = (int16_t)
N->getAsZExtVal();
2657 if (
N->getValueType(0) == MVT::i32)
2658 return Imm == (int32_t)
N->getAsZExtVal();
2660 return Imm == (int64_t)
N->getAsZExtVal();
2678 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2687 if (
MemSDNode *Memop = dyn_cast<MemSDNode>(U)) {
2688 if (Memop->getMemoryVT() == MVT::f64) {
2689 Base =
N.getOperand(0);
2702 if (!isa<ConstantSDNode>(
N))
2705 Imm = (int64_t)
N->getAsZExtVal();
2706 return isInt<34>(Imm);
2733 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2738 Base =
N.getOperand(0);
2741 }
else if (
N.getOpcode() ==
ISD::OR) {
2743 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2755 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2756 Base =
N.getOperand(0);
2827 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2833 Base =
N.getOperand(0);
2836 }
else if (
N.getOperand(1).getOpcode() ==
PPCISD::Lo) {
2838 assert(!
N.getOperand(1).getConstantOperandVal(1) &&
2839 "Cannot handle constant offsets yet!");
2840 Disp =
N.getOperand(1).getOperand(0);
2845 Base =
N.getOperand(0);
2848 }
else if (
N.getOpcode() ==
ISD::OR) {
2851 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2861 dyn_cast<FrameIndexSDNode>(
N.getOperand(0))) {
2865 Base =
N.getOperand(0);
2878 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm))) {
2881 CN->getValueType(0));
2886 if ((CN->getValueType(0) == MVT::i32 ||
2887 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2888 (!EncodingAlignment ||
2889 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2890 int Addr = (int)CN->getZExtValue();
2897 unsigned Opc = CN->
getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2918 if (
N.getValueType() != MVT::i64)
2931 Base =
N.getOperand(0);
2947 Base =
N.getOperand(0);
2980 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2981 Base =
N.getOperand(0);
2994 Ty *PCRelCand = dyn_cast<Ty>(
N);
3006 if (isValidPCRelNode<ConstantPoolSDNode>(
N) ||
3007 isValidPCRelNode<GlobalAddressSDNode>(
N) ||
3008 isValidPCRelNode<JumpTableSDNode>(
N) ||
3009 isValidPCRelNode<BlockAddressSDNode>(
N))
3025 EVT MemVT = LD->getMemoryVT();
3032 if (!ST.hasP8Vector())
3037 if (!ST.hasP9Vector())
3050 if (UI.getUse().get().getResNo() == 0 &&
3072 Ptr = LD->getBasePtr();
3073 VT = LD->getMemoryVT();
3074 Alignment = LD->getAlign();
3075 }
else if (
StoreSDNode *ST = dyn_cast<StoreSDNode>(
N)) {
3076 Ptr = ST->getBasePtr();
3077 VT = ST->getMemoryVT();
3078 Alignment = ST->getAlign();
3101 if (isa<FrameIndexSDNode>(
Base) || isa<RegisterSDNode>(
Base))
3104 SDValue Val = cast<StoreSDNode>(
N)->getValue();
3117 if (VT != MVT::i64) {
3122 if (Alignment <
Align(4))
3132 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
3134 isa<ConstantSDNode>(
Offset))
3149 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3191 const bool Is64Bit = Subtarget.
isPPC64();
3192 EVT VT = Is64Bit ? MVT::i64 : MVT::i32;
3206 EVT PtrVT =
Op.getValueType();
3222 return getTOCEntry(DAG,
SDLoc(CP), GA);
3225 unsigned MOHiFlag, MOLoFlag;
3232 return getTOCEntry(DAG,
SDLoc(CP), GA);
3292 EVT PtrVT =
Op.getValueType();
3310 return getTOCEntry(DAG,
SDLoc(JT), GA);
3313 unsigned MOHiFlag, MOLoFlag;
3320 return getTOCEntry(DAG,
SDLoc(GA), GA);
3330 EVT PtrVT =
Op.getValueType();
3349 return getTOCEntry(DAG,
SDLoc(BASDN), GA);
3358 unsigned MOHiFlag, MOLoFlag;
3369 return LowerGlobalTLSAddressAIX(
Op, DAG);
3371 return LowerGlobalTLSAddressLinux(
Op, DAG);
3393 if (
I.getOpcode() == Instruction::Call)
3394 if (
const CallInst *CI = dyn_cast<const CallInst>(&
I))
3395 if (
Function *CF = CI->getCalledFunction())
3396 if (CF->isDeclaration() &&
3397 CF->getIntrinsicID() == Intrinsic::threadlocal_address)
3399 dyn_cast<GlobalValue>(
I.getOperand(0))) {
3405 unsigned TLSGVCnt = TLSGV.
size();
3415 <<
" function is using the TLS-IE model for TLS-LD access.\n");
3430 bool Is64Bit = Subtarget.
isPPC64();
3434 if (Subtarget.hasAIXShLibTLSModelOpt())
3440 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3441 bool HasAIXSmallTLSGlobalAttr =
false;
3444 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3448 if (GVar->hasAttribute(
"aix-small-tls"))
3449 HasAIXSmallTLSGlobalAttr =
true;
3468 if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) &&
3469 IsTLSLocalExecModel) {
3489 if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr)
3491 "currently only supported on AIX (64-bit mode).");
3497 bool HasAIXSmallLocalDynamicTLS = Subtarget.hasAIXSmallLocalDynamicTLS();
3501 if (!Is64Bit && HasAIXSmallLocalDynamicTLS)
3503 "currently only supported on AIX (64-bit mode).");
3511 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3515 dyn_cast_or_null<GlobalVariable>(
M->getOrInsertGlobal(
3518 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3521 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3532 if (HasAIXSmallLocalDynamicTLS) {
3541 return DAG.
getNode(
ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
3554 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3555 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3573 bool is64bit = Subtarget.
isPPC64();
3620 if (!
TM.isPositionIndependent())
3679 PtrVT, GOTPtr, TGA, TGA);
3681 PtrVT, TLSAddr, TGA);
3690 EVT PtrVT =
Op.getValueType();
3715 return getTOCEntry(DAG,
DL, GA);
3718 unsigned MOHiFlag, MOLoFlag;
3726 return getTOCEntry(DAG,
DL, GA);
3738 bool IsStrict =
Op->isStrictFPOpcode();
3740 cast<CondCodeSDNode>(
Op.getOperand(IsStrict ? 3 : 2))->get();
3744 EVT LHSVT =
LHS.getValueType();
3748 if (LHSVT == MVT::f128) {
3749 assert(!Subtarget.hasP9Vector() &&
3750 "SETCC for f128 is already legal under Power9!");
3761 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3763 if (
Op.getValueType() == MVT::v2i64) {
3766 if (
LHS.getValueType() == MVT::v2i64) {
3774 int ShuffV[] = {1, 0, 3, 2};
3779 dl, MVT::v4i32, Shuff, SetCC32));
3796 if (
C->isAllOnes() ||
C->isZero())
3806 EVT VT =
Op.getValueType();
3815 EVT VT =
Node->getValueType(0);
3819 const Value *SV = cast<SrcValueSDNode>(
Node->getOperand(2))->getValue();
3829 if (VT == MVT::i64) {
3860 InChain = OverflowArea.
getValue(1);
3906 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3913 assert(!Subtarget.
isPPC64() &&
"LowerVACOPY is PPC32 only");
3919 false,
true,
nullptr, std::nullopt,
3928 return Op.getOperand(0);
3937 "Expecting Inline ASM node.");
3947 if (
Op.getOperand(NumOps - 1).getValueType() == MVT::Glue)
3953 unsigned NumVals =
Flags.getNumOperandRegisters();
3956 switch (
Flags.getKind()) {
3967 for (; NumVals; --NumVals, ++i) {
3968 Register Reg = cast<RegisterSDNode>(
Op.getOperand(i))->getReg();
3969 if (Reg != PPC::LR && Reg != PPC::LR8)
3994 bool isPPC64 = (PtrVT == MVT::i64);
4000 Entry.Ty = IntPtrTy;
4001 Entry.Node = Trmp;
Args.push_back(Entry);
4005 isPPC64 ? MVT::i64 : MVT::i32);
4006 Args.push_back(Entry);
4008 Entry.Node = FPtr;
Args.push_back(Entry);
4009 Entry.Node = Nest;
Args.push_back(Entry);
4013 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
4017 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
4018 return CallResult.second;
4032 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
4033 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
4068 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
4077 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
4092 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
4095 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
4097 nextOffset += FrameOffset;
4098 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
4101 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
4107static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
4108 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
4109 PPC::F11, PPC::F12, PPC::F13};
4114 unsigned PtrByteSize) {
4116 if (Flags.isByVal())
4117 ArgSize = Flags.getByValSize();
4121 if (!Flags.isInConsecutiveRegs())
4122 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4131 unsigned PtrByteSize) {
4132 Align Alignment(PtrByteSize);
4135 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4136 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4137 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4138 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4139 Alignment =
Align(16);
4142 if (Flags.isByVal()) {
4143 auto BVAlign = Flags.getNonZeroByValAlign();
4144 if (BVAlign > PtrByteSize) {
4145 if (BVAlign.value() % PtrByteSize != 0)
4147 "ByVal alignment is not a multiple of the pointer size");
4149 Alignment = BVAlign;
4154 if (Flags.isInConsecutiveRegs()) {
4158 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4172 unsigned PtrByteSize,
unsigned LinkageSize,
4173 unsigned ParamAreaSize,
unsigned &ArgOffset,
4174 unsigned &AvailableFPRs,
4175 unsigned &AvailableVRs) {
4176 bool UseMemory =
false;
4181 ArgOffset =
alignTo(ArgOffset, Alignment);
4184 if (ArgOffset >= LinkageSize + ParamAreaSize)
4189 if (Flags.isInConsecutiveRegsLast())
4190 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4193 if (ArgOffset > LinkageSize + ParamAreaSize)
4198 if (!Flags.isByVal()) {
4199 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4200 if (AvailableFPRs > 0) {
4204 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4205 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4206 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4207 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4208 if (AvailableVRs > 0) {
4220 unsigned NumBytes) {
4224SDValue PPCTargetLowering::LowerFormalArguments(
4229 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4232 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4235 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4239SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4281 const Align PtrAlign(4);
4290 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4292 CCInfo.PreAnalyzeFormalArguments(Ins);
4295 CCInfo.clearWasPPCF128();
4297 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4310 RC = &PPC::GPRCRegClass;
4313 if (Subtarget.hasP8Vector())
4314 RC = &PPC::VSSRCRegClass;
4315 else if (Subtarget.hasSPE())
4316 RC = &PPC::GPRCRegClass;
4318 RC = &PPC::F4RCRegClass;
4321 if (Subtarget.hasVSX())
4322 RC = &PPC::VSFRCRegClass;
4323 else if (Subtarget.hasSPE())
4325 RC = &PPC::GPRCRegClass;
4327 RC = &PPC::F8RCRegClass;
4332 RC = &PPC::VRRCRegClass;
4335 RC = &PPC::VRRCRegClass;
4339 RC = &PPC::VRRCRegClass;
4346 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4347 assert(i + 1 < e &&
"No second half of double precision argument");
4359 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4360 if (ValVT == MVT::i1)
4375 ArgOffset += ArgSize - ObjSize;
4393 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4398 unsigned MinReservedArea = CCByValInfo.getStackSize();
4399 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4415 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4416 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4418 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4421 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4424 unsigned NumFPArgRegs = std::size(FPArgRegs);
4433 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4437 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4446 for (
unsigned GPRIndex = 0; GPRIndex != NumGPArgRegs; ++GPRIndex) {
4450 VReg = MF.
addLiveIn(GPArgRegs[GPRIndex], &PPC::GPRCRegClass);
4465 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4469 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4482 if (!MemOps.
empty())
4493 const SDLoc &dl)
const {
4497 else if (
Flags.isZExt())
4504SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4517 "fastcc not supported on varargs functions");
4523 unsigned PtrByteSize = 8;
4527 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4528 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4531 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4532 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4535 const unsigned Num_GPR_Regs = std::size(GPR);
4537 const unsigned Num_VR_Regs = std::size(VR);
4545 bool HasParameterArea = !isELFv2ABI || isVarArg;
4546 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4547 unsigned NumBytes = LinkageSize;
4548 unsigned AvailableFPRs = Num_FPR_Regs;
4549 unsigned AvailableVRs = Num_VR_Regs;
4550 for (
unsigned i = 0, e =
Ins.size(); i != e; ++i) {
4551 if (Ins[i].
Flags.isNest())
4555 PtrByteSize, LinkageSize, ParamAreaSize,
4556 NumBytes, AvailableFPRs, AvailableVRs))
4557 HasParameterArea =
true;
4564 unsigned ArgOffset = LinkageSize;
4565 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4568 unsigned CurArgIdx = 0;
4569 for (
unsigned ArgNo = 0, e =
Ins.size(); ArgNo != e; ++ArgNo) {
4571 bool needsLoad =
false;
4572 EVT ObjectVT =
Ins[ArgNo].VT;
4573 EVT OrigVT =
Ins[ArgNo].ArgVT;
4575 unsigned ArgSize = ObjSize;
4577 if (Ins[ArgNo].isOrigArg()) {
4578 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4579 CurArgIdx =
Ins[ArgNo].getOrigArgIndex();
4584 unsigned CurArgOffset;
4586 auto ComputeArgOffset = [&]() {
4590 ArgOffset =
alignTo(ArgOffset, Alignment);
4591 CurArgOffset = ArgOffset;
4598 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4599 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4604 if (
Flags.isByVal()) {
4605 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4611 ObjSize =
Flags.getByValSize();
4612 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4634 if (HasParameterArea ||
4635 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4642 if (ObjSize < PtrByteSize) {
4646 if (!isLittleEndian) {
4652 if (GPR_idx != Num_GPR_Regs) {
4664 ArgOffset += PtrByteSize;
4673 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4674 if (GPR_idx == Num_GPR_Regs)
4685 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4693 ArgOffset += ArgSize;
4702 if (
Flags.isNest()) {
4707 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4708 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4716 if (GPR_idx != Num_GPR_Regs) {
4721 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4724 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4730 ArgSize = PtrByteSize;
4741 if (FPR_idx != Num_FPR_Regs) {
4744 if (ObjectVT == MVT::f32)
4746 Subtarget.hasP8Vector()
4747 ? &PPC::VSSRCRegClass
4748 : &PPC::F4RCRegClass);
4751 ? &PPC::VSFRCRegClass
4752 : &PPC::F8RCRegClass);
4767 if (ObjectVT == MVT::f32) {
4768 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4786 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4787 ArgOffset += ArgSize;
4788 if (
Flags.isInConsecutiveRegsLast())
4789 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4803 if (VR_idx != Num_VR_Regs) {
4820 if (ObjSize < ArgSize && !isLittleEndian)
4821 CurArgOffset += ArgSize - ObjSize;
4831 unsigned MinReservedArea;
4832 if (HasParameterArea)
4833 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4835 MinReservedArea = LinkageSize;
4852 int Depth = ArgOffset;
4861 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4862 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4874 if (!MemOps.
empty())
4883 unsigned ParamSize) {
4885 if (!isTailCall)
return 0;
4889 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4891 if (SPDiff < FI->getTailCallSPDelta())
4907 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4920 if (!TM.shouldAssumeDSOLocal(CalleeGV))
4926 const Function *
F = dyn_cast<Function>(CalleeGV);
4927 const GlobalAlias *Alias = dyn_cast<GlobalAlias>(CalleeGV);
4932 F = dyn_cast<Function>(GlobalObj);
4965 if (TM.getFunctionSections() || CalleeGV->
hasComdat() ||
4966 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
4968 if (
const auto *
F = dyn_cast<Function>(CalleeGV)) {
4969 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4981 const unsigned PtrByteSize = 8;
4985 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4986 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4989 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4990 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4993 const unsigned NumGPRs = std::size(GPR);
4994 const unsigned NumFPRs = 13;
4995 const unsigned NumVRs = std::size(VR);
4996 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4998 unsigned NumBytes = LinkageSize;
4999 unsigned AvailableFPRs = NumFPRs;
5000 unsigned AvailableVRs = NumVRs;
5003 if (Param.Flags.isNest())
continue;
5006 LinkageSize, ParamAreaSize, NumBytes,
5007 AvailableFPRs, AvailableVRs))
5018 auto CalleeArgEnd = CB.
arg_end();
5021 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
5022 const Value* CalleeArg = *CalleeArgIter;
5023 const Value* CallerArg = &(*CallerArgIter);
5024 if (CalleeArg == CallerArg)
5032 isa<UndefValue>(CalleeArg))
5050 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
5060bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
5065 bool isCalleeExternalSymbol)
const {
5068 if (
DisableSCO && !TailCallOpt)
return false;
5071 if (isVarArg)
return false;
5147bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5181 if (!
C)
return nullptr;
5183 int Addr =
C->getZExtValue();
5184 if ((
Addr & 3) != 0 ||
5190 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5197struct TailCallArgumentInfo {
5202 TailCallArgumentInfo() =
default;
5212 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5213 SDValue Arg = TailCallArgs[i].Arg;
5214 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5215 int FI = TailCallArgs[i].FrameIdx;
5218 Chain, dl, Arg, FIN,
5227 int SPDiff,
const SDLoc &dl) {
5233 bool isPPC64 = Subtarget.
isPPC64();
5234 int SlotSize = isPPC64 ? 8 : 4;
5235 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5237 NewRetAddrLoc,
true);
5238 EVT VT = isPPC64 ? MVT::i64 : MVT::i32;
5240 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5250 SDValue Arg,
int SPDiff,
unsigned ArgOffset,
5252 int Offset = ArgOffset + SPDiff;
5255 EVT VT = isPPC64 ? MVT::i64 : MVT::i32;
5257 TailCallArgumentInfo
Info;
5259 Info.FrameIdxOp = FIN;
5267SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5272 EVT VT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
5273 LROpOut = getReturnAddrFrameIndex(DAG);
5291 Chain, dl, Dst, Src, SizeNode, Flags.getNonZeroByValAlign(),
false,
false,
5299 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5322 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5332 if (!MemOpChains2.
empty())
5356SDValue PPCTargetLowering::LowerCallResult(
5364 CCRetInfo.AnalyzeCallResult(
5370 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5376 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5379 Chain =
Lo.getValue(1);
5380 InGlue =
Lo.getValue(2);
5384 Chain =
Hi.getValue(1);
5385 InGlue =
Hi.getValue(2);
5422 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5454 bool IsStrictFPCall =
false) {
5458 unsigned RetOpc = 0;
5483 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5489 if (IsStrictFPCall) {
5520 auto isLocalCallee = [&]() {
5525 !isa_and_nonnull<GlobalIFunc>(GV);
5536 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5546 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5549 const GlobalValue *GV = cast<GlobalAddressSDNode>(Callee)->getGlobal();
5552 assert(!isa<GlobalIFunc>(GV) &&
"IFunc is not supported on AIX.");
5553 return getAIXFuncEntryPointSymbolSDNode(GV);
5560 const char *SymName = S->getSymbol();
5566 dyn_cast_or_null<Function>(
Mod->getNamedValue(SymName)))
5567 return getAIXFuncEntryPointSymbolSDNode(
F);
5573 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5581 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5588 assert(Callee.getNode() &&
"What no callee?");
5594 "Expected a CALLSEQ_STARTSDNode.");
5611 SDValue MTCTROps[] = {Chain, Callee, Glue};
5612 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5653 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5668 const MVT RegVT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
5672 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5673 Alignment, MMOFlags);
5680 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5687 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5699 "Nest parameter is not supported on AIX.");
5715 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5718 const bool IsPPC64 = Subtarget.
isPPC64();
5720 const MVT RegVT = IsPPC64 ? MVT::i64 : MVT::i32;
5767 for (
unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
5769 RegsToPass[i].second.getValueType()));
5786 assert(Mask &&
"Missing call preserved mask for calling convention");
5794SDValue PPCTargetLowering::FinishCall(
5809 if (!CFlags.IsIndirect)
5813 dl, CFlags.HasNest, Subtarget);
5823 if (CFlags.IsTailCall) {
5827 cast<RegisterSDNode>(Callee)->getReg() == PPC::CTR) ||
5830 isa<ConstantSDNode>(Callee) ||
5832 "Expecting a global address, external symbol, absolute value, "
5833 "register or an indirect tail call when PC Relative calls are "
5837 "Unexpected call opcode for a tail call.");
5844 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5845 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes, Ops);
5857 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5860 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5871 const GlobalValue *CalleeGV = dyn_cast<GlobalValue>(CalleeFunc);
5880 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5881 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5885bool PPCTargetLowering::isEligibleForTCO(
5890 bool isCalleeExternalSymbol)
const {
5895 return IsEligibleForTailCallOptimization_64SVR4(
5896 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5897 isCalleeExternalSymbol);
5899 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5922 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5924 bool IsCalleeExternalSymbol = isa<ExternalSymbolSDNode>(Callee);
5927 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5941 isa<GlobalAddressSDNode>(Callee)) &&
5942 "Callee should be an llvm::Function object.");
5945 <<
"\nTCO callee: ");
5952 "site marked musttail");
5957 if (Subtarget.useLongCalls() && isa<GlobalAddressSDNode>(Callee) &&
5959 Callee = LowerGlobalAddress(Callee, DAG);
5962 CallConv, isTailCall, isVarArg, isPatchPoint,
5970 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5975 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5977 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5981SDValue PPCTargetLowering::LowerCall_32SVR4(
5992 const bool IsVarArg = CFlags.IsVarArg;
5993 const bool IsTailCall = CFlags.IsTailCall;
5999 const Align PtrAlign(4);
6024 CCInfo.PreAnalyzeCallOperands(Outs);
6030 unsigned NumArgs = Outs.
size();
6032 for (
unsigned i = 0; i != NumArgs; ++i) {
6033 MVT ArgVT = Outs[i].VT;
6037 if (Outs[i].IsFixed) {
6047 errs() <<
"Call operand #" << i <<
" has unhandled type "
6057 CCInfo.clearWasPPCF128();
6064 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
6071 unsigned NumBytes = CCByValInfo.getStackSize();
6085 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6096 bool seenFloatArg =
false;
6101 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
6103 ++i, ++RealArgIdx) {
6105 SDValue Arg = OutVals[RealArgIdx];
6108 if (
Flags.isByVal()) {
6113 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
6136 Chain = CallSeqStart = NewCallSeqStart;
6155 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6162 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6186 if (!MemOpChains.
empty())
6192 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
6193 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
6194 RegsToPass[i].second, InGlue);
6202 SDValue Ops[] = { Chain, InGlue };
6214 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6215 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6220SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6232 return NewCallSeqStart;
6235SDValue PPCTargetLowering::LowerCall_64SVR4(
6244 unsigned NumOps = Outs.
size();
6245 bool IsSibCall =
false;
6249 unsigned PtrByteSize = 8;
6264 assert(!(IsFastCall && CFlags.IsVarArg) &&
6265 "fastcc not supported on varargs functions");
6272 unsigned NumBytes = LinkageSize;
6273 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6276 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6277 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6280 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6281 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6284 const unsigned NumGPRs = std::size(GPR);
6286 const unsigned NumVRs = std::size(VR);
6292 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6293 if (!HasParameterArea) {
6294 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6295 unsigned AvailableFPRs = NumFPRs;
6296 unsigned AvailableVRs = NumVRs;
6297 unsigned NumBytesTmp = NumBytes;
6298 for (
unsigned i = 0; i != NumOps; ++i) {
6299 if (Outs[i].
Flags.isNest())
continue;
6301 PtrByteSize, LinkageSize, ParamAreaSize,
6302 NumBytesTmp, AvailableFPRs, AvailableVRs))
6303 HasParameterArea =
true;
6309 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6314 HasParameterArea =
false;
6317 for (
unsigned i = 0; i != NumOps; ++i) {
6319 EVT ArgVT = Outs[i].VT;
6320 EVT OrigVT = Outs[i].ArgVT;
6326 if (
Flags.isByVal()) {
6327 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6328 if (NumGPRsUsed > NumGPRs)
6329 HasParameterArea =
true;
6336 if (++NumGPRsUsed <= NumGPRs)
6346 if (++NumVRsUsed <= NumVRs)
6350 if (++NumVRsUsed <= NumVRs)
6355 if (++NumFPRsUsed <= NumFPRs)
6359 HasParameterArea =
true;
6366 NumBytes =
alignTo(NumBytes, Alignement);
6369 if (
Flags.isInConsecutiveRegsLast())
6370 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6373 unsigned NumBytesActuallyUsed = NumBytes;
6383 if (HasParameterArea)
6384 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6386 NumBytes = LinkageSize;
6401 if (CFlags.IsTailCall)
6413 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6424 unsigned ArgOffset = LinkageSize;
6430 for (
unsigned i = 0; i != NumOps; ++i) {
6433 EVT ArgVT = Outs[i].VT;
6434 EVT OrigVT = Outs[i].ArgVT;
6443 auto ComputePtrOff = [&]() {
6447 ArgOffset =
alignTo(ArgOffset, Alignment);
6458 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6459 GPR_idx = std::min(GPR_idx, NumGPRs);
6466 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6472 if (
Flags.isByVal()) {
6490 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6491 if (GPR_idx != NumGPRs) {
6495 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6497 ArgOffset += PtrByteSize;
6502 if (GPR_idx == NumGPRs &&
Size < 8) {
6504 if (!isLittleEndian) {
6509 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6512 ArgOffset += PtrByteSize;
6521 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6522 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6527 if (
Size < 8 && GPR_idx != NumGPRs) {
6537 if (!isLittleEndian) {
6541 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6549 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6552 ArgOffset += PtrByteSize;
6558 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6561 if (GPR_idx != NumGPRs) {
6562 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6568 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6569 ArgOffset += PtrByteSize;
6571 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6583 if (
Flags.isNest()) {
6585 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6592 if (GPR_idx != NumGPRs) {
6593 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6598 assert(HasParameterArea &&
6599 "Parameter area must exist to pass an argument in memory.");
6601 true, CFlags.IsTailCall,
false, MemOpChains,
6602 TailCallArguments, dl);
6604 ArgOffset += PtrByteSize;
6607 ArgOffset += PtrByteSize;
6620 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6621 bool NeededLoad =
false;
6624 if (FPR_idx != NumFPRs)
6625 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6628 if (!NeedGPROrStack)
6630 else if (GPR_idx != NumGPRs && !IsFastCall) {
6644 }
else if (!
Flags.isInConsecutiveRegs()) {
6650 }
else if (ArgOffset % PtrByteSize != 0) {
6654 if (!isLittleEndian)
6659 }
else if (
Flags.isInConsecutiveRegsLast()) {
6662 if (!isLittleEndian)
6672 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6680 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6685 assert(HasParameterArea &&
6686 "Parameter area must exist to pass an argument in memory.");
6688 true, CFlags.IsTailCall,
false, MemOpChains,
6689 TailCallArguments, dl);
6696 if (!IsFastCall || NeededLoad) {
6698 Flags.isInConsecutiveRegs()) ? 4 : 8;
6699 if (
Flags.isInConsecutiveRegsLast())
6700 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6720 if (CFlags.IsVarArg) {
6721 assert(HasParameterArea &&
6722 "Parameter area must exist if we have a varargs call.");
6728 if (VR_idx != NumVRs) {
6732 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6735 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6736 if (GPR_idx == NumGPRs)
6743 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6749 if (VR_idx != NumVRs) {
6750 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6755 assert(HasParameterArea &&
6756 "Parameter area must exist to pass an argument in memory.");
6758 true, CFlags.IsTailCall,
true, MemOpChains,
6759 TailCallArguments, dl);
6770 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6771 "mismatch in size of parameter area");
6772 (void)NumBytesActuallyUsed;
6774 if (!MemOpChains.
empty())
6780 if (CFlags.IsIndirect) {
6784 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6799 if (isELFv2ABI && !CFlags.IsPatchPoint)
6800 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6806 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
6807 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
6808 RegsToPass[i].second, InGlue);
6812 if (CFlags.IsTailCall && !IsSibCall)
6816 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6817 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6824 "Required alignment greater than stack alignment.");
6844 return RequiredAlign <= 8;
6849 return RequiredAlign <= 4;
6859 const bool IsPPC64 = Subtarget.
isPPC64();
6860 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6861 const Align PtrAlign(PtrSize);
6862 const Align StackAlign(16);
6863 const MVT RegVT = IsPPC64 ? MVT::i64 : MVT::i32;
6865 if (ValVT == MVT::f128)
6872 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6873 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6875 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6876 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6879 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6880 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6881 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6887 if (ByValAlign > StackAlign)
6889 "16 are not supported.");
6892 const Align ObjAlign = ByValAlign > PtrAlign ? ByValAlign : PtrAlign;
6896 if (ByValSize == 0) {
6904 while (NextReg != GPRs.
size() &&
6910 assert(Reg &&
"Alocating register unexpectedly failed.");
6915 const unsigned StackSize =
alignTo(ByValSize, ObjAlign);
6936 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6965 for (
unsigned I = 0;
I < StoreSize;
I += PtrSize) {
6967 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
7000 const unsigned VecSize = 16;
7001 const Align VecAlign(VecSize);
7021 while (NextRegIndex != GPRs.
size() &&
7026 assert(Reg &&
"Allocating register unexpectedly failed.");
7039 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
7051 if (NextRegIndex == GPRs.
size()) {
7060 if (GPRs[NextRegIndex] == PPC::R9) {
7065 const unsigned FirstReg = State.
AllocateReg(PPC::R9);
7066 const unsigned SecondReg = State.
AllocateReg(PPC::R10);
7067 assert(FirstReg && SecondReg &&
7068 "Allocating R9 or R10 unexpectedly failed.");
7082 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
7084 assert(Reg &&
"Failed to allocated register for vararg vector argument");
7099 assert((IsPPC64 || SVT != MVT::i64) &&
7100 "i64 should have been split for 32-bit codegen.");
7108 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7110 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
7112 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
7120 return &PPC::VRRCRegClass;
7133 else if (Flags.isZExt())
7143 if (PPC::GPRCRegClass.
contains(Reg)) {
7144 assert(Reg >= PPC::R3 && Reg <= PPC::R10 &&
7145 "Reg must be a valid argument register!");
7146 return LASize + 4 * (Reg - PPC::R3);
7149 if (PPC::G8RCRegClass.
contains(Reg)) {
7150 assert(Reg >= PPC::X3 && Reg <= PPC::X10 &&
7151 "Reg must be a valid argument register!");
7152 return LASize + 8 * (Reg - PPC::X3);
7198SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7205 "Unexpected calling convention!");
7215 const bool IsPPC64 = Subtarget.
isPPC64();
7216 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7228 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7229 uint64_t SaveStackPos = CCInfo.getStackSize();
7231 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7251 LocVT.
SimpleTy, IsPPC64, Subtarget.hasP8Vector(), Subtarget.hasVSX());
7253 MVT SaveVT = RegClass == &PPC::G8RCRegClass ? MVT::i64 : LocVT;
7265 unsigned StoreSize =
7267 SaveStackPos =
alignTo(SaveStackPos + StoreSize, PtrByteSize);
7270 auto HandleMemLoc = [&]() {
7273 assert((ValSize <= LocSize) &&
7274 "Object size is larger than size of MemLoc");
7277 if (LocSize > ValSize)
7278 CurArgOffset += LocSize - ValSize;
7280 const bool IsImmutable =
7295 assert(isVarArg &&
"Only use custom memloc for vararg.");
7298 const unsigned OriginalValNo = VA.
getValNo();
7299 (void)OriginalValNo;
7301 auto HandleCustomVecRegLoc = [&]() {
7302 assert(
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7303 "Missing custom RegLoc.");
7306 "Unexpected Val type for custom RegLoc.");
7308 "ValNo mismatch between custom MemLoc and RegLoc.");
7312 Subtarget.hasVSX()));
7319 HandleCustomVecRegLoc();
7320 HandleCustomVecRegLoc();
7324 if (
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7326 "Only 2 custom RegLocs expected for 64-bit codegen.");
7327 HandleCustomVecRegLoc();
7328 HandleCustomVecRegLoc();
7372 const unsigned Size =
7384 if (
Flags.isByVal()) {
7390 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7399 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7401 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7414 CopyFrom.
getValue(1), dl, CopyFrom,
7424 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7427 "RegLocs should be for ByVal argument.");
7434 if (
Offset != StackSize) {
7436 "Expected MemLoc for remaining bytes.");
7437 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7451 Subtarget.hasVSX()));
7468 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7470 unsigned CallerReservedArea = std::max<unsigned>(
7471 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7477 CallerReservedArea =
7486 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7487 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7489 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7490 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7491 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7496 for (
unsigned GPRIndex =
7497 (CCInfo.getStackSize() - LinkageSize) / PtrByteSize;
7498 GPRIndex < NumGPArgRegs; ++GPRIndex) {
7501 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7502 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7514 if (!MemOps.
empty())
7520SDValue PPCTargetLowering::LowerCall_AIX(
7533 "Unexpected calling convention!");
7535 if (CFlags.IsPatchPoint)
7542 AIXCCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7550 const bool IsPPC64 = Subtarget.
isPPC64();
7552 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7553 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7554 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7562 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7563 const unsigned NumBytes = std::max<unsigned>(
7564 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7580 for (
unsigned I = 0, E = ArgLocs.
size();
I != E;) {
7581 const unsigned ValNo = ArgLocs[
I].getValNo();
7585 if (
Flags.isByVal()) {
7586 const unsigned ByValSize =
Flags.getByValSize();
7594 auto GetLoad = [&](
EVT VT,
unsigned LoadOffset) {
7603 unsigned LoadOffset = 0;
7606 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7609 LoadOffset += PtrByteSize;
7612 "Unexpected location for pass-by-value argument.");
7616 if (LoadOffset == ByValSize)
7620 assert(ArgLocs[
I].getValNo() == ValNo &&
7621 "Expected additional location for by-value argument.");
7623 if (ArgLocs[
I].isMemLoc()) {
7624 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7629 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7635 CallSeqStart, MemcpyFlags, DAG, dl);
7644 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7645 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7646 "Unexpected register residue for by-value argument.");
7648 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7652 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7662 "Unexpected load emitted during handling of pass-by-value "
7670 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7705 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7713 const unsigned OriginalValNo = VA.
getValNo();
7715 unsigned LoadOffset = 0;
7716 auto HandleCustomVecRegLoc = [&]() {
7717 assert(
I != E &&
"Unexpected end of CCvalAssigns.");
7718 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7719 "Expected custom RegLoc.");
7722 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7728 LoadOffset += PtrByteSize;
7734 HandleCustomVecRegLoc();
7735 HandleCustomVecRegLoc();
7737 if (
I != E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7738 ArgLocs[
I].getValNo() == OriginalValNo) {
7740 "Only 2 custom RegLocs expected for 64-bit codegen.");
7741 HandleCustomVecRegLoc();
7742 HandleCustomVecRegLoc();
7760 "Unexpected register handling for calling convention.");
7766 "Custom register handling only expected for VarArg.");
7784 "Unexpected custom register for argument!");
7805 if (!MemOpChains.
empty())
7810 if (CFlags.IsIndirect) {
7811 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7814 const MVT PtrVT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
7815 const unsigned TOCSaveOffset =
7831 for (
auto Reg : RegsToPass) {
7836 const int SPDiff = 0;
7837 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7838 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7847 CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
7848 return CCInfo.CheckReturn(
7863 CCInfo.AnalyzeReturn(Outs,
7872 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7876 SDValue Arg = OutVals[RealResIdx];
7891 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7914 RetOps.push_back(Glue);
7920PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7925 EVT IntVT =
Op.getValueType();
7929 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7931 SDValue Ops[2] = {Chain, FPSIdx};
7945 bool isPPC64 = Subtarget.
isPPC64();
7946 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7966 bool isPPC64 = Subtarget.
isPPC64();
7987PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
7989 bool isPPC64 = Subtarget.
isPPC64();
8023 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
8024 SDValue Ops[3] = { Chain, NegSize, FPSIdx };
8035 bool isPPC64 = Subtarget.
isPPC64();
8047 Op.getOperand(0),
Op.getOperand(1));
8054 Op.getOperand(0),
Op.getOperand(1));
8058 if (
Op.getValueType().isVector())
8059 return LowerVectorLoad(
Op, DAG);
8061 assert(
Op.getValueType() == MVT::i1 &&
8062 "Custom lowering only for i1 loads");
8075 BasePtr, MVT::i8, MMO);
8083 if (
Op.getOperand(1).getValueType().isVector())
8084 return LowerVectorStore(
Op, DAG);
8086 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
8087 "Custom lowering only for i1 stores");
8106 assert(
Op.getValueType() == MVT::i1 &&
8107 "Custom lowering only for i1 results");
8135 EVT TrgVT =
Op.getValueType();
8148 !llvm::has_single_bit<uint32_t>(
8159 if (SrcSize == 256) {
8170 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8178 for (
unsigned i = 0; i < TrgNumElts; ++i)
8181 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8185 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8198 EVT ResVT =
Op.getValueType();
8199 EVT CmpVT =
Op.getOperand(0).getValueType();
8201 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8207 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8224 if (Subtarget.hasP9Vector() && LHS == TV && RHS == FV) {
8256 if (
LHS.getValueType() == MVT::f32)
8269 if (
LHS.getValueType() == MVT::f32)
8278 if (
LHS.getValueType() == MVT::f32)
8292 if (
Cmp.getValueType() == MVT::f32)
8302 if (
Cmp.getValueType() == MVT::f32)
8308 if (
Cmp.getValueType() == MVT::f32)
8314 if (
Cmp.getValueType() == MVT::f32)
8320 if (
Cmp.getValueType() == MVT::f32)
8353 bool IsStrict =
Op->isStrictFPOpcode();
8359 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8362 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8364 MVT DestTy =
Op.getSimpleValueType();
8365 assert(Src.getValueType().isFloatingPoint() &&
8366 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8367 DestTy == MVT::i64) &&
8368 "Invalid FP_TO_INT types");
8369 if (Src.getValueType() == MVT::f32) {
8373 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8374 Chain = Src.getValue(1);
8378 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8379 DestTy = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
8388 assert((IsSigned || Subtarget.hasFPCVT()) &&
8389 "i64 FP_TO_UINT is supported only with FPCVT");
8392 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8396 Conv = DAG.
getNode(Opc, dl, DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src},
8399 Conv = DAG.
getNode(Opc, dl, ConvTy, Src);
8404void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8406 const SDLoc &dl)
const {
8410 bool IsStrict =
Op->isStrictFPOpcode();
8413 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8414 (IsSigned || Subtarget.hasFPCVT());
8416 int FI = cast<FrameIndexSDNode>(FIPtr)->getIndex();
8425 Alignment =
Align(4);
8428 SDValue Ops[] = { Chain, Tmp, FIPtr };
8430 DAG.
getVTList(MVT::Other), Ops, MVT::i32, MMO);
8432 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8436 if (
Op.getValueType() == MVT::i32 && !i32Stack) {
8445 RLI.Alignment = Alignment;
8453 const SDLoc &dl)
const {
8456 if (
Op->isStrictFPOpcode())
8463 const SDLoc &dl)
const {
8464 bool IsStrict =
Op->isStrictFPOpcode();
8467 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8468 EVT SrcVT = Src.getValueType();
8469 EVT DstVT =
Op.getValueType();
8472 if (SrcVT == MVT::f128)
8473 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8477 if (SrcVT == MVT::ppcf128) {
8478 if (DstVT == MVT::i32) {
8483 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8494 {Op.getOperand(0), Lo, Hi}, Flags);
8497 {Res.getValue(1), Res}, Flags);
8503 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8527 {Chain, Src, FltOfs}, Flags);
8531 {Chain, Val}, Flags);
8534 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8552 if (Subtarget.hasDirectMove() && Subtarget.
isPPC64())
8553 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8556 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8558 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8559 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8570bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8575 if (
Op->isStrictFPOpcode())
8580 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8584 Op.getOperand(0).getValueType())) {
8586 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8591 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8592 LD->isNonTemporal())
8594 if (
LD->getMemoryVT() != MemVT)
8604 RLI.Ptr =
LD->getBasePtr();
8605 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8607 "Non-pre-inc AM on PPC?");
8612 RLI.Chain =
LD->getChain();
8613 RLI.MPI =
LD->getPointerInfo();
8614 RLI.IsDereferenceable =
LD->isDereferenceable();
8615 RLI.IsInvariant =
LD->isInvariant();
8616 RLI.Alignment =
LD->getAlign();
8617 RLI.AAInfo =
LD->getAAInfo();
8618 RLI.Ranges =
LD->getRanges();
8620 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8628void PPCTargetLowering::spliceIntoChain(
SDValue ResChain,
8634 SDLoc dl(NewResChain);
8637 NewResChain, DAG.
getUNDEF(MVT::Other));
8639 "A new TF really is required here");
8648bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8649 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8656 if (!Subtarget.hasP9Vector() &&
8665 if (UI.getUse().get().getResNo() != 0)
8687 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8691 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8694 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8695 if (
Op->isStrictFPOpcode()) {
8697 Chain =
Op.getOperand(0);
8699 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8701 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8709 const SDLoc &dl)
const {
8710 assert((
Op.getValueType() == MVT::f32 ||
8711 Op.getValueType() == MVT::f64) &&
8712 "Invalid floating point type as target of conversion");
8713 assert(Subtarget.hasFPCVT() &&
8714 "Int to FP conversions with direct moves require FPCVT");
8715 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8716 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8738 for (
unsigned i = 1; i < NumConcat; ++i)
8745 const SDLoc &dl)
const {
8746 bool IsStrict =
Op->isStrictFPOpcode();
8747 unsigned Opc =
Op.getOpcode();
8748 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8751 "Unexpected conversion type");
8752 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8753 "Supports conversions to v2f64/v4f32 only.");
8757 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8760 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8765 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8768 for (
unsigned i = 0; i < WideNumElts; ++i)
8771 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8772 int SaveElts = FourEltRes ? 4 : 2;
8774 for (
int i = 0; i < SaveElts; i++)
8775 ShuffV[i * Stride] = i;
8777 for (
int i = 1; i <= SaveElts; i++)
8778 ShuffV[i * Stride - 1] = i - 1;
8786 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8787 EVT ExtVT = Src.getValueType();
8788 if (Subtarget.hasP9Altivec())
8799 {Op.getOperand(0), Extend}, Flags);
8801 return DAG.
getNode(Opc, dl,
Op.getValueType(), Extend);
8809 bool IsStrict =
Op->isStrictFPOpcode();
8810 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8815 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8817 EVT InVT = Src.getValueType();
8818 EVT OutVT =
Op.getValueType();
8821 return LowerINT_TO_FPVector(
Op, DAG, dl);
8824 if (
Op.getValueType() == MVT::f128)
8825 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8828 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8831 if (Src.getValueType() == MVT::i1) {
8843 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8844 Subtarget.
isPPC64() && Subtarget.hasFPCVT())
8845 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8847 assert((IsSigned || Subtarget.hasFPCVT()) &&
8848 "UINT_TO_FP is supported only with FPCVT");
8850 if (Src.getValueType() == MVT::i64) {
8862 if (
Op.getValueType() == MVT::f32 &&
8863 !Subtarget.hasFPCVT() &&
8904 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8905 Bits = DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8906 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8907 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8908 }
else if (Subtarget.hasLFIWAX() &&
8909 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8912 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8913 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8916 Ops, MVT::i32, MMO);
8917 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8918 }
else if (Subtarget.hasFPCVT() &&
8919 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8922 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8923 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8926 Ops, MVT::i32, MMO);
8927 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8928 }
else if (((Subtarget.hasLFIWAX() &&
8930 (Subtarget.hasFPCVT() &&
8944 assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
8945 "Expected an i32 store");
8951 RLI.Alignment =
Align(4);
8955 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8956 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8959 dl, DAG.
getVTList(MVT::f64, MVT::Other),
8960 Ops, MVT::i32, MMO);
8961 Chain =
Bits.getValue(1);
8967 Chain =
FP.getValue(1);
8969 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8973 {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
8981 assert(Src.getValueType() == MVT::i32 &&
8982 "Unhandled INT_TO_FP type in custom expander!");
8992 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
8995 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
9004 assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
9005 "Expected an i32 store");
9011 RLI.Alignment =
Align(4);
9016 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
9017 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
9019 DAG.
getVTList(MVT::f64, MVT::Other), Ops,
9023 spliceIntoChain(RLI.ResChain, Ld.
getValue(1), DAG);
9026 "i32->FP without LFIWAX supported only on PPC64");
9035 Chain, dl, Ext64, FIdx,
9041 MVT::f64, dl, Chain, FIdx,
9049 Chain =
FP.getValue(1);
9050 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
9054 {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
9085 EVT VT =
Op.getValueType();
9091 Chain =
MFFS.getValue(1);
9105 "Stack slot adjustment is valid only on big endian subtargets!");
9135 EVT VT =
Op.getValueType();
9139 VT ==
Op.getOperand(1).getValueType() &&
9159 SDValue OutOps[] = { OutLo, OutHi };
9164 EVT VT =
Op.getValueType();
9168 VT ==
Op.getOperand(1).getValueType() &&
9188 SDValue OutOps[] = { OutLo, OutHi };
9194 EVT VT =
Op.getValueType();
9197 VT ==
Op.getOperand(1).getValueType() &&
9217 SDValue OutOps[] = { OutLo, OutHi };
9224 EVT VT =
Op.getValueType();
9231 EVT AmtVT =
Z.getValueType();
9254 static const MVT VTys[] = {
9255 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9258 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9261 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9266 EVT CanonicalVT = VTys[SplatSize-1];
9275 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9276 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9285 EVT DestVT = MVT::Other) {
9286 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9295 EVT DestVT = MVT::Other) {
9298 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9310 for (
unsigned i = 0; i != 16; ++i)
9331 EVT VecVT = V->getValueType(0);
9332 bool RightType = VecVT == MVT::v2f64 ||
9333 (HasP8Vector && VecVT == MVT::v4f32) ||
9334 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9338 bool IsSplat =
true;
9339 bool IsLoad =
false;
9340 SDValue Op0 = V->getOperand(0);
9345 if (V->isConstant())
9347 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9348 if (V->getOperand(i).isUndef())
9352 if (V->getOperand(i).getOpcode() ==
ISD::LOAD ||
9354 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9356 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9358 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD))
9362 if (V->getOperand(i) != Op0 ||
9363 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9366 return !(IsSplat && IsLoad);
9378 if ((
Op.getValueType() != MVT::f128) ||
9380 (
Hi.getValueType() != MVT::i64) || !Subtarget.
isPPC64())
9400 LoadSDNode *LD = cast<LoadSDNode>(*InputLoad);
9408 APFloat APFloatToConvert = ArgAPFloat;
9409 bool LosesInfo =
true;
9414 ArgAPFloat = APFloatToConvert;
9436 APFloat APFloatToConvert = ArgAPFloat;
9437 bool LosesInfo =
true;
9441 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9446 LoadSDNode *InputNode = dyn_cast<LoadSDNode>(
Op.getOperand(0));
9450 EVT Ty =
Op->getValueType(0);
9453 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9462 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9466 if (Ty == MVT::v2i64) {
9469 if (MemVT == MVT::i32) {
9489 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9492 APInt APSplatBits, APSplatUndef;
9493 unsigned SplatBitSize;
9495 bool BVNIsConstantSplat =
9503 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9504 Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
9507 if ((
Op->getValueType(0) == MVT::v2f64) &&
9540 if (!BVNIsConstantSplat || SplatBitSize > 32) {
9547 const SDValue *InputLoad = &
Op.getOperand(0);
9552 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9553 unsigned ElementSize =
9556 assert(((ElementSize == 2 * MemorySize)
9560 "Unmatched element size and opcode!\n");
9565 unsigned NumUsesOfInputLD = 128 / ElementSize;
9567 if (BVInOp.isUndef())
9582 if (NumUsesOfInputLD == 1 &&
9585 Subtarget.hasLFIWAX()))
9594 Subtarget.isISA3_1() && ElementSize <= 16)
9597 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9599 Subtarget.hasVSX()) {
9606 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other), Ops,
9607 LD->getMemoryVT(),
LD->getMemOperand());
9619 if (Subtarget.hasVSX() && Subtarget.
isPPC64() &&
9621 Subtarget.hasP8Vector()))
9628 unsigned SplatSize = SplatBitSize / 8;
9633 if (SplatBits == 0) {
9635 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9647 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 2)
9649 Op.getValueType(), DAG, dl);
9651 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 4)
9656 if (Subtarget.hasP9Vector() && SplatSize == 1)
9661 int32_t SextVal =
SignExtend32(SplatBits, SplatBitSize);
9662 if (SextVal >= -16 && SextVal <= 15)
9675 if (SextVal >= -32 && SextVal <= 31) {
9680 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9681 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9684 if (VT ==
Op.getValueType())
9693 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9707 static const signed char SplatCsts[] = {
9708 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9709 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9712 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9715 int i = SplatCsts[idx];
9719 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9722 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9724 static const unsigned IIDs[] = {
9725 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9726 Intrinsic::ppc_altivec_vslw
9733 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9735 static const unsigned IIDs[] = {
9736 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9737 Intrinsic::ppc_altivec_vsrw
9744 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9745 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9747 static const unsigned IIDs[] = {
9748 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
9749 Intrinsic::ppc_altivec_vrlw
9756 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
9762 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
9768 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
9783 unsigned OpNum = (PFEntry >> 26) & 0x0F;
9784 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
9785 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
9801 if (LHSID == (1*9+2)*9+3)
return LHS;
9802 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
9814 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
9815 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
9816 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
9817 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
9820 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
9821 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
9822 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
9823 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
9826 for (
unsigned i = 0; i != 16; ++i)
9827 ShufIdxs[i] = (i&3)+0;
9830 for (
unsigned i = 0; i != 16; ++i)
9831 ShufIdxs[i] = (i&3)+4;
9834 for (
unsigned i = 0; i != 16; ++i)
9835 ShufIdxs[i] = (i&3)+8;
9838 for (
unsigned i = 0; i != 16; ++i)
9839 ShufIdxs[i] = (i&3)+12;
9860 const unsigned BytesInVector = 16;
9865 unsigned ShiftElts = 0, InsertAtByte = 0;
9869 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
9870 0, 15, 14, 13, 12, 11, 10, 9};
9871 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
9872 1, 2, 3, 4, 5, 6, 7, 8};
9875 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
9887 bool FoundCandidate =
false;
9891 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
9894 for (
unsigned i = 0; i < BytesInVector; ++i) {
9895 unsigned CurrentElement =
Mask[i];
9898 if (
V2.isUndef() && CurrentElement != VINSERTBSrcElem)
9901 bool OtherElementsInOrder =
true;
9904 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
9911 (!
V2.isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
9912 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
9913 OtherElementsInOrder =
false;
9920 if (OtherElementsInOrder) {
9927 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
9928 : BigEndianShifts[CurrentElement & 0xF];
9929 Swap = CurrentElement < BytesInVector;
9931 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
9932 FoundCandidate =
true;
9937 if (!FoundCandidate)
9961 const unsigned NumHalfWords = 8;
9962 const unsigned BytesInVector = NumHalfWords * 2;
9971 unsigned ShiftElts = 0, InsertAtByte = 0;
9975 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
9976 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
9979 uint32_t OriginalOrderLow = 0x1234567;
9980 uint32_t OriginalOrderHigh = 0x89ABCDEF;
9983 for (
unsigned i = 0; i < NumHalfWords; ++i) {
9984 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10001 bool FoundCandidate =
false;
10004 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10005 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10013 if (
V2.isUndef()) {
10015 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
10016 TargetOrder = OriginalOrderLow;
10020 if (MaskOneElt == VINSERTHSrcElem &&
10021 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10022 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10023 FoundCandidate =
true;
10029 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
10031 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10033 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
10034 : BigEndianShifts[MaskOneElt & 0x7];
10035 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10036 Swap = MaskOneElt < NumHalfWords;
10037 FoundCandidate =
true;
10043 if (!FoundCandidate)
10078 auto ShuffleMask = SVN->
getMask();
10093 ShuffleMask = CommutedSV->
getMask();
10102 APInt APSplatValue, APSplatUndef;
10103 unsigned SplatBitSize;
10119 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
10120 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
10121 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
10123 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
10124 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
10125 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
10133 for (; SplatBitSize < 32; SplatBitSize <<= 1)
10134 SplatVal |= (SplatVal << SplatBitSize);
10148 assert(
Op.getValueType() == MVT::v1i128 &&
10149 "Only set v1i128 as custom, other type shouldn't reach here!");
10154 if (SHLAmt % 8 == 0) {
10155 std::array<int, 16>
Mask;
10156 std::iota(
Mask.begin(),
Mask.end(), 0);
10157 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10186 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10187 if (!isa<ShuffleVectorSDNode>(NewShuffle))
10190 SVOp = cast<ShuffleVectorSDNode>(
Op);
10191 V1 =
Op.getOperand(0);
10192 V2 =
Op.getOperand(1);
10194 EVT VT =
Op.getValueType();
10197 unsigned ShiftElts, InsertAtByte;
10203 bool IsPermutedLoad =
false;
10205 if (InputLoad && Subtarget.hasVSX() &&
V2.isUndef() &&
10215 if (IsPermutedLoad) {
10216 assert((isLittleEndian || IsFourByte) &&
10217 "Unexpected size for permuted load on big endian target");
10218 SplatIdx += IsFourByte ? 2 : 1;
10219 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10220 "Splat of a value outside of the loaded memory");
10225 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10228 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10230 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10234 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10247 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10250 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10259 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10262 if (Subtarget.hasP9Vector() &&
10283 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
10285 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10286 return SplatInsertNode;
10289 if (Subtarget.hasP9Altivec()) {
10291 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10294 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10298 if (Subtarget.hasVSX() &&
10311 if (Subtarget.hasVSX() &&
10324 if (Subtarget.hasP9Vector()) {
10344 if (Subtarget.hasVSX()) {
10365 if (
V2.isUndef()) {
10378 (Subtarget.hasP8Altivec() && (
10389 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10399 (Subtarget.hasP8Altivec() && (
10410 unsigned PFIndexes[4];
10411 bool isFourElementShuffle =
true;
10412 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10414 unsigned EltNo = 8;
10415 for (
unsigned j = 0;
j != 4; ++
j) {
10416 if (PermMask[i * 4 + j] < 0)
10419 unsigned ByteSource = PermMask[i * 4 +
j];
10420 if ((ByteSource & 3) != j) {
10421 isFourElementShuffle =
false;
10426 EltNo = ByteSource / 4;
10427 }
else if (EltNo != ByteSource / 4) {
10428 isFourElementShuffle =
false;
10432 PFIndexes[i] = EltNo;
10440 if (isFourElementShuffle) {
10442 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10443 PFIndexes[2] * 9 + PFIndexes[3];
10446 unsigned Cost = (PFEntry >> 30);
10466 if (
V2.isUndef())
V2 = V1;
10468 return LowerVPERM(
Op, DAG, PermMask, VT, V1, V2);
10477 bool NeedSwap =
false;
10479 bool isPPC64 = Subtarget.
isPPC64();
10481 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10483 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10484 "XXPERM instead\n");
10490 if ((!isLittleEndian && !
V2->hasOneUse() && V1->
hasOneUse()) ||
10491 (isLittleEndian && !V1->
hasOneUse() &&
V2->hasOneUse())) {
10493 NeedSwap = !NeedSwap;
10528 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10530 if (V1HasXXSWAPD) {
10533 else if (SrcElt < 16)
10536 if (V2HasXXSWAPD) {
10539 else if (SrcElt > 15)
10548 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10549 if (isLittleEndian)
10551 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10554 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10557 if (V1HasXXSWAPD) {
10561 if (V2HasXXSWAPD) {
10562 dl =
SDLoc(
V2->getOperand(0));
10563 V2 =
V2->getOperand(0)->getOperand(1);
10566 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10567 if (ValType != MVT::v2f64)
10569 if (
V2.getValueType() != MVT::v2f64)
10573 ShufflesHandledWithVPERM++;
10578 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10580 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10583 dbgs() <<
"With the following permute control vector:\n";
10588 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10592 if (isLittleEndian)
10598 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10610 switch (IntrinsicID) {
10614 case Intrinsic::ppc_altivec_vcmpbfp_p:
10618 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10622 case Intrinsic::ppc_altivec_vcmpequb_p:
10626 case Intrinsic::ppc_altivec_vcmpequh_p:
10630 case Intrinsic::ppc_altivec_vcmpequw_p:
10634 case Intrinsic::ppc_altivec_vcmpequd_p:
10635 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10641 case Intrinsic::ppc_altivec_vcmpneb_p:
10642 case Intrinsic::ppc_altivec_vcmpneh_p:
10643 case Intrinsic::ppc_altivec_vcmpnew_p:
10644 case Intrinsic::ppc_altivec_vcmpnezb_p:
10645 case Intrinsic::ppc_altivec_vcmpnezh_p:
10646 case Intrinsic::ppc_altivec_vcmpnezw_p:
10647 if (Subtarget.hasP9Altivec()) {
10648 switch (IntrinsicID) {
10651 case Intrinsic::ppc_altivec_vcmpneb_p:
10654 case Intrinsic::ppc_altivec_vcmpneh_p:
10657 case Intrinsic::ppc_altivec_vcmpnew_p:
10660 case Intrinsic::ppc_altivec_vcmpnezb_p:
10663 case Intrinsic::ppc_altivec_vcmpnezh_p:
10666 case Intrinsic::ppc_altivec_vcmpnezw_p:
10674 case Intrinsic::ppc_altivec_vcmpgefp_p:
10678 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10682 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10686 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10690 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10694 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10695 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10701 case Intrinsic::ppc_altivec_vcmpgtub_p:
10705 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10709 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10713 case Intrinsic::ppc_altivec_vcmpgtud_p:
10714 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10721 case Intrinsic::ppc_altivec_vcmpequq:
10722 case Intrinsic::ppc_altivec_vcmpgtsq:
10723 case Intrinsic::ppc_altivec_vcmpgtuq:
10724 if (!Subtarget.isISA3_1())
10726 switch (IntrinsicID) {
10729 case Intrinsic::ppc_altivec_vcmpequq:
10732 case Intrinsic::ppc_altivec_vcmpgtsq:
10735 case Intrinsic::ppc_altivec_vcmpgtuq:
10742 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10743 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10744 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10745 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10746 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10747 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10748 if (Subtarget.hasVSX()) {
10749 switch (IntrinsicID) {
10750 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10753 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10756 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10759 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10762 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10765 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10775 case Intrinsic::ppc_altivec_vcmpbfp:
10778 case Intrinsic::ppc_altivec_vcmpeqfp:
10781 case Intrinsic::ppc_altivec_vcmpequb:
10784 case Intrinsic::ppc_altivec_vcmpequh:
10787 case Intrinsic::ppc_altivec_vcmpequw:
10790 case Intrinsic::ppc_altivec_vcmpequd:
10791 if (Subtarget.hasP8Altivec())
10796 case Intrinsic::ppc_altivec_vcmpneb:
10797 case Intrinsic::ppc_altivec_vcmpneh:
10798 case Intrinsic::ppc_altivec_vcmpnew:
10799 case Intrinsic::ppc_altivec_vcmpnezb:
10800 case Intrinsic::ppc_altivec_vcmpnezh:
10801 case Intrinsic::ppc_altivec_vcmpnezw:
10802 if (Subtarget.hasP9Altivec())
10803 switch (IntrinsicID) {
10806 case Intrinsic::ppc_altivec_vcmpneb:
10809 case Intrinsic::ppc_altivec_vcmpneh:
10812 case Intrinsic::ppc_altivec_vcmpnew:
10815 case Intrinsic::ppc_altivec_vcmpnezb:
10818 case Intrinsic::ppc_altivec_vcmpnezh:
10821 case Intrinsic::ppc_altivec_vcmpnezw:
10828 case Intrinsic::ppc_altivec_vcmpgefp:
10831 case Intrinsic::ppc_altivec_vcmpgtfp:
10834 case Intrinsic::ppc_altivec_vcmpgtsb:
10837 case Intrinsic::ppc_altivec_vcmpgtsh:
10840 case Intrinsic::ppc_altivec_vcmpgtsw:
10843 case Intrinsic::ppc_altivec_vcmpgtsd:
10844 if (Subtarget.hasP8Altivec())
10849 case Intrinsic::ppc_altivec_vcmpgtub:
10852 case Intrinsic::ppc_altivec_vcmpgtuh:
10855 case Intrinsic::ppc_altivec_vcmpgtuw:
10858 case Intrinsic::ppc_altivec_vcmpgtud:
10859 if (Subtarget.hasP8Altivec())
10864 case Intrinsic::ppc_altivec_vcmpequq_p:
10865 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10866 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10867 if (!Subtarget.isISA3_1())
10869 switch (IntrinsicID) {
10872 case Intrinsic::ppc_altivec_vcmpequq_p:
10875 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10878 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10892 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
10896 switch (IntrinsicID) {
10897 case Intrinsic::thread_pointer:
10903 case Intrinsic::ppc_rldimi: {
10904 assert(Subtarget.
isPPC64() &&
"rldimi is only available in 64-bit!");
10908 return Op.getOperand(2);
10909 if (
Mask.isAllOnes())
10912 unsigned MB = 0, ME = 0;
10916 if (ME < 63 - SH) {
10919 }
else if (ME > 63 - SH) {
10925 {Op.getOperand(2), Src,
10926 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
10927 DAG.getTargetConstant(MB, dl, MVT::i32)}),
10931 case Intrinsic::ppc_rlwimi: {
10934 return Op.getOperand(2);
10935 if (
Mask.isAllOnes())
10938 unsigned MB = 0, ME = 0;
10942 PPC::RLWIMI, dl, MVT::i32,
10943 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
10944 DAG.getTargetConstant(MB, dl, MVT::i32),
10945 DAG.getTargetConstant(ME, dl, MVT::i32)}),
10949 case Intrinsic::ppc_rlwnm: {
10950 if (
Op.getConstantOperandVal(3) == 0)
10952 unsigned MB = 0, ME = 0;
10957 {Op.getOperand(1), Op.getOperand(2),
10958 DAG.getTargetConstant(MB, dl, MVT::i32),
10959 DAG.getTargetConstant(ME, dl, MVT::i32)}),
10963 case Intrinsic::ppc_mma_disassemble_acc: {
10964 if (Subtarget.isISAFuture()) {
10965 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11003 case Intrinsic::ppc_vsx_disassemble_pair: {
11006 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
11011 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
11022 case Intrinsic::ppc_mma_xxmfacc:
11023 case Intrinsic::ppc_mma_xxmtacc: {
11025 if (!Subtarget.isISAFuture())
11036 case Intrinsic::ppc_unpack_longdouble: {
11037 auto *
Idx = dyn_cast<ConstantSDNode>(
Op.getOperand(2));
11038 assert(
Idx && (
Idx->getSExtValue() == 0 ||
Idx->getSExtValue() == 1) &&
11039 "Argument of long double unpack must be 0 or 1!");
11042 Idx->getValueType(0)));
11045 case Intrinsic::ppc_compare_exp_lt:
11046 case Intrinsic::ppc_compare_exp_gt:
11047 case Intrinsic::ppc_compare_exp_eq:
11048 case Intrinsic::ppc_compare_exp_uo: {
11050 switch (IntrinsicID) {
11051 case Intrinsic::ppc_compare_exp_lt:
11054 case Intrinsic::ppc_compare_exp_gt:
11057 case Intrinsic::ppc_compare_exp_eq:
11060 case Intrinsic::ppc_compare_exp_uo:
11066 PPC::SELECT_CC_I4, dl, MVT::i32,
11067 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
11068 Op.getOperand(1), Op.getOperand(2)),
11070 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11071 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
11074 case Intrinsic::ppc_test_data_class: {
11075 EVT OpVT =
Op.getOperand(1).getValueType();
11076 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
11077 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
11081 PPC::SELECT_CC_I4, dl, MVT::i32,
11082 {SDValue(DAG.getMachineNode(CmprOpc, dl, MVT::i32, Op.getOperand(2),
11085 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11086 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
11089 case Intrinsic::ppc_fnmsub: {
11090 EVT VT =
Op.getOperand(1).getValueType();
11091 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
11097 Op.getOperand(2),
Op.getOperand(3));
11099 case Intrinsic::ppc_convert_f128_to_ppcf128:
11100 case Intrinsic::ppc_convert_ppcf128_to_f128: {
11101 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
11102 ? RTLIB::CONVERT_PPCF128_F128
11103 : RTLIB::CONVERT_F128_PPCF128;
11104 MakeLibCallOptions CallOptions;
11105 std::pair<SDValue, SDValue>
Result =
11106 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
11110 case Intrinsic::ppc_maxfe:
11111 case Intrinsic::ppc_maxfl:
11112 case Intrinsic::ppc_maxfs:
11113 case Intrinsic::ppc_minfe:
11114 case Intrinsic::ppc_minfl:
11115 case Intrinsic::ppc_minfs: {
11116 EVT VT =
Op.getValueType();
11119 [VT](
const SDUse &
Use) { return Use.getValueType() == VT; }) &&
11120 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
11123 if (IntrinsicID == Intrinsic::ppc_minfe ||
11124 IntrinsicID == Intrinsic::ppc_minfl ||
11125 IntrinsicID == Intrinsic::ppc_minfs)
11147 Op.getOperand(1),
Op.getOperand(2),
11158 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11170 switch (
Op.getConstantOperandVal(1)) {
11173 BitNo = 0; InvertBit =
false;
11176 BitNo = 0; InvertBit =
true;
11179 BitNo = 2; InvertBit =
false;
11182 BitNo = 2; InvertBit =
true;
11204 int ArgStart = isa<ConstantSDNode>(
Op.getOperand(0)) ? 0 : 1;
11206 switch (
Op.getConstantOperandVal(ArgStart)) {
11207 case Intrinsic::ppc_cfence: {
11208 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11209 SDValue Val =
Op.getOperand(ArgStart + 1);
11211 if (Ty == MVT::i128) {
11216 unsigned Opcode = Subtarget.
isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11217 EVT FTy = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
11241 int VectorIndex = 0;
11254 "Expecting an atomic compare-and-swap here.");
11256 auto *AtomicNode = cast<AtomicSDNode>(
Op.getNode());
11257 EVT MemVT = AtomicNode->getMemoryVT();
11275 for (
int i = 0, e = AtomicNode->getNumOperands(); i <
e; i++)
11276 Ops.
push_back(AtomicNode->getOperand(i));
11288 EVT MemVT =
N->getMemoryVT();
11290 "Expect quadword atomic operations");
11292 unsigned Opc =
N->getOpcode();
11300 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11301 for (
int I = 1, E =
N->getNumOperands();
I < E; ++
I)
11304 Ops, MemVT,
N->getMemOperand());
11311 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11321 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11331 N->getMemOperand());
11343 enum DataClassMask {
11345 DC_NEG_INF = 1 << 4,
11346 DC_POS_INF = 1 << 5,
11347 DC_NEG_ZERO = 1 << 2,
11348 DC_POS_ZERO = 1 << 3,
11349 DC_NEG_SUBNORM = 1,
11350 DC_POS_SUBNORM = 1 << 1,
11353 EVT VT =
Op.getValueType();
11355 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11356 : VT == MVT::f64 ? PPC::XSTSTDCDP
11367 return DAG.
getNOT(Dl, Rev, MVT::i1);
11374 TestOp, Dl, MVT::i32,
11376 DC_NEG_ZERO | DC_POS_ZERO |
11377 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11383 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11389 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11394 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11407 bool IsQuiet = Mask &
fcQNan;
11413 if (VT == MVT::f128) {
11417 QuietMask = 0x8000;
11418 }
else if (VT == MVT::f64) {
11430 QuietMask = 0x80000;
11431 }
else if (VT == MVT::f32) {
11433 QuietMask = 0x400000;
11449 unsigned NativeMask = 0;
11451 NativeMask |= DC_NAN;
11453 NativeMask |= DC_NEG_INF;
11455 NativeMask |= DC_POS_INF;
11457 NativeMask |= DC_NEG_ZERO;
11459 NativeMask |= DC_POS_ZERO;
11461 NativeMask |= DC_NEG_SUBNORM;
11463 NativeMask |= DC_POS_SUBNORM;
11466 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11468 TestOp, Dl, MVT::i32,
11477 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11479 uint64_t RHSC =
Op.getConstantOperandVal(1);
11507 64 -
Op.getValueType().getScalarSizeInBits(), dl, ShiftAmountTy);
11514 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx,
11528 "Should only be called for ISD::INSERT_VECTOR_ELT");
11532 EVT VT =
Op.getValueType();
11537 if (VT == MVT::v2f64 &&
C)
11540 if (Subtarget.hasP9Vector()) {
11549 if ((VT == MVT::v4f32) && (
V2.getValueType() == MVT::f32) &&
11550 (isa<LoadSDNode>(V2))) {
11555 BitcastLoad,
Op.getOperand(2));
11556 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
11560 if (Subtarget.isISA3_1()) {
11561 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.
isPPC64())
11565 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
11566 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
11576 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
11579 unsigned InsertAtElement =
C->getZExtValue();
11580 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
11582 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
11596 EVT VT =
Op.getValueType();
11598 if (VT != MVT::v256i1 && VT != MVT::v512i1)
11604 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
11605 "Type unsupported without MMA");
11606 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
11607 "Type unsupported without paired vector support");
11612 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
11614 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
11624 std::reverse(Loads.
begin(), Loads.
end());
11625 std::reverse(LoadChains.
begin(), LoadChains.
end());
11643 EVT StoreVT =
Value.getValueType();
11645 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
11651 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
11652 "Type unsupported without MMA");
11653 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
11654 "Type unsupported without paired vector support");
11657 unsigned NumVecs = 2;
11658 if (StoreVT == MVT::v512i1) {
11659 if (Subtarget.isISAFuture()) {
11660 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11662 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
11665 Value2 =
SDValue(ExtNode, 1);
11670 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
11673 if (Subtarget.isISAFuture()) {
11683 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
11697 if (
Op.getValueType() == MVT::v4i32) {
11714 LHS, RHS, DAG, dl, MVT::v4i32);
11717 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
11722 }
else if (
Op.getValueType() == MVT::v16i8) {
11728 LHS, RHS, DAG, dl, MVT::v8i16);
11733 LHS, RHS, DAG, dl, MVT::v8i16);
11741 for (
unsigned i = 0; i != 8; ++i) {
11742 if (isLittleEndian) {
11744 Ops[i*2+1] = 2*i+16;
11747 Ops[i*2+1] = 2*i+1+16;
11750 if (isLittleEndian)
11760 bool IsStrict =
Op->isStrictFPOpcode();
11761 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
11762 !Subtarget.hasP9Vector())
11772 "Should only be called for ISD::FP_EXTEND");
11776 if (
Op.getValueType() != MVT::v2f64 ||
11777 Op.getOperand(0).getValueType() != MVT::v2f32)
11789 "Node should have 2 operands with second one being a constant!");
11801 int DWord =
Idx >> 1;
11824 LD->getMemoryVT(),
LD->getMemOperand());
11837 LD->getMemoryVT(),
LD->getMemOperand());
11848 switch (
Op.getOpcode()) {
11877 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
11903 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
11904 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
11916 return LowerFP_ROUND(
Op, DAG);
11929 return LowerINTRINSIC_VOID(
Op, DAG);
11931 return LowerBSWAP(
Op, DAG);
11933 return LowerATOMIC_CMP_SWAP(
Op, DAG);
11935 return LowerATOMIC_LOAD_STORE(
Op, DAG);
11937 return LowerIS_FPCLASS(
Op, DAG);
11945 switch (
N->getOpcode()) {
11947 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
11964 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
11967 assert(
N->getValueType(0) == MVT::i1 &&
11968 "Unexpected result type for CTR decrement intrinsic");
11970 N->getValueType(0));
11980 switch (
N->getConstantOperandVal(0)) {
11981 case Intrinsic::ppc_pack_longdouble:
11983 N->getOperand(2),
N->getOperand(1)));
11985 case Intrinsic::ppc_maxfe:
11986 case Intrinsic::ppc_minfe:
11987 case Intrinsic::ppc_fnmsub:
11988 case Intrinsic::ppc_convert_f128_to_ppcf128:
11998 EVT VT =
N->getValueType(0);
12000 if (VT == MVT::i64) {
12013 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
12017 Results.push_back(LoweredValue);
12018 if (
N->isStrictFPOpcode())
12023 if (!
N->getValueType(0).isVector())
12074 if (isa<LoadInst>(Inst))
12078 Intrinsic::ppc_cfence, {Inst->getType()}),
12088 unsigned AtomicSize,
12089 unsigned BinOpcode,
12090 unsigned CmpOpcode,
12091 unsigned CmpPred)
const {
12095 auto LoadMnemonic = PPC::LDARX;
12096 auto StoreMnemonic = PPC::STDCX;
12097 switch (AtomicSize) {
12101 LoadMnemonic = PPC::LBARX;
12102 StoreMnemonic = PPC::STBCX;
12103 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12106 LoadMnemonic = PPC::LHARX;
12107 StoreMnemonic = PPC::STHCX;
12108 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12111 LoadMnemonic = PPC::LWARX;
12112 StoreMnemonic = PPC::STWCX;
12115 LoadMnemonic = PPC::LDARX;
12116 StoreMnemonic = PPC::STDCX;
12132 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12134 F->insert(It, loopMBB);
12136 F->insert(It, loop2MBB);
12137 F->insert(It, exitMBB);
12143 Register TmpReg = (!BinOpcode) ? incr :
12145 : &PPC::GPRCRegClass);
12170 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
12177 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
12179 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
12207 switch(
MI.getOpcode()) {
12211 return TII->isSignExtended(
MI.getOperand(1).getReg(),
12212 &
MI.getMF()->getRegInfo());
12236 case PPC::EXTSB8_32_64:
12237 case PPC::EXTSB8_rec:
12238 case PPC::EXTSB_rec:
12241 case PPC::EXTSH8_32_64:
12242 case PPC::EXTSH8_rec:
12243 case PPC::EXTSH_rec:
12245 case PPC::EXTSWSLI:
12246 case PPC::EXTSWSLI_32_64:
12247 case PPC::EXTSWSLI_32_64_rec:
12248 case PPC::EXTSWSLI_rec:
12249 case PPC::EXTSW_32:
12250 case PPC::EXTSW_32_64:
12251 case PPC::EXTSW_32_64_rec:
12252 case PPC::EXTSW_rec:
12255 case PPC::SRAWI_rec:
12256 case PPC::SRAW_rec:
12265 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
12275 bool IsSignExtended =
12278 if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
12280 BuildMI(*BB,
MI, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
12281 .
addReg(
MI.getOperand(3).getReg());
12282 MI.getOperand(3).setReg(ValueReg);
12286 if (Subtarget.hasPartwordAtomics())
12294 bool is64bit = Subtarget.
isPPC64();
12296 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
12307 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12309 F->insert(It, loopMBB);
12311 F->insert(It, loop2MBB);
12312 F->insert(It, exitMBB);
12318 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12363 if (ptrA != ZeroReg) {
12365 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
12373 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
12374 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
12377 .
addImm(is8bit ? 28 : 27);
12378 if (!isLittleEndian)
12379 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
12381 .
addImm(is8bit ? 24 : 16);
12383 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
12388 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
12398 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
12402 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
12407 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
12411 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
12414 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
12426 unsigned ValueReg = SReg;
12427 unsigned CmpReg = Incr2Reg;
12428 if (CmpOpcode == PPC::CMPW) {
12430 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
12434 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
12436 ValueReg = ValueSReg;
12468 .
addImm(is8bit ? 24 : 16)
12489 Register DstReg =
MI.getOperand(0).getReg();
12491 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
12492 Register mainDstReg =
MRI.createVirtualRegister(RC);
12493 Register restoreDstReg =
MRI.createVirtualRegister(RC);
12496 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
12497 "Invalid Pointer Size!");
12545 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
12546 Register BufReg =
MI.getOperand(1).getReg();
12561 BaseReg = Subtarget.
isPPC64() ? PPC::X1 : PPC::R1;
12563 BaseReg = Subtarget.
isPPC64() ? PPC::BP8 : PPC::BP;
12566 TII->get(Subtarget.
isPPC64() ? PPC::STD : PPC::STW))
12589 TII->get(Subtarget.
isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
12610 TII->get(PPC::PHI), DstReg)
12614 MI.eraseFromParent();
12628 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
12629 "Invalid Pointer Size!");
12632 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12635 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
12636 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
12650 Register BufReg =
MI.getOperand(0).getReg();
12655 if (PVT == MVT::i64) {
12667 if (PVT == MVT::i64) {
12679 if (PVT == MVT::i64) {
12691 if (PVT == MVT::i64) {
12703 if (PVT == MVT::i64 && Subtarget.
isSVR4ABI()) {
12713 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
12716 MI.eraseFromParent();
12732 "Unexpected stack alignment");
12736 unsigned StackProbeSize =
12739 StackProbeSize &= ~(StackAlign - 1);
12740 return StackProbeSize ? StackProbeSize : StackAlign;
12752 const bool isPPC64 = Subtarget.
isPPC64();
12784 MF->
insert(MBBIter, TestMBB);
12785 MF->
insert(MBBIter, BlockMBB);
12786 MF->
insert(MBBIter, TailMBB);
12791 Register DstReg =
MI.getOperand(0).getReg();
12792 Register NegSizeReg =
MI.getOperand(1).getReg();
12793 Register SPReg = isPPC64 ? PPC::X1 : PPC::R1;
12794 Register FinalStackPtr =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12795 Register FramePointer =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12796 Register ActualNegSizeReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12802 if (!
MRI.hasOneNonDBGUse(NegSizeReg))
12804 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
12810 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
12811 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
12813 .
addDef(ActualNegSizeReg)
12815 .
add(
MI.getOperand(2))
12816 .
add(
MI.getOperand(3));
12822 .
addReg(ActualNegSizeReg);
12825 int64_t NegProbeSize = -(int64_t)ProbeSize;
12826 assert(isInt<32>(NegProbeSize) &&
"Unhandled probe size!");
12827 Register ScratchReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12828 if (!isInt<16>(NegProbeSize)) {
12829 Register TempReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12831 .
addImm(NegProbeSize >> 16);
12835 .
addImm(NegProbeSize & 0xFFFF);
12842 Register Div =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12844 .
addReg(ActualNegSizeReg)
12846 Register Mul =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12850 Register NegMod =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12853 .
addReg(ActualNegSizeReg);
12862 Register CmpResult =
MRI.createVirtualRegister(&PPC::CRRCRegClass);
12863 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
12877 BuildMI(BlockMBB,
DL,
TII->get(isPPC64 ? PPC::STDUX : PPC::STWUX), SPReg)
12888 MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12890 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
12891 MaxCallFrameSizeReg)
12892 .
add(
MI.getOperand(2))
12893 .
add(
MI.getOperand(3));
12894 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
12896 .
addReg(MaxCallFrameSizeReg);
12905 MI.eraseFromParent();
12907 ++NumDynamicAllocaProbed;
12912 switch (
MI.getOpcode()) {
12913 case PPC::SELECT_CC_I4:
12914 case PPC::SELECT_CC_I8:
12915 case PPC::SELECT_CC_F4:
12916 case PPC::SELECT_CC_F8:
12917 case PPC::SELECT_CC_F16:
12918 case PPC::SELECT_CC_VRRC:
12919 case PPC::SELECT_CC_VSFRC:
12920 case PPC::SELECT_CC_VSSRC:
12921 case PPC::SELECT_CC_VSRC:
12922 case PPC::SELECT_CC_SPE4:
12923 case PPC::SELECT_CC_SPE:
12931 switch (
MI.getOpcode()) {
12932 case PPC::SELECT_I4:
12933 case PPC::SELECT_I8:
12934 case PPC::SELECT_F4:
12935 case PPC::SELECT_F8:
12936 case PPC::SELECT_F16:
12937 case PPC::SELECT_SPE:
12938 case PPC::SELECT_SPE4:
12939 case PPC::SELECT_VRRC:
12940 case PPC::SELECT_VSFRC:
12941 case PPC::SELECT_VSSRC:
12942 case PPC::SELECT_VSRC:
12952 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
12953 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
12955 MI.getOpcode() == TargetOpcode::PATCHPOINT &&
12968 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
12969 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
12971 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
12972 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
12986 if (Subtarget.hasISEL() &&
12987 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
12988 MI.getOpcode() == PPC::SELECT_CC_I8 ||
12989 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
12991 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
12992 MI.getOpcode() == PPC::SELECT_CC_I8)
12993 Cond.push_back(
MI.getOperand(4));
12996 Cond.push_back(
MI.getOperand(1));
12999 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
13000 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
13016 F->insert(It, copy0MBB);
13017 F->insert(It, sinkMBB);
13021 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
13036 .
addReg(
MI.getOperand(1).getReg())
13039 unsigned SelectPred =
MI.getOperand(4).getImm();
13042 .
addReg(
MI.getOperand(1).getReg())
13059 .
addReg(
MI.getOperand(3).getReg())
13061 .
addReg(
MI.getOperand(2).getReg())
13063 }
else if (
MI.getOpcode() == PPC::ReadTB) {
13079 F->insert(It, readMBB);
13080 F->insert(It, sinkMBB);
13101 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
13111 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
13113 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
13115 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
13117 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
13120 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
13122 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
13124 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
13126 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
13129 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
13131 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
13133 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
13135 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
13138 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
13140 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
13142 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
13144 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
13147 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
13149 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
13151 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
13153 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
13156 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
13158 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
13160 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
13162 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
13165 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
13167 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
13169 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
13171 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
13174 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
13176 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
13178 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
13180 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
13183 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
13185 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
13187 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
13189 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
13192 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
13194 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
13196 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
13198 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
13201 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
13203 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
13205 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
13207 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
13209 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
13210 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
13211 (Subtarget.hasPartwordAtomics() &&
13212 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
13213 (Subtarget.hasPartwordAtomics() &&
13214 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
13215 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
13217 auto LoadMnemonic = PPC::LDARX;
13218 auto StoreMnemonic = PPC::STDCX;
13219 switch (
MI.getOpcode()) {
13222 case PPC::ATOMIC_CMP_SWAP_I8:
13223 LoadMnemonic = PPC::LBARX;
13224 StoreMnemonic = PPC::STBCX;
13225 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13227 case PPC::ATOMIC_CMP_SWAP_I16:
13228 LoadMnemonic = PPC::LHARX;
13229 StoreMnemonic = PPC::STHCX;
13230 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13232 case PPC::ATOMIC_CMP_SWAP_I32:
13233 LoadMnemonic = PPC::LWARX;
13234 StoreMnemonic = PPC::STWCX;
13236 case PPC::ATOMIC_CMP_SWAP_I64:
13237 LoadMnemonic = PPC::LDARX;
13238 StoreMnemonic = PPC::STDCX;
13246 Register oldval =
MI.getOperand(3).getReg();
13247 Register newval =
MI.getOperand(4).getReg();
13253 F->insert(It, loop1MBB);
13254 F->insert(It, loop2MBB);
13255 F->insert(It, exitMBB);
13276 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
13302 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
13303 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
13307 bool is64bit = Subtarget.
isPPC64();
13309 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
13314 Register oldval =
MI.getOperand(3).getReg();
13315 Register newval =
MI.getOperand(4).getReg();
13321 F->insert(It, loop1MBB);
13322 F->insert(It, loop2MBB);
13323 F->insert(It, exitMBB);
13330 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13349 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13381 if (ptrA != ZeroReg) {
13383 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13392 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13393 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
13396 .
addImm(is8bit ? 28 : 27);
13397 if (!isLittleEndian)
13398 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13400 .
addImm(is8bit ? 24 : 16);
13402 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13407 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13412 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
13415 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
13422 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13426 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13429 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
13432 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
13437 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13454 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13478 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
13503 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
13511 }
else if (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
13512 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT ||
13513 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
13514 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
13515 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
13516 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
13519 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
13520 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
13524 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
13528 .
addReg(
MI.getOperand(1).getReg())
13531 MI.getOperand(0).getReg())
13532 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
13533 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
13539 MI.getOperand(0).getReg())
13541 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
13543 unsigned Imm =
MI.getOperand(1).getImm();
13546 MI.getOperand(0).getReg())
13548 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
13550 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13553 if (
MRI.use_empty(OldFPSCRReg))
13554 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
13556 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13567 unsigned Mode =
MI.getOperand(1).getImm();
13568 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
13572 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
13575 }
else if (
MI.getOpcode() == PPC::SETRND) {
13583 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
13584 if (Subtarget.hasDirectMove()) {
13585 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
13589 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
13592 if (RC == &PPC::F8RCRegClass) {
13595 "Unsupported RegClass.");
13597 StoreOp = PPC::STFD;
13602 (RegInfo.
getRegClass(DestReg) == &PPC::F8RCRegClass) &&
13603 "Unsupported RegClass.");
13636 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13639 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13653 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
13661 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
13662 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
13668 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
13675 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
13684 }
else if (
MI.getOpcode() == PPC::SETFLM) {
13688 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13689 if (
MRI.use_empty(OldFPSCRReg))
13690 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
13692 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13695 Register NewFPSCRReg =
MI.getOperand(1).getReg();
13701 }
else if (
MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
13702 MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
13704 }
else if (
MI.getOpcode() == PPC::SPLIT_QUADWORD) {
13711 .
addUse(Src, 0, PPC::sub_gp8_x1);
13714 .
addUse(Src, 0, PPC::sub_gp8_x0);
13715 }
else if (
MI.getOpcode() == PPC::LQX_PSEUDO ||
13716 MI.getOpcode() == PPC::STQX_PSEUDO) {
13722 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
13728 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
13729 :
TII->get(PPC::STQ))
13737 MI.eraseFromParent();
13750 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
13753 return RefinementSteps;
13759 EVT VT =
Op.getValueType();
13762 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
13786PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
13789 EVT VT =
Op.getValueType();
13790 if (VT != MVT::f64 &&
13791 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
13798 int Enabled,
int &RefinementSteps,
13799 bool &UseOneConstNR,
13800 bool Reciprocal)
const {
13802 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
13803 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
13804 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
13805 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
13811 UseOneConstNR = !Subtarget.needsTwoConstNR();
13819 int &RefinementSteps)
const {
13821 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
13822 (VT == MVT::f64 && Subtarget.hasFRE()) ||
13823 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
13824 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
13832unsigned PPCTargetLowering::combineRepeatedFPDivisors()
const {
13870 unsigned Bytes,
int Dist,
13880 int FI = cast<FrameIndexSDNode>(Loc)->getIndex();
13881 int BFI = cast<FrameIndexSDNode>(BaseLoc)->getIndex();
13884 if (FS != BFS || FS != (
int)Bytes)
return false;
13888 SDValue Base1 = Loc, Base2 = BaseLoc;
13889 int64_t Offset1 = 0, Offset2 = 0;
13892 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
13902 if (isGA1 && isGA2 && GV1 == GV2)
13903 return Offset1 == (Offset2 + Dist*Bytes);
13910 unsigned Bytes,
int Dist,
13913 EVT VT = LS->getMemoryVT();
13914 SDValue Loc = LS->getBasePtr();
13920 switch (
N->getConstantOperandVal(1)) {
13921 default:
return false;
13922 case Intrinsic::ppc_altivec_lvx:
13923 case Intrinsic::ppc_altivec_lvxl:
13924 case Intrinsic::ppc_vsx_lxvw4x:
13925 case Intrinsic::ppc_vsx_lxvw4x_be:
13928 case Intrinsic::ppc_vsx_lxvd2x:
13929 case Intrinsic::ppc_vsx_lxvd2x_be:
13932 case Intrinsic::ppc_altivec_lvebx:
13935 case Intrinsic::ppc_altivec_lvehx:
13938 case Intrinsic::ppc_altivec_lvewx:
13948 switch (
N->getConstantOperandVal(1)) {
13949 default:
return false;
13950 case Intrinsic::ppc_altivec_stvx:
13951 case Intrinsic::ppc_altivec_stvxl:
13952 case Intrinsic::ppc_vsx_stxvw4x:
13955 case Intrinsic::ppc_vsx_stxvd2x:
13958 case Intrinsic::ppc_vsx_stxvw4x_be:
13961 case Intrinsic::ppc_vsx_stxvd2x_be:
13964 case Intrinsic::ppc_altivec_stvebx:
13967 case Intrinsic::ppc_altivec_stvehx:
13970 case Intrinsic::ppc_altivec_stvewx:
13987 SDValue Chain = LD->getChain();
13988 EVT VT = LD->getMemoryVT();
13997 while (!Queue.empty()) {
13998 SDNode *ChainNext = Queue.pop_back_val();
13999 if (!Visited.
insert(ChainNext).second)
14002 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(ChainNext)) {
14006 if (!Visited.
count(ChainLD->getChain().getNode()))
14007 Queue.push_back(ChainLD->getChain().getNode());
14009 for (
const SDUse &O : ChainNext->
ops())
14010 if (!Visited.
count(O.getNode()))
14011 Queue.push_back(O.getNode());
14013 LoadRoots.
insert(ChainNext);
14024 for (
SDNode *
I : LoadRoots) {
14025 Queue.push_back(
I);
14027 while (!Queue.empty()) {
14028 SDNode *LoadRoot = Queue.pop_back_val();
14029 if (!Visited.
insert(LoadRoot).second)
14032 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(LoadRoot))
14037 if (((isa<MemSDNode>(U) &&
14038 cast<MemSDNode>(U)->getChain().
getNode() == LoadRoot) ||
14041 Queue.push_back(U);
14074 auto Final = Shifted;
14085 DAGCombinerInfo &DCI)
const {
14093 if (!DCI.isAfterLegalizeDAG())
14098 for (
const SDNode *U :
N->uses())
14103 auto OpSize =
N->getOperand(0).getValueSizeInBits();
14107 if (OpSize <
Size) {
14125 DAGCombinerInfo &DCI)
const {
14129 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
14140 N->getValueType(0) != MVT::i1)
14143 if (
N->getOperand(0).getValueType() != MVT::i32 &&
14144 N->getOperand(0).getValueType() != MVT::i64)
14152 cast<CondCodeSDNode>(
N->getOperand(
14154 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
14165 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
14188 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
14189 N->getOperand(0).getOpcode() !=
ISD::OR &&
14190 N->getOperand(0).getOpcode() !=
ISD::XOR &&
14200 N->getOperand(1).getOpcode() !=
ISD::AND &&
14201 N->getOperand(1).getOpcode() !=
ISD::OR &&
14202 N->getOperand(1).getOpcode() !=
ISD::XOR &&
14215 for (
unsigned i = 0; i < 2; ++i) {
14219 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
14220 isa<ConstantSDNode>(
N->getOperand(i)))
14231 while (!BinOps.
empty()) {
14239 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
14273 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14274 if (isa<ConstantSDNode>(Inputs[i]))
14297 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
14319 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14322 if (isa<ConstantSDNode>(Inputs[i]))
14328 std::list<HandleSDNode> PromOpHandles;
14329 for (
auto &PromOp : PromOps)
14330 PromOpHandles.emplace_back(PromOp);
14337 while (!PromOpHandles.empty()) {
14339 PromOpHandles.pop_back();
14345 if (!isa<ConstantSDNode>(PromOp.
getOperand(0)) &&
14348 PromOpHandles.emplace_front(PromOp);
14353 if (isa<ConstantSDNode>(RepValue))
14362 default:
C = 0;
break;
14367 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
14375 PromOpHandles.emplace_front(PromOp);
14382 for (
unsigned i = 0; i < 2; ++i)
14383 if (isa<ConstantSDNode>(Ops[
C+i]))
14392 return N->getOperand(0);
14400 DAGCombinerInfo &DCI)
const {
14418 if (
N->getValueType(0) != MVT::i32 &&
14419 N->getValueType(0) != MVT::i64)
14422 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
14423 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.
isPPC64())))
14426 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
14427 N->getOperand(0).getOpcode() !=
ISD::OR &&
14428 N->getOperand(0).getOpcode() !=
ISD::XOR &&
14439 while (!BinOps.
empty()) {
14447 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
14478 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14479 if (isa<ConstantSDNode>(Inputs[i]))
14490 SelectTruncOp[0].
insert(std::make_pair(
User,
14494 SelectTruncOp[0].
insert(std::make_pair(
User,
14497 SelectTruncOp[1].
insert(std::make_pair(
User,
14503 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
14512 SelectTruncOp[0].
insert(std::make_pair(
User,
14516 SelectTruncOp[0].
insert(std::make_pair(
User,
14519 SelectTruncOp[1].
insert(std::make_pair(
User,
14525 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
14526 bool ReallyNeedsExt =
false;
14530 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14531 if (isa<ConstantSDNode>(Inputs[i]))
14535 Inputs[i].getOperand(0).getValueSizeInBits();
14536 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
14541 OpBits-PromBits))) ||
14544 (OpBits-(PromBits-1)))) {
14545 ReallyNeedsExt =
true;
14553 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14557 if (isa<ConstantSDNode>(Inputs[i]))
14560 SDValue InSrc = Inputs[i].getOperand(0);
14574 std::list<HandleSDNode> PromOpHandles;
14575 for (
auto &PromOp : PromOps)
14576 PromOpHandles.emplace_back(PromOp);
14582 while (!PromOpHandles.empty()) {
14584 PromOpHandles.pop_back();
14588 default:
C = 0;
break;
14593 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
14601 PromOpHandles.emplace_front(PromOp);
14611 (SelectTruncOp[1].count(PromOp.
getNode()) &&
14613 PromOpHandles.emplace_front(PromOp);
14622 for (
unsigned i = 0; i < 2; ++i) {
14623 if (!isa<ConstantSDNode>(Ops[
C+i]))
14640 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
14641 if (SI0 != SelectTruncOp[0].
end())
14643 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
14644 if (SI1 != SelectTruncOp[1].
end())
14653 if (!ReallyNeedsExt)
14654 return N->getOperand(0);
14661 N->getValueSizeInBits(0), PromBits),
14662 dl,
N->getValueType(0)));
14665 "Invalid extension type");
14668 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
14676 DAGCombinerInfo &DCI)
const {
14678 "Should be called with a SETCC node");
14696 EVT VT =
N->getValueType(0);
14697 EVT OpVT =
LHS.getValueType();
14703 return DAGCombineTruncBoolExt(
N, DCI);
14708 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(
Op.getNode()))
14710 Op.getValueType() == MVT::f64;
14722combineElementTruncationToVectorTruncation(
SDNode *
N,
14723 DAGCombinerInfo &DCI)
const {
14725 "Should be called with a BUILD_VECTOR node");
14730 SDValue FirstInput =
N->getOperand(0);
14732 "The input operand must be an fp-to-int conversion.");
14741 bool IsSplat =
true;
14746 EVT TargetVT =
N->getValueType(0);
14747 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
14748 SDValue NextOp =
N->getOperand(i);
14752 if (NextConversion != FirstConversion)
14760 if (
N->getOperand(i) != FirstInput)
14771 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
14772 SDValue In =
N->getOperand(i).getOperand(0);
14795 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
14797 return DAG.
getNode(Opcode, dl, TargetVT, BV);
14810 "Should be called with a BUILD_VECTOR node");
14815 if (!
N->getValueType(0).getVectorElementType().isByteSized())
14818 bool InputsAreConsecutiveLoads =
true;
14819 bool InputsAreReverseConsecutive =
true;
14820 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
14821 SDValue FirstInput =
N->getOperand(0);
14822 bool IsRoundOfExtLoad =
false;
14827 FirstLoad = cast<LoadSDNode>(FirstInput.
getOperand(0));
14832 N->getNumOperands() == 1)
14835 if (!IsRoundOfExtLoad)
14836 FirstLoad = cast<LoadSDNode>(FirstInput);
14840 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
14842 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
14845 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
14851 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
14852 LoadSDNode *LD1 = cast<LoadSDNode>(PreviousInput);
14853 LoadSDNode *LD2 = cast<LoadSDNode>(NextInput);
14862 InputsAreConsecutiveLoads =
false;
14864 InputsAreReverseConsecutive =
false;
14867 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
14872 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
14873 "The loads cannot be both consecutive and reverse consecutive.");
14877 if (InputsAreConsecutiveLoads) {
14878 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
14882 ReturnSDVal = WideLoad;
14883 }
else if (InputsAreReverseConsecutive) {
14885 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
14890 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
14894 DAG.
getUNDEF(
N->getValueType(0)), Ops);
14898 for (
auto *LD : InputLoads)
14900 return ReturnSDVal;
14917 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
14919 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
14921 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
14922 CorrectElems = CorrectElems >> 8;
14923 Elems = Elems >> 8;
14930 EVT VT =
N->getValueType(0);
14968 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
14988 if (Input && Input != Extract.
getOperand(0))
14994 Elems = Elems << 8;
15003 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
15004 if (!isSExtOfVecExtract(
N->getOperand(i))) {
15011 int TgtElemArrayIdx;
15013 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
15014 if (InputSize + OutputSize == 40)
15015 TgtElemArrayIdx = 0;
15016 else if (InputSize + OutputSize == 72)
15017 TgtElemArrayIdx = 1;
15018 else if (InputSize + OutputSize == 48)
15019 TgtElemArrayIdx = 2;
15020 else if (InputSize + OutputSize == 80)
15021 TgtElemArrayIdx = 3;
15022 else if (InputSize + OutputSize == 96)
15023 TgtElemArrayIdx = 4;
15027 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
15029 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
15030 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
15031 if (Elems != CorrectElems) {
15047 if (
N->getValueType(0) != MVT::v1i128)
15050 SDValue Operand =
N->getOperand(0);
15056 auto *LD = cast<LoadSDNode>(Operand);
15057 EVT MemoryType = LD->getMemoryVT();
15061 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
15062 MemoryType == MVT::i32 || MemoryType == MVT::i64;
15065 if (!ValidLDType ||
15071 LD->getChain(), LD->getBasePtr(),
15075 DAG.
getVTList(MVT::v1i128, MVT::Other),
15076 LoadOps, MemoryType, LD->getMemOperand());
15080 DAGCombinerInfo &DCI)
const {
15082 "Should be called with a BUILD_VECTOR node");
15087 if (!Subtarget.hasVSX())
15093 SDValue FirstInput =
N->getOperand(0);
15095 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
15110 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
15119 if (Subtarget.isISA3_1()) {
15125 if (
N->getValueType(0) != MVT::v2f64)
15136 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
15140 SDValue Ext2 =
N->getOperand(1).getOperand(0);
15147 if (!Ext1Op || !Ext2Op)
15156 if (FirstElem == 0 && SecondElem == 1)
15158 else if (FirstElem == 2 && SecondElem == 3)
15166 return DAG.
getNode(NodeType, dl, MVT::v2f64,
15171 DAGCombinerInfo &DCI)
const {
15174 "Need an int -> FP conversion node here");
15185 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
15187 if (!
Op.getOperand(0).getValueType().isSimple())
15189 if (
Op.getOperand(0).getValueType().getSimpleVT() <=
MVT(MVT::i1) ||
15190 Op.getOperand(0).getValueType().getSimpleVT() >
MVT(MVT::i64))
15193 SDValue FirstOperand(
Op.getOperand(0));
15194 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
15195 (FirstOperand.getValueType() == MVT::i8 ||
15196 FirstOperand.getValueType() == MVT::i16);
15197 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
15199 bool DstDouble =
Op.getValueType() == MVT::f64;
15200 unsigned ConvOp =
Signed ?
15206 LoadSDNode *LDN = cast<LoadSDNode>(FirstOperand.getNode());
15215 SDValue ExtOps[] = { Ld, WidthConst };
15217 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
15219 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
15227 if (
Op.getOperand(0).getValueType() == MVT::i32)
15231 "UINT_TO_FP is supported only with FPCVT");
15235 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
15240 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
15247 Subtarget.hasFPCVT()) ||
15249 SDValue Src =
Op.getOperand(0).getOperand(0);
15250 if (Src.getValueType() == MVT::f32) {
15252 DCI.AddToWorklist(Src.getNode());
15253 }
else if (Src.getValueType() != MVT::f64) {
15265 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
15268 DCI.AddToWorklist(
FP.getNode());
15292 switch (
N->getOpcode()) {
15297 Chain = LD->getChain();
15298 Base = LD->getBasePtr();
15299 MMO = LD->getMemOperand();
15318 MVT VecTy =
N->getValueType(0).getSimpleVT();
15326 Chain = Load.getValue(1);
15332 if (VecTy != MVT::v2f64) {
15359 switch (
N->getOpcode()) {
15364 Chain = ST->getChain();
15365 Base = ST->getBasePtr();
15366 MMO = ST->getMemOperand();
15386 SDValue Src =
N->getOperand(SrcOpnd);
15387 MVT VecTy = Src.getValueType().getSimpleVT();
15390 if (VecTy != MVT::v2f64) {
15396 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
15402 StoreOps, VecTy, MMO);
15409 DAGCombinerInfo &DCI)
const {
15412 unsigned Opcode =
N->getOperand(1).getOpcode();
15414 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
15418 &&
"Not a FP_TO_INT Instruction!");
15420 SDValue Val =
N->getOperand(1).getOperand(Strict ? 1 : 0);
15421 EVT Op1VT =
N->getOperand(1).getValueType();
15424 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
15428 bool ValidTypeForStoreFltAsInt =
15429 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.
isPPC64()) ||
15430 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
15433 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
15436 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
15437 cast<StoreSDNode>(
N)->isTruncatingStore() || !ValidTypeForStoreFltAsInt)
15444 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
15450 cast<StoreSDNode>(
N)->getMemoryVT(),
15451 cast<StoreSDNode>(
N)->getMemOperand());
15459 bool PrevElemFromFirstVec = Mask[0] < NumElts;
15460 for (
int i = 1, e = Mask.size(); i < e; i++) {
15461 if (PrevElemFromFirstVec && Mask[i] < NumElts)
15463 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
15465 PrevElemFromFirstVec = !PrevElemFromFirstVec;
15477 FirstOp =
Op.getOperand(i);
15484 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
15494 Op =
Op.getOperand(0);
15509 int LHSMaxIdx,
int RHSMinIdx,
15510 int RHSMaxIdx,
int HalfVec,
15511 unsigned ValidLaneWidth,
15513 for (
int i = 0, e = ShuffV.
size(); i < e; i++) {
15514 int Idx = ShuffV[i];
15515 if ((
Idx >= 0 &&
Idx < LHSMaxIdx) || (
Idx >= RHSMinIdx &&
Idx < RHSMaxIdx))
15517 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - ValidLaneWidth;
15528 SDLoc dl(OrigSToV);
15531 "Expecting a SCALAR_TO_VECTOR here");
15544 "Cannot produce a permuted scalar_to_vector for one element vector");
15546 unsigned ResultInElt = NumElts / 2;
15548 NewMask[ResultInElt] =
Idx->getZExtValue();
15573 int NumElts =
LHS.getValueType().getVectorNumElements();
15583 if (!Subtarget.hasDirectMove())
15593 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
15602 if (SToVLHS || SToVRHS) {
15609 if (SToVLHS && SToVRHS &&
15616 int NumEltsOut = ShuffV.
size();
15621 unsigned ValidLaneWidth =
15623 LHS.getValueType().getScalarSizeInBits()
15625 RHS.getValueType().getScalarSizeInBits();
15629 int LHSMaxIdx = -1;
15630 int RHSMinIdx = -1;
15631 int RHSMaxIdx = -1;
15632 int HalfVec =
LHS.getValueType().getVectorNumElements() / 2;
15644 LHSMaxIdx = NumEltsOut / NumEltsIn;
15653 RHSMinIdx = NumEltsOut;
15654 RHSMaxIdx = NumEltsOut / NumEltsIn + RHSMinIdx;
15667 HalfVec, ValidLaneWidth, Subtarget);
15672 if (!isa<ShuffleVectorSDNode>(Res))
15674 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
15693 if (IsLittleEndian) {
15696 if (Mask[0] < NumElts)
15697 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
15701 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
15706 for (
int i = 0, e =
Mask.size(); i <
e; i += 2) {
15710 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
15715 if (Mask[0] < NumElts)
15716 for (
int i = 0, e =
Mask.size(); i <
e; i += 2) {
15720 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
15725 for (
int i = 1, e =
Mask.size(); i <
e; i += 2) {
15729 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
15736 cast<BuildVectorSDNode>(TheSplat.
getNode())->getSplatValue();
15739 if (IsLittleEndian)
15748 DAGCombinerInfo &DCI)
const {
15750 "Not a reverse memop pattern!");
15755 auto I =
Mask.rbegin();
15756 auto E =
Mask.rend();
15758 for (;
I != E; ++
I) {
15775 if (!Subtarget.hasP9Vector())
15778 if(!IsElementReverse(SVN))
15817 if (IntrinsicID == Intrinsic::ppc_stdcx)
15819 else if (IntrinsicID == Intrinsic::ppc_stwcx)
15821 else if (IntrinsicID == Intrinsic::ppc_sthcx)
15823 else if (IntrinsicID == Intrinsic::ppc_stbcx)
15834 switch (
N->getOpcode()) {
15837 return combineADD(
N, DCI);
15846 !isa<ConstantSDNode>(Op2) ||
N->getValueType(0) != MVT::i64 ||
15856 if (!isUInt<32>(Imm))
15863 return combineSHL(
N, DCI);
15865 return combineSRA(
N, DCI);
15867 return combineSRL(
N, DCI);
15869 return combineMUL(
N, DCI);
15872 return combineFMALike(
N, DCI);
15875 return N->getOperand(0);
15879 return N->getOperand(0);
15885 return N->getOperand(0);
15891 return DAGCombineExtBoolTrunc(
N, DCI);
15893 return combineTRUNCATE(
N, DCI);
15895 if (
SDValue CSCC = combineSetCC(
N, DCI))
15899 return DAGCombineTruncBoolExt(
N, DCI);
15902 return combineFPToIntToFP(
N, DCI);
15905 LSBaseSDNode* LSBase = cast<LSBaseSDNode>(
N->getOperand(0));
15906 return combineVReverseMemOP(cast<ShuffleVectorSDNode>(
N), LSBase, DCI);
15908 return combineVectorShuffle(cast<ShuffleVectorSDNode>(
N), DCI.
DAG);
15911 EVT Op1VT =
N->getOperand(1).getValueType();
15912 unsigned Opcode =
N->getOperand(1).getOpcode();
15916 SDValue Val = combineStoreFPToInt(
N, DCI);
15923 SDValue Val= combineVReverseMemOP(SVN, cast<LSBaseSDNode>(
N), DCI);
15929 if (cast<StoreSDNode>(
N)->isUnindexed() && Opcode ==
ISD::BSWAP &&
15930 N->getOperand(1).getNode()->hasOneUse() &&
15931 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
15932 (Subtarget.hasLDBRX() && Subtarget.
isPPC64() && Op1VT == MVT::i64))) {
15936 EVT mVT = cast<StoreSDNode>(
N)->getMemoryVT();
15940 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
15947 if (Op1VT.
bitsGT(mVT)) {
15952 if (Op1VT == MVT::i64)
15957 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
15961 Ops, cast<StoreSDNode>(
N)->getMemoryVT(),
15962 cast<StoreSDNode>(
N)->getMemOperand());
15968 isa<ConstantSDNode>(
N->getOperand(1)) && Op1VT == MVT::i32) {
15970 EVT MemVT = cast<StoreSDNode>(
N)->getMemoryVT();
15980 cast<StoreSDNode>(
N)->setTruncatingStore(
true);
15989 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
15990 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
15997 EVT VT = LD->getValueType(0);
16004 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
16005 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
16016 auto ReplaceTwoFloatLoad = [&]() {
16017 if (VT != MVT::i64)
16032 if (!LD->hasNUsesOfValue(2, 0))
16035 auto UI = LD->use_begin();
16036 while (UI.getUse().getResNo() != 0) ++UI;
16038 while (UI.getUse().getResNo() != 0) ++UI;
16039 SDNode *RightShift = *UI;
16047 if (RightShift->getOpcode() !=
ISD::SRL ||
16048 !isa<ConstantSDNode>(RightShift->getOperand(1)) ||
16049 RightShift->getConstantOperandVal(1) != 32 ||
16050 !RightShift->hasOneUse())
16053 SDNode *Trunc2 = *RightShift->use_begin();
16063 Bitcast->getValueType(0) != MVT::f32)
16075 SDValue BasePtr = LD->getBasePtr();
16076 if (LD->isIndexed()) {
16078 "Non-pre-inc AM on PPC?");
16086 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
16087 LD->getPointerInfo(), LD->getAlign(),
16088 MMOFlags, LD->getAAInfo());
16094 LD->getPointerInfo().getWithOffset(4),
16097 if (LD->isIndexed()) {
16111 if (ReplaceTwoFloatLoad())
16114 EVT MemVT = LD->getMemoryVT();
16117 if (LD->isUnindexed() && VT.
isVector() &&
16120 !Subtarget.hasP8Vector() &&
16121 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
16122 VT == MVT::v4f32))) &&
16123 LD->getAlign() < ABIAlignment) {
16125 SDValue Chain = LD->getChain();
16154 MVT PermCntlTy, PermTy, LDTy;
16155 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
16156 : Intrinsic::ppc_altivec_lvsl;
16157 IntrLD = Intrinsic::ppc_altivec_lvx;
16158 IntrPerm = Intrinsic::ppc_altivec_vperm;
16159 PermCntlTy = MVT::v16i8;
16160 PermTy = MVT::v4i32;
16179 SDValue BaseLoadOps[] = { Chain, LDXIntID,
Ptr };
16183 BaseLoadOps, LDTy, BaseMMO);
16192 int IncValue = IncOffset;
16209 SDValue ExtraLoadOps[] = { Chain, LDXIntID,
Ptr };
16213 ExtraLoadOps, LDTy, ExtraMMO);
16224 if (isLittleEndian)
16226 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
16229 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
16232 Perm = Subtarget.hasAltivec()
16248 unsigned IID =
N->getConstantOperandVal(0);
16250 : Intrinsic::ppc_altivec_lvsl);
16251 if (IID ==
Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
16258 .
zext(
Add.getScalarValueSizeInBits()))) {
16259 SDNode *BasePtr =
Add->getOperand(0).getNode();
16260 for (
SDNode *U : BasePtr->uses()) {
16262 U->getConstantOperandVal(0) == IID) {
16272 if (isa<ConstantSDNode>(
Add->getOperand(1))) {
16273 SDNode *BasePtr =
Add->getOperand(0).getNode();
16274 for (
SDNode *U : BasePtr->uses()) {
16276 isa<ConstantSDNode>(U->getOperand(1)) &&
16277 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
16283 V->getConstantOperandVal(0) == IID) {
16295 (IID == Intrinsic::ppc_altivec_vmaxsw ||
16296 IID == Intrinsic::ppc_altivec_vmaxsh ||
16297 IID == Intrinsic::ppc_altivec_vmaxsb)) {
16313 V2.getOperand(1) == V1) {
16328 switch (
N->getConstantOperandVal(1)) {
16331 case Intrinsic::ppc_altivec_vsum4sbs:
16332 case Intrinsic::ppc_altivec_vsum4shs:
16333 case Intrinsic::ppc_altivec_vsum4ubs: {
16339 dyn_cast<BuildVectorSDNode>(
N->getOperand(3))) {
16340 APInt APSplatBits, APSplatUndef;
16341 unsigned SplatBitSize;
16344 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
16347 if (BVNIsConstantSplat && APSplatBits == 0)
16352 case Intrinsic::ppc_vsx_lxvw4x:
16353 case Intrinsic::ppc_vsx_lxvd2x:
16365 switch (
N->getConstantOperandVal(1)) {
16368 case Intrinsic::ppc_vsx_stxvw4x:
16369 case Intrinsic::ppc_vsx_stxvd2x:
16378 bool Is64BitBswapOn64BitTgt =
16379 Subtarget.
isPPC64() &&
N->getValueType(0) == MVT::i64;
16381 N->getOperand(0).hasOneUse();
16382 if (IsSingleUseNormalLd &&
16383 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
16384 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
16395 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
16396 MVT::i64 : MVT::i32, MVT::Other),
16397 Ops, LD->getMemoryVT(), LD->getMemOperand());
16401 if (
N->getValueType(0) == MVT::i16)
16418 !IsSingleUseNormalLd)
16420 LoadSDNode *LD = cast<LoadSDNode>(
N->getOperand(0));
16423 if (!LD->isSimple())
16425 SDValue BasePtr = LD->getBasePtr();
16427 LD->getPointerInfo(), LD->getAlign());
16432 LD->getMemOperand(), 4, 4);
16442 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
16451 if (!
N->getOperand(0).hasOneUse() &&
16452 !
N->getOperand(1).hasOneUse() &&
16453 !
N->getOperand(2).hasOneUse()) {
16456 SDNode *VCMPrecNode =
nullptr;
16458 SDNode *LHSN =
N->getOperand(0).getNode();
16462 UI->getOperand(1) ==
N->getOperand(1) &&
16463 UI->getOperand(2) ==
N->getOperand(2) &&
16464 UI->getOperand(0) ==
N->getOperand(0)) {
16477 SDNode *FlagUser =
nullptr;
16479 FlagUser ==
nullptr; ++UI) {
16480 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
16493 return SDValue(VCMPrecNode, 0);
16515 auto RHSAPInt =
RHS->getAsAPIntVal();
16516 if (!RHSAPInt.isIntN(64))
16519 unsigned Val = RHSAPInt.getZExtValue();
16520 auto isImpossibleCompare = [&]() {
16523 if (Val != 0 && Val != 1) {
16525 return N->getOperand(0);
16528 N->getOperand(0),
N->getOperand(4));
16533 unsigned StoreWidth = 0;
16536 if (
SDValue Impossible = isImpossibleCompare())
16550 auto *MemNode = cast<MemSDNode>(
LHS);
16553 DAG.
getVTList(MVT::i32, MVT::Other, MVT::Glue), Ops,
16554 MemNode->getMemoryVT(), MemNode->getMemOperand());
16558 if (
N->getOperand(0) ==
LHS.getValue(1))
16559 InChain =
LHS.getOperand(0);
16571 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
16577 assert(isDot &&
"Can't compare against a vector result!");
16579 if (
SDValue Impossible = isImpossibleCompare())
16582 bool BranchOnWhenPredTrue = (
CC ==
ISD::SETEQ) ^ (Val == 0);
16589 EVT VTs[] = {
LHS.getOperand(2).getValueType(), MVT::Glue };
16594 switch (
LHS.getConstantOperandVal(1)) {
16613 N->getOperand(4), CompNode.
getValue(1));
16618 return DAGCombineBuildVector(
N, DCI);
16629 EVT VT =
N->getValueType(0);
16630 if (VT == MVT::i64 && !Subtarget.
isPPC64())
16632 if ((VT != MVT::i32 && VT != MVT::i64) ||
16640 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
16660 const APInt &DemandedElts,
16662 unsigned Depth)
const {
16664 switch (
Op.getOpcode()) {
16668 if (cast<VTSDNode>(
Op.getOperand(2))->getVT() == MVT::i16)
16669 Known.
Zero = 0xFFFF0000;
16673 switch (
Op.getConstantOperandVal(0)) {
16675 case Intrinsic::ppc_altivec_vcmpbfp_p:
16676 case Intrinsic::ppc_altivec_vcmpeqfp_p:
16677 case Intrinsic::ppc_altivec_vcmpequb_p:
16678 case Intrinsic::ppc_altivec_vcmpequh_p:
16679 case Intrinsic::ppc_altivec_vcmpequw_p:
16680 case Intrinsic::ppc_altivec_vcmpequd_p:
16681 case Intrinsic::ppc_altivec_vcmpequq_p:
16682 case Intrinsic::ppc_altivec_vcmpgefp_p:
16683 case Intrinsic::ppc_altivec_vcmpgtfp_p:
16684 case Intrinsic::ppc_altivec_vcmpgtsb_p:
16685 case Intrinsic::ppc_altivec_vcmpgtsh_p:
16686 case Intrinsic::ppc_altivec_vcmpgtsw_p:
16687 case Intrinsic::ppc_altivec_vcmpgtsd_p:
16688 case Intrinsic::ppc_altivec_vcmpgtsq_p:
16689 case Intrinsic::ppc_altivec_vcmpgtub_p:
16690 case Intrinsic::ppc_altivec_vcmpgtuh_p:
16691 case Intrinsic::ppc_altivec_vcmpgtuw_p:
16692 case Intrinsic::ppc_altivec_vcmpgtud_p:
16693 case Intrinsic::ppc_altivec_vcmpgtuq_p:
16700 switch (
Op.getConstantOperandVal(1)) {
16703 case Intrinsic::ppc_load2r:
16705 Known.
Zero = 0xFFFF0000;
16736 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
16745 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
16747 LoopSize +=
TII->getInstSizeInBytes(J);
16752 if (LoopSize > 16 && LoopSize <= 32)
16766 if (Constraint.
size() == 1) {
16767 switch (Constraint[0]) {
16785 }
else if (Constraint ==
"wc") {
16787 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
16788 Constraint ==
"wf" || Constraint ==
"ws" ||
16789 Constraint ==
"wi" || Constraint ==
"ww") {
16802 Value *CallOperandVal =
info.CallOperandVal;
16805 if (!CallOperandVal)
16812 else if ((
StringRef(constraint) ==
"wa" ||
16824 switch (*constraint) {
16854std::pair<unsigned, const TargetRegisterClass *>
16858 if (Constraint.
size() == 1) {
16860 switch (Constraint[0]) {
16862 if (VT == MVT::i64 && Subtarget.
isPPC64())
16863 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
16864 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
16866 if (VT == MVT::i64 && Subtarget.
isPPC64())
16867 return std::make_pair(0U, &PPC::G8RCRegClass);
16868 return std::make_pair(0U, &PPC::GPRCRegClass);
16874 if (Subtarget.hasSPE()) {
16875 if (VT == MVT::f32 || VT == MVT::i32)
16876 return std::make_pair(0U, &PPC::GPRCRegClass);
16877 if (VT == MVT::f64 || VT == MVT::i64)
16878 return std::make_pair(0U, &PPC::SPERCRegClass);
16880 if (VT == MVT::f32 || VT == MVT::i32)
16881 return std::make_pair(0U, &PPC::F4RCRegClass);
16882 if (VT == MVT::f64 || VT == MVT::i64)
16883 return std::make_pair(0U, &PPC::F8RCRegClass);
16887 if (Subtarget.hasAltivec() && VT.
isVector())
16888 return std::make_pair(0U, &PPC::VRRCRegClass);
16889 else if (Subtarget.hasVSX())
16891 return std::make_pair(0U, &PPC::VFRCRegClass);
16894 return std::make_pair(0U, &PPC::CRRCRegClass);
16896 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
16898 return std::make_pair(0U, &PPC::CRBITRCRegClass);
16899 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
16900 Constraint ==
"wf" || Constraint ==
"wi") &&
16901 Subtarget.hasVSX()) {
16905 return std::make_pair(0U, &PPC::VSRCRegClass);
16906 if (VT == MVT::f32 && Subtarget.hasP8Vector())
16907 return std::make_pair(0U, &PPC::VSSRCRegClass);
16908 return std::make_pair(0U, &PPC::VSFRCRegClass);
16909 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
16910 if (VT == MVT::f32 && Subtarget.hasP8Vector())
16911 return std::make_pair(0U, &PPC::VSSRCRegClass);
16913 return std::make_pair(0U, &PPC::VSFRCRegClass);
16914 }
else if (Constraint ==
"lr") {
16915 if (VT == MVT::i64)
16916 return std::make_pair(0U, &PPC::LR8RCRegClass);
16918 return std::make_pair(0U, &PPC::LRRCRegClass);
16923 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
16927 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
16928 int VSNum = atoi(Constraint.
data() + 3);
16929 assert(VSNum >= 0 && VSNum <= 63 &&
16930 "Attempted to access a vsr out of range");
16932 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
16933 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
16938 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
16939 int RegNum = atoi(Constraint.
data() + 2);
16940 if (RegNum > 31 || RegNum < 0)
16942 if (VT == MVT::f32 || VT == MVT::i32)
16943 return Subtarget.hasSPE()
16944 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
16945 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
16946 if (VT == MVT::f64 || VT == MVT::i64)
16947 return Subtarget.hasSPE()
16948 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
16949 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
16953 std::pair<unsigned, const TargetRegisterClass *> R =
16962 if (R.first && VT == MVT::i64 && Subtarget.
isPPC64() &&
16963 PPC::GPRCRegClass.contains(R.first))
16964 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
16965 PPC::sub_32, &PPC::G8RCRegClass),
16966 &PPC::G8RCRegClass);
16969 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
16970 R.first = PPC::CR0;
16971 R.second = &PPC::CRRCRegClass;
16975 if (Subtarget.
isAIXABI() && !TM.getAIXExtendedAltivecABI()) {
16976 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
16977 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
16978 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
16979 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
16980 "default AIX AltiVec ABI and cannot be used\n";
16990 std::vector<SDValue> &Ops,
16995 if (Constraint.
size() > 1)
16998 char Letter = Constraint[0];
17013 EVT TCVT = MVT::i64;
17018 if (isInt<16>(
Value))
17022 if (isShiftedUInt<16, 16>(
Value))
17026 if (isShiftedInt<16, 16>(
Value))
17030 if (isUInt<16>(
Value))
17046 if (isInt<16>(-
Value))
17054 if (Result.getNode()) {
17055 Ops.push_back(Result);
17066 if (
I.getNumOperands() <= 1)
17068 if (!isa<ConstantSDNode>(Ops[1].
getNode()))
17070 auto IntrinsicID = Ops[1].getNode()->getAsZExtVal();
17071 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
17072 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
17075 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
17103 switch (AM.
Scale) {
17134 unsigned Depth =
Op.getConstantOperandVal(0);
17140 bool isPPC64 = Subtarget.
isPPC64();
17152 isPPC64 ? MVT::i64 : MVT::i32);
17159 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
17167 unsigned Depth =
Op.getConstantOperandVal(0);
17174 bool isPPC64 = PtrVT == MVT::i64;
17180 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
17182 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
17196 bool isPPC64 = Subtarget.
isPPC64();
17230 if (isa<JumpTableSDNode>(GA) || isa<BlockAddressSDNode>(GA))
17248 unsigned Intrinsic)
const {
17249 switch (Intrinsic) {
17250 case Intrinsic::ppc_atomicrmw_xchg_i128:
17251 case Intrinsic::ppc_atomicrmw_add_i128:
17252 case Intrinsic::ppc_atomicrmw_sub_i128:
17253 case Intrinsic::ppc_atomicrmw_nand_i128:
17254 case Intrinsic::ppc_atomicrmw_and_i128:
17255 case Intrinsic::ppc_atomicrmw_or_i128:
17256 case Intrinsic::ppc_atomicrmw_xor_i128:
17257 case Intrinsic::ppc_cmpxchg_i128:
17259 Info.memVT = MVT::i128;
17260 Info.ptrVal =
I.getArgOperand(0);
17266 case Intrinsic::ppc_atomic_load_i128:
17268 Info.memVT = MVT::i128;
17269 Info.ptrVal =
I.getArgOperand(0);
17274 case Intrinsic::ppc_atomic_store_i128:
17276 Info.memVT = MVT::i128;
17277 Info.ptrVal =
I.getArgOperand(2);
17282 case Intrinsic::ppc_altivec_lvx:
17283 case Intrinsic::ppc_altivec_lvxl:
17284 case Intrinsic::ppc_altivec_lvebx:
17285 case Intrinsic::ppc_altivec_lvehx:
17286 case Intrinsic::ppc_altivec_lvewx:
17287 case Intrinsic::ppc_vsx_lxvd2x:
17288 case Intrinsic::ppc_vsx_lxvw4x:
17289 case Intrinsic::ppc_vsx_lxvd2x_be:
17290 case Intrinsic::ppc_vsx_lxvw4x_be:
17291 case Intrinsic::ppc_vsx_lxvl:
17292 case Intrinsic::ppc_vsx_lxvll: {
17294 switch (Intrinsic) {
17295 case Intrinsic::ppc_altivec_lvebx:
17298 case Intrinsic::ppc_altivec_lvehx:
17301 case Intrinsic::ppc_altivec_lvewx:
17304 case Intrinsic::ppc_vsx_lxvd2x:
17305 case Intrinsic::ppc_vsx_lxvd2x_be:
17315 Info.ptrVal =
I.getArgOperand(0);
17322 case Intrinsic::ppc_altivec_stvx:
17323 case Intrinsic::ppc_altivec_stvxl:
17324 case Intrinsic::ppc_altivec_stvebx:
17325 case Intrinsic::ppc_altivec_stvehx:
17326 case Intrinsic::ppc_altivec_stvewx:
17327 case Intrinsic::ppc_vsx_stxvd2x:
17328 case Intrinsic::ppc_vsx_stxvw4x:
17329 case Intrinsic::ppc_vsx_stxvd2x_be:
17330 case Intrinsic::ppc_vsx_stxvw4x_be:
17331 case Intrinsic::ppc_vsx_stxvl:
17332 case Intrinsic::ppc_vsx_stxvll: {
17334 switch (Intrinsic) {
17335 case Intrinsic::ppc_altivec_stvebx:
17338 case Intrinsic::ppc_altivec_stvehx:
17341 case Intrinsic::ppc_altivec_stvewx:
17344 case Intrinsic::ppc_vsx_stxvd2x:
17345 case Intrinsic::ppc_vsx_stxvd2x_be:
17355 Info.ptrVal =
I.getArgOperand(1);
17362 case Intrinsic::ppc_stdcx:
17363 case Intrinsic::ppc_stwcx:
17364 case Intrinsic::ppc_sthcx:
17365 case Intrinsic::ppc_stbcx: {
17367 auto Alignment =
Align(8);
17368 switch (Intrinsic) {
17369 case Intrinsic::ppc_stdcx:
17372 case Intrinsic::ppc_stwcx:
17374 Alignment =
Align(4);
17376 case Intrinsic::ppc_sthcx:
17378 Alignment =
Align(2);
17380 case Intrinsic::ppc_stbcx:
17382 Alignment =
Align(1);
17387 Info.ptrVal =
I.getArgOperand(0);
17389 Info.align = Alignment;
17407 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
17408 if (
Op.isMemset() && Subtarget.hasVSX()) {
17413 if (TailSize > 2 && TailSize <= 4) {
17418 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
17437 return !(BitSize == 0 || BitSize > 64);
17445 return NumBits1 == 64 && NumBits2 == 32;
17453 return NumBits1 == 64 && NumBits2 == 32;
17459 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(Val)) {
17460 EVT MemVT = LD->getMemoryVT();
17461 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
17462 (Subtarget.
isPPC64() && MemVT == MVT::i32)) &&
17478 "invalid fpext types");
17480 if (DestVT == MVT::f128)
17486 return isInt<16>(Imm) || isUInt<16>(Imm);
17490 return isInt<16>(Imm) || isUInt<16>(Imm);
17495 unsigned *
Fast)
const {
17509 !Subtarget.allowsUnalignedFPAccess())
17513 if (Subtarget.hasVSX()) {
17514 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
17515 VT != MVT::v4f32 && VT != MVT::v4i32)
17522 if (VT == MVT::ppcf128)
17536 if (
auto *ConstNode = dyn_cast<ConstantSDNode>(
C.getNode())) {
17537 if (!ConstNode->getAPIntValue().isSignedIntN(64))
17545 int64_t Imm = ConstNode->getSExtValue();
17546 unsigned Shift = llvm::countr_zero<uint64_t>(Imm);
17548 if (isInt<16>(Imm))
17573 return Subtarget.hasP9Vector();
17581 if (!
I->hasOneUse())
17585 assert(
User &&
"A single use instruction with no uses.");
17587 switch (
I->getOpcode()) {
17588 case Instruction::FMul: {
17590 if (
User->getOpcode() != Instruction::FSub &&
17591 User->getOpcode() != Instruction::FAdd)
17604 case Instruction::Load: {
17617 if (
User->getOpcode() != Instruction::Store)
17637 static const MCPhysReg ScratchRegs[] = {
17638 PPC::X12, PPC::LR8, PPC::CTR8, 0
17641 return ScratchRegs;
17645 const Constant *PersonalityFn)
const {
17646 return Subtarget.
isPPC64() ? PPC::X3 : PPC::R3;
17650 const Constant *PersonalityFn)
const {
17651 return Subtarget.
isPPC64() ? PPC::X4 : PPC::R4;
17656 EVT VT ,
unsigned DefinedValues)
const {
17657 if (VT == MVT::v2i64)
17658 return Subtarget.hasDirectMove();
17660 if (Subtarget.hasVSX())
17694 bool LegalOps,
bool OptForSize,
17696 unsigned Depth)
const {
17700 unsigned Opc =
Op.getOpcode();
17701 EVT VT =
Op.getValueType();
17726 if (Flags.hasNoSignedZeros() ||
Options.NoSignedZerosFPMath) {
17730 N0Cost,
Depth + 1);
17734 N1Cost,
Depth + 1);
17736 if (NegN0 && N0Cost <= N1Cost) {
17737 Cost = std::min(N0Cost, N2Cost);
17738 return DAG.
getNode(Opc, Loc, VT, NegN0, N1, NegN2, Flags);
17739 }
else if (NegN1) {
17740 Cost = std::min(N1Cost, N2Cost);
17741 return DAG.
getNode(Opc, Loc, VT, N0, NegN1, NegN2, Flags);
17784 bool ForCodeSize)
const {
17785 if (!VT.
isSimple() || !Subtarget.hasVSX())
17795 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
17800 APSInt IntResult(16,
false);
17805 if (IsExact && IntResult <= 15 && IntResult >= -16)
17807 return Imm.isZero();
17810 return Imm.isPosZero();
17822 unsigned Opcode =
N->getOpcode();
17823 unsigned TargetOpcode;
17842 if (Mask->getZExtValue() == OpSizeInBits - 1)
17848SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17854 if (!Subtarget.isISA3_0() || !Subtarget.
isPPC64() ||
17857 N->getValueType(0) != MVT::i64)
17872 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
17878SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17885SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17904 auto isZextOfCompareWithConstant = [](
SDValue Op) {
17906 Op.getValueType() != MVT::i64)
17910 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
17911 Cmp.getOperand(0).getValueType() != MVT::i64)
17914 if (
auto *
Constant = dyn_cast<ConstantSDNode>(Cmp.getOperand(1))) {
17915 int64_t NegConstant = 0 -
Constant->getSExtValue();
17918 return isInt<16>(NegConstant);
17924 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
17925 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
17928 if (LHSHasPattern && !RHSHasPattern)
17930 else if (!LHSHasPattern && !RHSHasPattern)
17936 SDValue Z = Cmp.getOperand(0);
17937 auto *
Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
17938 int64_t NegConstant = 0 -
Constant->getSExtValue();
17940 switch(cast<CondCodeSDNode>(Cmp.getOperand(2))->get()) {
17951 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
17966 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
18003 if (!GSDN || !ConstNode)
18010 if (!isInt<34>(NewOffset))
18023SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18043 DAGCombinerInfo &DCI)
const {
18045 if (Subtarget.useCRBits()) {
18047 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
18048 return CRTruncValue;
18055 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
18058 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
18068 EltToExtract = EltToExtract ? 0 : 1;
18078 return DCI.DAG.getNode(
18080 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
18085SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18089 if (!ConstOpOrElement)
18097 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne,
EVT VT) ->
bool {
18121 return IsAddOne && IsNeg ? VT.
isVector() :
true;
18125 EVT VT =
N->getValueType(0);
18132 if ((MulAmtAbs - 1).isPowerOf2()) {
18136 if (!IsProfitable(IsNeg,
true, VT))
18149 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
18153 if (!IsProfitable(IsNeg,
false, VT))
18174 DAGCombinerInfo &DCI)
const {
18179 EVT VT =
N->getValueType(0);
18182 unsigned Opc =
N->getOpcode();
18184 bool LegalOps = !DCI.isBeforeLegalizeOps();
18192 if (!
Flags.hasNoSignedZeros() && !
Options.NoSignedZerosFPMath)
18208bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
18225 if (!Callee ||
Callee->isVarArg())
18238bool PPCTargetLowering::
18239isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
18242 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(Mask)) {
18244 if (CI->getBitWidth() > 64)
18246 int64_t ConstVal = CI->getZExtValue();
18247 return isUInt<16>(ConstVal) ||
18248 (isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
18257PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
18263 if ((Flags & FlagSet) == FlagSet)
18266 if ((Flags & FlagSet) == FlagSet)
18269 if ((Flags & FlagSet) == FlagSet)
18272 if ((Flags & FlagSet) == FlagSet)
18293 if ((FrameIndexAlign % 4) != 0)
18294 FlagSet &= ~PPC::MOF_RPlusSImm16Mult4;
18295 if ((FrameIndexAlign % 16) != 0)
18296 FlagSet &= ~PPC::MOF_RPlusSImm16Mult16;
18300 if ((FrameIndexAlign % 4) == 0)
18302 if ((FrameIndexAlign % 16) == 0)
18315 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
18316 if ((Imm & 0x3) == 0)
18318 if ((Imm & 0xf) == 0)
18324 const APInt &ConstImm = CN->getAPIntValue();
18343 const APInt &ConstImm = CN->getAPIntValue();
18353 }
else if (
RHS.getOpcode() ==
PPCISD::Lo && !
RHS.getConstantOperandVal(1))
18365 isValidPCRelNode<ConstantPoolSDNode>(
N) ||
18366 isValidPCRelNode<GlobalAddressSDNode>(
N) ||
18367 isValidPCRelNode<JumpTableSDNode>(
N) ||
18368 isValidPCRelNode<BlockAddressSDNode>(
N));
18373unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
18378 if (!Subtarget.hasP9Vector())
18383 if (Subtarget.hasPrefixInstrs())
18386 if (Subtarget.hasSPE())
18395 unsigned ParentOp = Parent->
getOpcode();
18399 if ((
ID == Intrinsic::ppc_vsx_lxvp) || (
ID == Intrinsic::ppc_vsx_stxvp)) {
18400 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
18411 if (
const LSBaseSDNode *LSB = dyn_cast<LSBaseSDNode>(Parent))
18412 if (LSB->isIndexed())
18417 const MemSDNode *MN = dyn_cast<MemSDNode>(Parent);
18418 assert(MN &&
"Parent should be a MemSDNode!");
18423 "Not expecting scalar integers larger than 16 bytes!");
18426 else if (
Size == 32)
18433 else if (
Size == 256) {
18434 assert(Subtarget.pairedVectorMemops() &&
18435 "256-bit vectors are only available when paired vector memops is "
18443 else if (MemVT == MVT::f128 || MemVT.
isVector())
18453 if (
const LoadSDNode *LN = dyn_cast<LoadSDNode>(Parent)) {
18474 FlagSet &= ~PPC::MOF_NoExt;
18479 bool IsNonP1034BitConst =
18483 IsNonP1034BitConst)
18496 int16_t ForceXFormImm = 0;
18499 Disp =
N.getOperand(0);
18500 Base =
N.getOperand(1);
18511 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
18512 Disp =
N.getOperand(0);
18513 Base =
N.getOperand(1);
18527 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID>
CC)
const {
18533 if (PartVT == MVT::f64 &&
18534 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
18543SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
18547 EVT RetVT =
Op.getValueType();
18555 EVT ArgVT =
N.getValueType();
18560 Entry.IsZExt = !Entry.IsSExt;
18561 Args.push_back(Entry);
18569 (
RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
18575 .setTailCall(isTailCall)
18582SDValue PPCTargetLowering::lowerLibCallBasedOnType(
18583 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
18585 if (
Op.getValueType() == MVT::f32)
18586 return lowerToLibCall(LibCallFloatName,
Op, DAG);
18588 if (
Op.getValueType() == MVT::f64)
18589 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
18594bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
18596 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
18600bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
18601 return Op.getNode()->getFlags().hasApproximateFuncs();
18604bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
18608SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
18609 const char *LibCallFloatName,
18610 const char *LibCallDoubleNameFinite,
18611 const char *LibCallFloatNameFinite,
18614 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
18617 if (!isLowringToMASSFiniteSafe(
Op))
18618 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
18621 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
18622 LibCallDoubleNameFinite,
Op, DAG);
18626 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
18627 "__xl_powf_finite",
Op, DAG);
18631 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
18632 "__xl_sinf_finite",
Op, DAG);
18636 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
18637 "__xl_cosf_finite",
Op, DAG);
18641 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
18642 "__xl_logf_finite",
Op, DAG);
18646 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
18647 "__xl_log10f_finite",
Op, DAG);
18651 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
18652 "__xl_expf_finite",
Op, DAG);
18659 if (!isa<FrameIndexSDNode>(
N))
18677 unsigned Flags = computeMOFlags(Parent,
N, DAG);
18689 "Must be using PC-Relative calls when a valid PC-Relative node is "
18719 Disp =
N.getOperand(1).getOperand(0);
18724 Base =
N.getOperand(0);
18731 auto *CN = cast<ConstantSDNode>(
N);
18732 EVT CNType = CN->getValueType(0);
18733 uint64_t CNImm = CN->getZExtValue();
18744 if ((CNType == MVT::i32 || isInt<32>(CNImm)) &&
18746 int32_t
Addr = (int32_t)CNImm;
18751 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
18767 unsigned Opcode =
N.getOpcode();
18775 Base =
N.getOperand(0);
18794 Base = FI ?
N :
N.getOperand(1);
18806 bool IsVarArg)
const {
18816 return Subtarget.
isPPC64() && Subtarget.hasQuadwordAtomics();
18850 return Intrinsic::ppc_atomicrmw_xchg_i128;
18852 return Intrinsic::ppc_atomicrmw_add_i128;
18854 return Intrinsic::ppc_atomicrmw_sub_i128;
18856 return Intrinsic::ppc_atomicrmw_and_i128;
18858 return Intrinsic::ppc_atomicrmw_or_i128;
18860 return Intrinsic::ppc_atomicrmw_xor_i128;
18862 return Intrinsic::ppc_atomicrmw_nand_i128;
18879 Value *LoHi = Builder.
CreateCall(RMW, {AlignedAddr, IncrLo, IncrHi});
18885 Lo, Builder.
CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
18906 Builder.
CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
18913 Lo, Builder.
CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
unsigned const MachineRegisterInfo * MRI
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall, std::optional< CallLowering::PtrAuthInfo > &PAI, MachineRegisterInfo &MRI)
static SDValue GeneratePerfectShuffle(unsigned ID, SDValue V1, SDValue V2, unsigned PFEntry, SDValue LHS, SDValue RHS, SelectionDAG &DAG, const SDLoc &dl)
GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit the specified operations t...
static bool isSignExtended(SDValue N, SelectionDAG &DAG)
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
static std::pair< Register, unsigned > getBaseWithConstantOffset(MachineRegisterInfo &MRI, Register Reg)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
static bool isLoad(int Opcode)
static bool isFloatingPointZero(SDValue Op)
isFloatingPointZero - Return true if this is +0.0.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
Atomic ordering constants.
Analysis containing CSE Info
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
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...
This defines the Use class.
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 void updateForAIXShLibTLSModelOpt(TLSModel::Model &Model, SelectionDAG &DAG, const TargetMachine &TM)
updateForAIXShLibTLSModelOpt - Helper to initialize TLS model opt settings, and then apply the update...
static bool provablyDisjointOr(SelectionDAG &DAG, const SDValue &N)
Used when computing address flags for selecting loads and stores.
static 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 cl::opt< unsigned > PPCGatherAllAliasesMaxDepth("ppc-gather-alias-max-depth", cl::init(18), cl::Hidden, cl::desc("max depth when checking alias info in GatherAllAliases()"))
static bool areCallingConvEligibleForTCO_64SVR4(CallingConv::ID CallerCC, CallingConv::ID CalleeCC)
static const MCPhysReg FPR[]
FPR - The set of FP registers that should be allocated for arguments on Darwin and AIX.
static SDNode * isBLACompatibleAddress(SDValue Op, SelectionDAG &DAG)
isCallCompatibleAddress - Return the immediate to use if the specified 32-bit value is representable ...
static Align CalculateStackSlotAlignment(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotAlignment - Calculates the alignment of this argument on the stack.
static bool IsSelect(MachineInstr &MI)
static bool haveEfficientBuildVectorPattern(BuildVectorSDNode *V, bool HasDirectMove, bool HasP8Vector)
Do we have an efficient pattern in a .td file for this node?
static SDValue getSToVPermuted(SDValue OrigSToV, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &S)
static void setUsesTOCBasePtr(MachineFunction &MF)
static SDValue transformCallee(const SDValue &Callee, SelectionDAG &DAG, const SDLoc &dl, const PPCSubtarget &Subtarget)
static unsigned EnsureStackAlignment(const PPCFrameLowering *Lowering, unsigned NumBytes)
EnsureStackAlignment - Round stack frame size up from NumBytes to ensure minimum alignment required f...
static SDValue stripModuloOnShift(const TargetLowering &TLI, SDNode *N, SelectionDAG &DAG)
static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth)
static bool hasSameArgumentList(const Function *CallerFn, const CallBase &CB)
static bool isFPExtLoad(SDValue Op)
static SDValue BuildIntrinsicOp(unsigned IID, SDValue Op, SelectionDAG &DAG, const SDLoc &dl, EVT DestVT=MVT::Other)
BuildIntrinsicOp - Return a unary operator intrinsic node with the specified intrinsic ID.
static bool isConsecutiveLSLoc(SDValue Loc, EVT VT, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static void StoreTailCallArgumentsToStackSlot(SelectionDAG &DAG, SDValue Chain, const SmallVectorImpl< TailCallArgumentInfo > &TailCallArgs, SmallVectorImpl< SDValue > &MemOpChains, const SDLoc &dl)
StoreTailCallArgumentsToStackSlot - Stores arguments to their stack slot.
static const char AIXSSPCanaryWordName[]
static cl::opt< bool > UseAbsoluteJumpTables("ppc-use-absolute-jumptables", cl::desc("use absolute jump tables on ppc"), cl::Hidden)
static void setXFormForUnalignedFI(SDValue N, unsigned Flags, PPC::AddrMode &Mode)
static void getMaxByValAlign(Type *Ty, Align &MaxAlign, Align MaxMaxAlign)
getMaxByValAlign - Helper for getByValTypeAlignment to determine the desired ByVal argument alignment...
static bool isConsecutiveLS(SDNode *N, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static bool isVMerge(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned LHSStart, unsigned RHSStart)
isVMerge - Common function, used to match vmrg* shuffles.
static void getLabelAccessInfo(bool IsPIC, const PPCSubtarget &Subtarget, unsigned &HiOpFlags, unsigned &LoOpFlags, const GlobalValue *GV=nullptr)
Return true if we should reference labels using a PICBase, set the HiOpFlags and LoOpFlags to the tar...
cl::opt< bool > DisableAutoPairedVecSt("disable-auto-paired-vec-st", cl::desc("disable automatically generated 32byte paired vector stores"), cl::init(true), cl::Hidden)
static void buildCallOperands(SmallVectorImpl< SDValue > &Ops, PPCTargetLowering::CallFlags CFlags, const SDLoc &dl, SelectionDAG &DAG, SmallVector< std::pair< unsigned, SDValue >, 8 > &RegsToPass, SDValue Glue, SDValue Chain, SDValue &Callee, int SPDiff, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableInnermostLoopAlign32("disable-ppc-innermost-loop-align32", cl::desc("don't always align innermost loop to 32 bytes on ppc"), cl::Hidden)
static bool usePartialVectorLoads(SDNode *N, const PPCSubtarget &ST)
Returns true if we should use a direct load into vector instruction (such as lxsd or lfd),...
static SDValue getDataClassTest(SDValue Op, FPClassTest Mask, const SDLoc &Dl, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static 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 cl::opt< unsigned > PPCAIXTLSModelOptUseIEForLDLimit("ppc-aix-shared-lib-tls-model-opt-limit", cl::init(1), cl::Hidden, cl::desc("Set inclusive limit count of TLS local-dynamic access(es) in a " "function to use initial-exec"))
static unsigned getPPCStrictOpcode(unsigned Opc)
static void prepareDescriptorIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, SDValue CallSeqStart, const CallBase *CB, const SDLoc &dl, bool hasNest, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableP10StoreForward("disable-p10-store-forward", cl::desc("disable P10 store forward-friendly conversion"), cl::Hidden, cl::init(false))
static bool isXXBRShuffleMaskHelper(ShuffleVectorSDNode *N, int Width)
static bool isFunctionGlobalAddress(const GlobalValue *CalleeGV)
static bool isSplatBV(SDValue Op)
static SDValue combineBVOfVecSExt(SDNode *N, SelectionDAG &DAG)
static cl::opt< bool > DisableILPPref("disable-ppc-ilp-pref", cl::desc("disable setting the node scheduling preference to ILP on PPC"), cl::Hidden)
static bool isNByteElemShuffleMask(ShuffleVectorSDNode *, unsigned, int)
Check that the mask is shuffling N byte elements.
static SDValue combineBVOfConsecutiveLoads(SDNode *N, SelectionDAG &DAG)
Reduce the number of loads when building a vector.
static bool isValidPCRelNode(SDValue N)
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SI optimize exec mask operations pre RA
static const MCExpr * MaskShift(const MCExpr *Val, uint32_t Mask, uint32_t Shift, MCContext &Ctx)
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.
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).
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
AttributeList getAttributes() const
Return the attribute list for this Function.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Type * getReturnType() const
Returns the type of the ret val.
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
int64_t getOffset() const
unsigned getTargetFlags() const
const GlobalValue * getGlobal() const
const GlobalObject * getAliaseeObject() const
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
void setThreadLocalMode(ThreadLocalMode Val)
bool hasHiddenVisibility() const
StringRef getSection() const
Module * getParent()
Get the module that this global value is contained inside of...
bool isStrongDefinitionForLinker() const
Returns true if this global's definition will be the one chosen by the linker.
const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
Type * getValueType() const
bool hasProtectedVisibility() const
Common base class shared among various IRBuilders.
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
BasicBlock * GetInsertBlock() const
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 * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=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)
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.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
@ EK_LabelDifference32
EK_LabelDifference32 - Each entry is the address of the block minus the address of the jump table.
A description of a memory reference used in the backend.
LocationSize getSize() const
Return the size in bytes of the memory reference.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
MachineOperand class - Representation of each machine instruction operand.
static MachineOperand CreateImm(int64_t Val)
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Register getLiveInVirtReg(MCRegister PReg) const
getLiveInVirtReg - If PReg is a live-in physical register, return the corresponding live-in virtual r...
An SDNode that represents everything that will be needed to construct a MachineInstr.
This SDNode is used for target intrinsics that touch memory and need an associated MachineMemOperand.
This is an abstract virtual class for memory operations.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getBasePtr() const
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
uint64_t getReturnSaveOffset() const
getReturnSaveOffset - Return the previous frame offset to save the return address.
uint64_t getFramePointerSaveOffset() const
getFramePointerSaveOffset - Return the previous frame offset to save the frame pointer.
unsigned getLinkageSize() const
getLinkageSize - Return the size of the PowerPC ABI linkage area.
uint64_t getTOCSaveOffset() const
getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
void setVarArgsNumFPR(unsigned Num)
void setReturnAddrSaveIndex(int idx)
bool isAIXFuncUseTLSIEForLD() const
int getReturnAddrSaveIndex() const
unsigned getVarArgsNumFPR() const
void setAIXFuncUseTLSIEForLD()
int getFramePointerSaveIndex() const
void setVarArgsNumGPR(unsigned Num)
void appendParameterType(ParamType Type)
int getVarArgsFrameIndex() const
void setLRStoreRequired()
bool isAIXFuncTLSModelOptInitDone() const
void setTailCallSPDelta(int size)
void setAIXFuncTLSModelOptInitDone()
bool isLRStoreRequired() const
void setMinReservedArea(unsigned size)
unsigned getVarArgsNumGPR() const
unsigned getMinReservedArea() const
void setVarArgsStackOffset(int Offset)
void setVarArgsFrameIndex(int Index)
void addLiveInAttr(Register VReg, ISD::ArgFlagsTy Flags)
This function associates attributes for each live-in virtual register.
int getVarArgsStackOffset() const
void setFramePointerSaveIndex(int Idx)
static bool hasPCRelFlag(unsigned TF)
bool is32BitELFABI() const
unsigned descriptorTOCAnchorOffset() const
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 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 getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), AAResults *AA=nullptr)
SDValue makeEquivalentMemoryOrdering(SDValue OldChain, SDValue NewMemOpChain)
If an existing load has uses of its chain, create a token factor node with that chain and the new mem...
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
Align getEVTAlign(EVT MemoryVT) const
Compute the default alignment value for the given type.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
static constexpr unsigned MaxRecursionDepth
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
SDValue getTokenFactor(const SDLoc &DL, SmallVectorImpl< SDValue > &Vals)
Creates a new TokenFactor containing Vals.
bool areNonVolatileConsecutiveLoads(LoadSDNode *LD, LoadSDNode *Base, unsigned Bytes, int Dist) const
Return true if loads are next to each other and can be merged.
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue 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?...
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL) const
Returns the type for the shift amount of a shift opcode.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
virtual Align getPrefLoopAlignment(MachineLoop *ML=nullptr) const
Return the preferred loop alignment.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
void setIndexedStoreAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed store does or does not work with the specified type and indicate ...
virtual bool isJumpTableRelative() const
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setLibcallName(RTLIB::Libcall Call, const char *Name)
Rename the default libcall routine name for the specified libcall.
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
virtual AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setMinimumJumpTableEntries(unsigned Val)
Indicate the minimum number of blocks to generate jump tables.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
unsigned MaxLoadsPerMemcmpOptSize
Likewise for functions with the OptSize attribute.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
virtual AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
unsigned GatherAllAliasesMaxDepth
Depth that GatherAllAliases should continue looking for chain dependencies when trying to find a more...
NegatibleCost
Enum that specifies when a float negation is beneficial.
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.
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ BSWAP
Byte Swap and Counting operators.
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, 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 minimumNumber or maximumNumber on two values,...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two values.
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ INLINEASM_BR
INLINEASM_BR - Branching version of inline asm. Used by asm-goto.
@ EH_DWARF_CFA
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA),...
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ ADDE
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ INLINEASM
INLINEASM - Represents an inline asm block.
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ CALLSEQ_START
CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of a call sequence,...
@ GET_DYNAMIC_AREA_OFFSET
GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of the most recent dynamic alloca.
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ ADJUST_TRAMPOLINE
ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
bool 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)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
bool CC_PPC64_ELF(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
bool RetCC_PPC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Mod
The access may modify the value stored in memory.
bool isIntS34Immediate(SDNode *N, int64_t &Imm)
isIntS34Immediate - This method tests if value of node given can be accurately represented as a sign ...
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
@ Mul
Product of integers.
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.
static const unsigned PerfectShuffleTable[6561+1]
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This is used by foldLoadsRecursive() to capture a Root Load node which is of type or(load,...
static const fltSemantics & IEEEsingle() LLVM_READNONE
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & PPCDoubleDouble() LLVM_READNONE
static constexpr roundingMode rmTowardZero
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
Represent subnormal handling kind for floating point instruction inputs and outputs.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
unsigned getByValSize() const
void setByValSize(unsigned S)
Align getNonZeroByValAlign() const
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
bool isConstant() const
Returns true if we know the value of all bits.
void resetAll()
Resets the known state of all bits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
This class contains a discriminated union of information about pointers in memory operands,...
static MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
MachinePointerInfo getWithOffset(int64_t O) const
static MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Structure that collects some common arguments that get passed around between the functions for call l...
const CallingConv::ID CallConv
These are IR-level optimization flags that may be propagated to SDNodes.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
CallLoweringInfo & setIsPostTypeLegalization(bool Value=true)
CallLoweringInfo & setLibCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setZExtResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setSExtResult(bool Value=true)
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
bool isBeforeLegalizeOps() const
bool isAfterLegalizeDAG() const
void AddToWorklist(SDNode *N)
bool isBeforeLegalize() const
SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)