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);
3395 if (
II->getOpcode() == Instruction::Call)
3396 if (
const CallInst *CI = dyn_cast<const CallInst>(&*
II))
3397 if (
Function *CF = CI->getCalledFunction())
3398 if (CF->isDeclaration() &&
3399 CF->getIntrinsicID() == Intrinsic::threadlocal_address)
3401 dyn_cast<GlobalValue>(
II->getOperand(0))) {
3407 unsigned TLSGVCnt = TLSGV.
size();
3417 <<
" function is using the TLS-IE model for TLS-LD access.\n");
3432 bool Is64Bit = Subtarget.
isPPC64();
3436 if (Subtarget.hasAIXShLibTLSModelOpt())
3442 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3443 bool HasAIXSmallTLSGlobalAttr =
false;
3446 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3450 if (GVar->hasAttribute(
"aix-small-tls"))
3451 HasAIXSmallTLSGlobalAttr =
true;
3470 if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) &&
3471 IsTLSLocalExecModel) {
3491 if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr)
3493 "currently only supported on AIX (64-bit mode).");
3499 bool HasAIXSmallLocalDynamicTLS = Subtarget.hasAIXSmallLocalDynamicTLS();
3503 if (!Is64Bit && HasAIXSmallLocalDynamicTLS)
3505 "currently only supported on AIX (64-bit mode).");
3513 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3517 dyn_cast_or_null<GlobalVariable>(
M->getOrInsertGlobal(
3520 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3523 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3534 if (HasAIXSmallLocalDynamicTLS) {
3543 return DAG.
getNode(
ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
3556 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3557 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3575 bool is64bit = Subtarget.
isPPC64();
3622 if (!
TM.isPositionIndependent())
3681 PtrVT, GOTPtr, TGA, TGA);
3683 PtrVT, TLSAddr, TGA);
3692 EVT PtrVT =
Op.getValueType();
3717 return getTOCEntry(DAG,
DL, GA);
3720 unsigned MOHiFlag, MOLoFlag;
3728 return getTOCEntry(DAG,
DL, GA);
3740 bool IsStrict =
Op->isStrictFPOpcode();
3742 cast<CondCodeSDNode>(
Op.getOperand(IsStrict ? 3 : 2))->get();
3746 EVT LHSVT =
LHS.getValueType();
3750 if (LHSVT == MVT::f128) {
3751 assert(!Subtarget.hasP9Vector() &&
3752 "SETCC for f128 is already legal under Power9!");
3763 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3765 if (
Op.getValueType() == MVT::v2i64) {
3768 if (
LHS.getValueType() == MVT::v2i64) {
3776 int ShuffV[] = {1, 0, 3, 2};
3781 dl, MVT::v4i32, Shuff, SetCC32));
3798 if (
C->isAllOnes() ||
C->isZero())
3808 EVT VT =
Op.getValueType();
3817 EVT VT =
Node->getValueType(0);
3821 const Value *SV = cast<SrcValueSDNode>(
Node->getOperand(2))->getValue();
3831 if (VT == MVT::i64) {
3862 InChain = OverflowArea.
getValue(1);
3908 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3915 assert(!Subtarget.
isPPC64() &&
"LowerVACOPY is PPC32 only");
3921 false,
true,
nullptr, std::nullopt,
3930 return Op.getOperand(0);
3939 "Expecting Inline ASM node.");
3949 if (
Op.getOperand(NumOps - 1).getValueType() == MVT::Glue)
3955 unsigned NumVals =
Flags.getNumOperandRegisters();
3958 switch (
Flags.getKind()) {
3969 for (; NumVals; --NumVals, ++i) {
3970 Register Reg = cast<RegisterSDNode>(
Op.getOperand(i))->getReg();
3971 if (Reg != PPC::LR && Reg != PPC::LR8)
3996 bool isPPC64 = (PtrVT == MVT::i64);
4002 Entry.Ty = IntPtrTy;
4003 Entry.Node = Trmp;
Args.push_back(Entry);
4007 isPPC64 ? MVT::i64 : MVT::i32);
4008 Args.push_back(Entry);
4010 Entry.Node = FPtr;
Args.push_back(Entry);
4011 Entry.Node = Nest;
Args.push_back(Entry);
4015 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
4019 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
4020 return CallResult.second;
4034 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
4035 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
4070 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
4079 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
4094 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
4097 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
4099 nextOffset += FrameOffset;
4100 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
4103 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
4109static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
4110 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
4111 PPC::F11, PPC::F12, PPC::F13};
4116 unsigned PtrByteSize) {
4118 if (Flags.isByVal())
4119 ArgSize = Flags.getByValSize();
4123 if (!Flags.isInConsecutiveRegs())
4124 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4133 unsigned PtrByteSize) {
4134 Align Alignment(PtrByteSize);
4137 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4138 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4139 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4140 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4141 Alignment =
Align(16);
4144 if (Flags.isByVal()) {
4145 auto BVAlign = Flags.getNonZeroByValAlign();
4146 if (BVAlign > PtrByteSize) {
4147 if (BVAlign.value() % PtrByteSize != 0)
4149 "ByVal alignment is not a multiple of the pointer size");
4151 Alignment = BVAlign;
4156 if (Flags.isInConsecutiveRegs()) {
4160 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4174 unsigned PtrByteSize,
unsigned LinkageSize,
4175 unsigned ParamAreaSize,
unsigned &ArgOffset,
4176 unsigned &AvailableFPRs,
4177 unsigned &AvailableVRs) {
4178 bool UseMemory =
false;
4183 ArgOffset =
alignTo(ArgOffset, Alignment);
4186 if (ArgOffset >= LinkageSize + ParamAreaSize)
4191 if (Flags.isInConsecutiveRegsLast())
4192 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4195 if (ArgOffset > LinkageSize + ParamAreaSize)
4200 if (!Flags.isByVal()) {
4201 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4202 if (AvailableFPRs > 0) {
4206 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4207 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4208 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4209 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4210 if (AvailableVRs > 0) {
4222 unsigned NumBytes) {
4226SDValue PPCTargetLowering::LowerFormalArguments(
4231 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4234 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4237 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4241SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4283 const Align PtrAlign(4);
4292 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4294 CCInfo.PreAnalyzeFormalArguments(Ins);
4297 CCInfo.clearWasPPCF128();
4299 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4312 RC = &PPC::GPRCRegClass;
4315 if (Subtarget.hasP8Vector())
4316 RC = &PPC::VSSRCRegClass;
4317 else if (Subtarget.hasSPE())
4318 RC = &PPC::GPRCRegClass;
4320 RC = &PPC::F4RCRegClass;
4323 if (Subtarget.hasVSX())
4324 RC = &PPC::VSFRCRegClass;
4325 else if (Subtarget.hasSPE())
4327 RC = &PPC::GPRCRegClass;
4329 RC = &PPC::F8RCRegClass;
4334 RC = &PPC::VRRCRegClass;
4337 RC = &PPC::VRRCRegClass;
4341 RC = &PPC::VRRCRegClass;
4348 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4349 assert(i + 1 < e &&
"No second half of double precision argument");
4361 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4362 if (ValVT == MVT::i1)
4377 ArgOffset += ArgSize - ObjSize;
4395 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4400 unsigned MinReservedArea = CCByValInfo.getStackSize();
4401 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4417 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4418 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4420 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4423 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4426 unsigned NumFPArgRegs = std::size(FPArgRegs);
4435 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4439 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4448 for (
unsigned GPRIndex = 0; GPRIndex != NumGPArgRegs; ++GPRIndex) {
4452 VReg = MF.
addLiveIn(GPArgRegs[GPRIndex], &PPC::GPRCRegClass);
4467 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4471 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4484 if (!MemOps.
empty())
4495 const SDLoc &dl)
const {
4499 else if (
Flags.isZExt())
4506SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4519 "fastcc not supported on varargs functions");
4525 unsigned PtrByteSize = 8;
4529 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4530 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4533 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4534 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4537 const unsigned Num_GPR_Regs = std::size(GPR);
4539 const unsigned Num_VR_Regs = std::size(VR);
4547 bool HasParameterArea = !isELFv2ABI || isVarArg;
4548 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4549 unsigned NumBytes = LinkageSize;
4550 unsigned AvailableFPRs = Num_FPR_Regs;
4551 unsigned AvailableVRs = Num_VR_Regs;
4552 for (
unsigned i = 0, e =
Ins.size(); i != e; ++i) {
4553 if (Ins[i].
Flags.isNest())
4557 PtrByteSize, LinkageSize, ParamAreaSize,
4558 NumBytes, AvailableFPRs, AvailableVRs))
4559 HasParameterArea =
true;
4566 unsigned ArgOffset = LinkageSize;
4567 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4570 unsigned CurArgIdx = 0;
4571 for (
unsigned ArgNo = 0, e =
Ins.size(); ArgNo != e; ++ArgNo) {
4573 bool needsLoad =
false;
4574 EVT ObjectVT =
Ins[ArgNo].VT;
4575 EVT OrigVT =
Ins[ArgNo].ArgVT;
4577 unsigned ArgSize = ObjSize;
4579 if (Ins[ArgNo].isOrigArg()) {
4580 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4581 CurArgIdx =
Ins[ArgNo].getOrigArgIndex();
4586 unsigned CurArgOffset;
4588 auto ComputeArgOffset = [&]() {
4592 ArgOffset =
alignTo(ArgOffset, Alignment);
4593 CurArgOffset = ArgOffset;
4600 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4601 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4606 if (
Flags.isByVal()) {
4607 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4613 ObjSize =
Flags.getByValSize();
4614 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4636 if (HasParameterArea ||
4637 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4644 if (ObjSize < PtrByteSize) {
4648 if (!isLittleEndian) {
4654 if (GPR_idx != Num_GPR_Regs) {
4666 ArgOffset += PtrByteSize;
4675 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4676 if (GPR_idx == Num_GPR_Regs)
4687 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4695 ArgOffset += ArgSize;
4704 if (
Flags.isNest()) {
4709 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4710 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4718 if (GPR_idx != Num_GPR_Regs) {
4723 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4726 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4732 ArgSize = PtrByteSize;
4743 if (FPR_idx != Num_FPR_Regs) {
4746 if (ObjectVT == MVT::f32)
4748 Subtarget.hasP8Vector()
4749 ? &PPC::VSSRCRegClass
4750 : &PPC::F4RCRegClass);
4753 ? &PPC::VSFRCRegClass
4754 : &PPC::F8RCRegClass);
4769 if (ObjectVT == MVT::f32) {
4770 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4788 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4789 ArgOffset += ArgSize;
4790 if (
Flags.isInConsecutiveRegsLast())
4791 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4805 if (VR_idx != Num_VR_Regs) {
4822 if (ObjSize < ArgSize && !isLittleEndian)
4823 CurArgOffset += ArgSize - ObjSize;
4833 unsigned MinReservedArea;
4834 if (HasParameterArea)
4835 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4837 MinReservedArea = LinkageSize;
4854 int Depth = ArgOffset;
4863 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4864 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4876 if (!MemOps.
empty())
4885 unsigned ParamSize) {
4887 if (!isTailCall)
return 0;
4891 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4893 if (SPDiff < FI->getTailCallSPDelta())
4909 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4922 if (!
TM.shouldAssumeDSOLocal(CalleeGV))
4928 const Function *
F = dyn_cast<Function>(CalleeGV);
4929 const GlobalAlias *Alias = dyn_cast<GlobalAlias>(CalleeGV);
4934 F = dyn_cast<Function>(GlobalObj);
4967 if (
TM.getFunctionSections() || CalleeGV->
hasComdat() ||
4968 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
4970 if (
const auto *
F = dyn_cast<Function>(CalleeGV)) {
4971 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4983 const unsigned PtrByteSize = 8;
4987 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4988 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4991 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4992 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4995 const unsigned NumGPRs = std::size(GPR);
4996 const unsigned NumFPRs = 13;
4997 const unsigned NumVRs = std::size(VR);
4998 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
5000 unsigned NumBytes = LinkageSize;
5001 unsigned AvailableFPRs = NumFPRs;
5002 unsigned AvailableVRs = NumVRs;
5005 if (Param.Flags.isNest())
continue;
5008 LinkageSize, ParamAreaSize, NumBytes,
5009 AvailableFPRs, AvailableVRs))
5020 auto CalleeArgEnd = CB.
arg_end();
5023 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
5024 const Value* CalleeArg = *CalleeArgIter;
5025 const Value* CallerArg = &(*CallerArgIter);
5026 if (CalleeArg == CallerArg)
5034 isa<UndefValue>(CalleeArg))
5052 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
5062bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
5067 bool isCalleeExternalSymbol)
const {
5070 if (
DisableSCO && !TailCallOpt)
return false;
5073 if (isVarArg)
return false;
5149bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5183 if (!
C)
return nullptr;
5185 int Addr =
C->getZExtValue();
5186 if ((
Addr & 3) != 0 ||
5192 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5199struct TailCallArgumentInfo {
5204 TailCallArgumentInfo() =
default;
5214 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5215 SDValue Arg = TailCallArgs[i].Arg;
5216 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5217 int FI = TailCallArgs[i].FrameIdx;
5220 Chain, dl, Arg, FIN,
5229 int SPDiff,
const SDLoc &dl) {
5235 bool isPPC64 = Subtarget.
isPPC64();
5236 int SlotSize = isPPC64 ? 8 : 4;
5237 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5239 NewRetAddrLoc,
true);
5240 EVT VT = isPPC64 ? MVT::i64 : MVT::i32;
5242 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5252 SDValue Arg,
int SPDiff,
unsigned ArgOffset,
5254 int Offset = ArgOffset + SPDiff;
5257 EVT VT = isPPC64 ? MVT::i64 : MVT::i32;
5259 TailCallArgumentInfo
Info;
5261 Info.FrameIdxOp = FIN;
5269SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5274 EVT VT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
5275 LROpOut = getReturnAddrFrameIndex(DAG);
5293 Chain, dl, Dst, Src, SizeNode, Flags.getNonZeroByValAlign(),
false,
false,
5301 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5324 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5334 if (!MemOpChains2.
empty())
5358SDValue PPCTargetLowering::LowerCallResult(
5366 CCRetInfo.AnalyzeCallResult(
5372 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5378 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5381 Chain =
Lo.getValue(1);
5382 InGlue =
Lo.getValue(2);
5386 Chain =
Hi.getValue(1);
5387 InGlue =
Hi.getValue(2);
5424 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5456 bool IsStrictFPCall =
false) {
5460 unsigned RetOpc = 0;
5485 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5491 if (IsStrictFPCall) {
5522 auto isLocalCallee = [&]() {
5527 !isa_and_nonnull<GlobalIFunc>(GV);
5538 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5548 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5551 const GlobalValue *GV = cast<GlobalAddressSDNode>(Callee)->getGlobal();
5554 assert(!isa<GlobalIFunc>(GV) &&
"IFunc is not supported on AIX.");
5555 return getAIXFuncEntryPointSymbolSDNode(GV);
5562 const char *SymName = S->getSymbol();
5568 dyn_cast_or_null<Function>(
Mod->getNamedValue(SymName)))
5569 return getAIXFuncEntryPointSymbolSDNode(
F);
5575 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5583 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5590 assert(Callee.getNode() &&
"What no callee?");
5596 "Expected a CALLSEQ_STARTSDNode.");
5613 SDValue MTCTROps[] = {Chain, Callee, Glue};
5614 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5655 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5670 const MVT RegVT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
5674 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5675 Alignment, MMOFlags);
5682 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5689 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5701 "Nest parameter is not supported on AIX.");
5717 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5720 const bool IsPPC64 = Subtarget.
isPPC64();
5722 const MVT RegVT = IsPPC64 ? MVT::i64 : MVT::i32;
5769 for (
unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
5771 RegsToPass[i].second.getValueType()));
5788 assert(Mask &&
"Missing call preserved mask for calling convention");
5796SDValue PPCTargetLowering::FinishCall(
5811 if (!CFlags.IsIndirect)
5815 dl, CFlags.HasNest, Subtarget);
5825 if (CFlags.IsTailCall) {
5829 cast<RegisterSDNode>(Callee)->getReg() == PPC::CTR) ||
5832 isa<ConstantSDNode>(Callee) ||
5834 "Expecting a global address, external symbol, absolute value, "
5835 "register or an indirect tail call when PC Relative calls are "
5839 "Unexpected call opcode for a tail call.");
5846 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5847 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes, Ops);
5859 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5862 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5873 const GlobalValue *CalleeGV = dyn_cast<GlobalValue>(CalleeFunc);
5882 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5883 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5887bool PPCTargetLowering::isEligibleForTCO(
5892 bool isCalleeExternalSymbol)
const {
5897 return IsEligibleForTailCallOptimization_64SVR4(
5898 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5899 isCalleeExternalSymbol);
5901 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5924 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5926 bool IsCalleeExternalSymbol = isa<ExternalSymbolSDNode>(Callee);
5929 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5943 isa<GlobalAddressSDNode>(Callee)) &&
5944 "Callee should be an llvm::Function object.");
5947 <<
"\nTCO callee: ");
5954 "site marked musttail");
5959 if (Subtarget.useLongCalls() && isa<GlobalAddressSDNode>(Callee) &&
5961 Callee = LowerGlobalAddress(Callee, DAG);
5964 CallConv, isTailCall, isVarArg, isPatchPoint,
5972 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5977 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5979 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5983SDValue PPCTargetLowering::LowerCall_32SVR4(
5994 const bool IsVarArg = CFlags.IsVarArg;
5995 const bool IsTailCall = CFlags.IsTailCall;
6001 const Align PtrAlign(4);
6026 CCInfo.PreAnalyzeCallOperands(Outs);
6032 unsigned NumArgs = Outs.
size();
6034 for (
unsigned i = 0; i != NumArgs; ++i) {
6035 MVT ArgVT = Outs[i].VT;
6039 if (Outs[i].IsFixed) {
6049 errs() <<
"Call operand #" << i <<
" has unhandled type "
6059 CCInfo.clearWasPPCF128();
6066 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
6073 unsigned NumBytes = CCByValInfo.getStackSize();
6087 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6098 bool seenFloatArg =
false;
6103 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
6105 ++i, ++RealArgIdx) {
6107 SDValue Arg = OutVals[RealArgIdx];
6110 if (
Flags.isByVal()) {
6115 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
6138 Chain = CallSeqStart = NewCallSeqStart;
6157 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6164 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6188 if (!MemOpChains.
empty())
6194 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
6195 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
6196 RegsToPass[i].second, InGlue);
6204 SDValue Ops[] = { Chain, InGlue };
6216 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6217 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6222SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6234 return NewCallSeqStart;
6237SDValue PPCTargetLowering::LowerCall_64SVR4(
6246 unsigned NumOps = Outs.
size();
6247 bool IsSibCall =
false;
6251 unsigned PtrByteSize = 8;
6266 assert(!(IsFastCall && CFlags.IsVarArg) &&
6267 "fastcc not supported on varargs functions");
6274 unsigned NumBytes = LinkageSize;
6275 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6278 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6279 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6282 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6283 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6286 const unsigned NumGPRs = std::size(GPR);
6288 const unsigned NumVRs = std::size(VR);
6294 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6295 if (!HasParameterArea) {
6296 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6297 unsigned AvailableFPRs = NumFPRs;
6298 unsigned AvailableVRs = NumVRs;
6299 unsigned NumBytesTmp = NumBytes;
6300 for (
unsigned i = 0; i != NumOps; ++i) {
6301 if (Outs[i].
Flags.isNest())
continue;
6303 PtrByteSize, LinkageSize, ParamAreaSize,
6304 NumBytesTmp, AvailableFPRs, AvailableVRs))
6305 HasParameterArea =
true;
6311 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6316 HasParameterArea =
false;
6319 for (
unsigned i = 0; i != NumOps; ++i) {
6321 EVT ArgVT = Outs[i].VT;
6322 EVT OrigVT = Outs[i].ArgVT;
6328 if (
Flags.isByVal()) {
6329 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6330 if (NumGPRsUsed > NumGPRs)
6331 HasParameterArea =
true;
6338 if (++NumGPRsUsed <= NumGPRs)
6348 if (++NumVRsUsed <= NumVRs)
6352 if (++NumVRsUsed <= NumVRs)
6357 if (++NumFPRsUsed <= NumFPRs)
6361 HasParameterArea =
true;
6368 NumBytes =
alignTo(NumBytes, Alignement);
6371 if (
Flags.isInConsecutiveRegsLast())
6372 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6375 unsigned NumBytesActuallyUsed = NumBytes;
6385 if (HasParameterArea)
6386 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6388 NumBytes = LinkageSize;
6403 if (CFlags.IsTailCall)
6415 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6426 unsigned ArgOffset = LinkageSize;
6432 for (
unsigned i = 0; i != NumOps; ++i) {
6435 EVT ArgVT = Outs[i].VT;
6436 EVT OrigVT = Outs[i].ArgVT;
6445 auto ComputePtrOff = [&]() {
6449 ArgOffset =
alignTo(ArgOffset, Alignment);
6460 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6461 GPR_idx = std::min(GPR_idx, NumGPRs);
6468 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6474 if (
Flags.isByVal()) {
6492 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6493 if (GPR_idx != NumGPRs) {
6497 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6499 ArgOffset += PtrByteSize;
6504 if (GPR_idx == NumGPRs &&
Size < 8) {
6506 if (!isLittleEndian) {
6511 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6514 ArgOffset += PtrByteSize;
6523 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6524 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6529 if (
Size < 8 && GPR_idx != NumGPRs) {
6539 if (!isLittleEndian) {
6543 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6551 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6554 ArgOffset += PtrByteSize;
6560 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6563 if (GPR_idx != NumGPRs) {
6564 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6570 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6571 ArgOffset += PtrByteSize;
6573 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6585 if (
Flags.isNest()) {
6587 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6594 if (GPR_idx != NumGPRs) {
6595 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6600 assert(HasParameterArea &&
6601 "Parameter area must exist to pass an argument in memory.");
6603 true, CFlags.IsTailCall,
false, MemOpChains,
6604 TailCallArguments, dl);
6606 ArgOffset += PtrByteSize;
6609 ArgOffset += PtrByteSize;
6622 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6623 bool NeededLoad =
false;
6626 if (FPR_idx != NumFPRs)
6627 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6630 if (!NeedGPROrStack)
6632 else if (GPR_idx != NumGPRs && !IsFastCall) {
6646 }
else if (!
Flags.isInConsecutiveRegs()) {
6652 }
else if (ArgOffset % PtrByteSize != 0) {
6656 if (!isLittleEndian)
6661 }
else if (
Flags.isInConsecutiveRegsLast()) {
6664 if (!isLittleEndian)
6674 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6682 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6687 assert(HasParameterArea &&
6688 "Parameter area must exist to pass an argument in memory.");
6690 true, CFlags.IsTailCall,
false, MemOpChains,
6691 TailCallArguments, dl);
6698 if (!IsFastCall || NeededLoad) {
6700 Flags.isInConsecutiveRegs()) ? 4 : 8;
6701 if (
Flags.isInConsecutiveRegsLast())
6702 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6722 if (CFlags.IsVarArg) {
6723 assert(HasParameterArea &&
6724 "Parameter area must exist if we have a varargs call.");
6730 if (VR_idx != NumVRs) {
6734 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6737 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6738 if (GPR_idx == NumGPRs)
6745 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6751 if (VR_idx != NumVRs) {
6752 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6757 assert(HasParameterArea &&
6758 "Parameter area must exist to pass an argument in memory.");
6760 true, CFlags.IsTailCall,
true, MemOpChains,
6761 TailCallArguments, dl);
6772 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6773 "mismatch in size of parameter area");
6774 (void)NumBytesActuallyUsed;
6776 if (!MemOpChains.
empty())
6782 if (CFlags.IsIndirect) {
6786 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6801 if (isELFv2ABI && !CFlags.IsPatchPoint)
6802 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6808 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
6809 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
6810 RegsToPass[i].second, InGlue);
6814 if (CFlags.IsTailCall && !IsSibCall)
6818 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6819 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6826 "Required alignment greater than stack alignment.");
6846 return RequiredAlign <= 8;
6851 return RequiredAlign <= 4;
6861 const bool IsPPC64 = Subtarget.
isPPC64();
6862 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6863 const Align PtrAlign(PtrSize);
6864 const Align StackAlign(16);
6865 const MVT RegVT = IsPPC64 ? MVT::i64 : MVT::i32;
6867 if (ValVT == MVT::f128)
6874 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6875 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6877 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6878 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6881 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6882 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6883 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6889 if (ByValAlign > StackAlign)
6891 "16 are not supported.");
6894 const Align ObjAlign = ByValAlign > PtrAlign ? ByValAlign : PtrAlign;
6898 if (ByValSize == 0) {
6906 while (NextReg != GPRs.
size() &&
6912 assert(Reg &&
"Alocating register unexpectedly failed.");
6917 const unsigned StackSize =
alignTo(ByValSize, ObjAlign);
6938 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6967 for (
unsigned I = 0;
I < StoreSize;
I += PtrSize) {
6969 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
7002 const unsigned VecSize = 16;
7003 const Align VecAlign(VecSize);
7023 while (NextRegIndex != GPRs.
size() &&
7028 assert(Reg &&
"Allocating register unexpectedly failed.");
7041 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
7053 if (NextRegIndex == GPRs.
size()) {
7062 if (GPRs[NextRegIndex] == PPC::R9) {
7067 const unsigned FirstReg = State.
AllocateReg(PPC::R9);
7068 const unsigned SecondReg = State.
AllocateReg(PPC::R10);
7069 assert(FirstReg && SecondReg &&
7070 "Allocating R9 or R10 unexpectedly failed.");
7084 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
7086 assert(Reg &&
"Failed to allocated register for vararg vector argument");
7101 assert((IsPPC64 || SVT != MVT::i64) &&
7102 "i64 should have been split for 32-bit codegen.");
7110 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7112 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
7114 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
7122 return &PPC::VRRCRegClass;
7135 else if (Flags.isZExt())
7145 if (PPC::GPRCRegClass.
contains(Reg)) {
7146 assert(Reg >= PPC::R3 && Reg <= PPC::R10 &&
7147 "Reg must be a valid argument register!");
7148 return LASize + 4 * (Reg - PPC::R3);
7151 if (PPC::G8RCRegClass.
contains(Reg)) {
7152 assert(Reg >= PPC::X3 && Reg <= PPC::X10 &&
7153 "Reg must be a valid argument register!");
7154 return LASize + 8 * (Reg - PPC::X3);
7200SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7207 "Unexpected calling convention!");
7217 const bool IsPPC64 = Subtarget.
isPPC64();
7218 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7230 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7231 uint64_t SaveStackPos = CCInfo.getStackSize();
7233 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7253 LocVT.
SimpleTy, IsPPC64, Subtarget.hasP8Vector(), Subtarget.hasVSX());
7255 MVT SaveVT = RegClass == &PPC::G8RCRegClass ? MVT::i64 : LocVT;
7267 unsigned StoreSize =
7269 SaveStackPos =
alignTo(SaveStackPos + StoreSize, PtrByteSize);
7272 auto HandleMemLoc = [&]() {
7275 assert((ValSize <= LocSize) &&
7276 "Object size is larger than size of MemLoc");
7279 if (LocSize > ValSize)
7280 CurArgOffset += LocSize - ValSize;
7282 const bool IsImmutable =
7297 assert(isVarArg &&
"Only use custom memloc for vararg.");
7300 const unsigned OriginalValNo = VA.
getValNo();
7301 (void)OriginalValNo;
7303 auto HandleCustomVecRegLoc = [&]() {
7304 assert(
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7305 "Missing custom RegLoc.");
7308 "Unexpected Val type for custom RegLoc.");
7310 "ValNo mismatch between custom MemLoc and RegLoc.");
7314 Subtarget.hasVSX()));
7321 HandleCustomVecRegLoc();
7322 HandleCustomVecRegLoc();
7326 if (
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7328 "Only 2 custom RegLocs expected for 64-bit codegen.");
7329 HandleCustomVecRegLoc();
7330 HandleCustomVecRegLoc();
7374 const unsigned Size =
7386 if (
Flags.isByVal()) {
7392 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7401 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7403 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7416 CopyFrom.
getValue(1), dl, CopyFrom,
7426 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7429 "RegLocs should be for ByVal argument.");
7436 if (
Offset != StackSize) {
7438 "Expected MemLoc for remaining bytes.");
7439 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7453 Subtarget.hasVSX()));
7470 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7472 unsigned CallerReservedArea = std::max<unsigned>(
7473 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7479 CallerReservedArea =
7488 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7489 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7491 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7492 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7493 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7498 for (
unsigned GPRIndex =
7499 (CCInfo.getStackSize() - LinkageSize) / PtrByteSize;
7500 GPRIndex < NumGPArgRegs; ++GPRIndex) {
7503 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7504 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7516 if (!MemOps.
empty())
7522SDValue PPCTargetLowering::LowerCall_AIX(
7535 "Unexpected calling convention!");
7537 if (CFlags.IsPatchPoint)
7544 AIXCCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7552 const bool IsPPC64 = Subtarget.
isPPC64();
7554 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7555 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7556 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7564 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7565 const unsigned NumBytes = std::max<unsigned>(
7566 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7582 for (
unsigned I = 0, E = ArgLocs.
size();
I != E;) {
7583 const unsigned ValNo = ArgLocs[
I].getValNo();
7587 if (
Flags.isByVal()) {
7588 const unsigned ByValSize =
Flags.getByValSize();
7596 auto GetLoad = [&](
EVT VT,
unsigned LoadOffset) {
7605 unsigned LoadOffset = 0;
7608 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7611 LoadOffset += PtrByteSize;
7614 "Unexpected location for pass-by-value argument.");
7618 if (LoadOffset == ByValSize)
7622 assert(ArgLocs[
I].getValNo() == ValNo &&
7623 "Expected additional location for by-value argument.");
7625 if (ArgLocs[
I].isMemLoc()) {
7626 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7631 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7637 CallSeqStart, MemcpyFlags, DAG, dl);
7646 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7647 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7648 "Unexpected register residue for by-value argument.");
7650 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7654 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7664 "Unexpected load emitted during handling of pass-by-value "
7672 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7707 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7715 const unsigned OriginalValNo = VA.
getValNo();
7717 unsigned LoadOffset = 0;
7718 auto HandleCustomVecRegLoc = [&]() {
7719 assert(
I != E &&
"Unexpected end of CCvalAssigns.");
7720 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7721 "Expected custom RegLoc.");
7724 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7730 LoadOffset += PtrByteSize;
7736 HandleCustomVecRegLoc();
7737 HandleCustomVecRegLoc();
7739 if (
I != E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7740 ArgLocs[
I].getValNo() == OriginalValNo) {
7742 "Only 2 custom RegLocs expected for 64-bit codegen.");
7743 HandleCustomVecRegLoc();
7744 HandleCustomVecRegLoc();
7762 "Unexpected register handling for calling convention.");
7768 "Custom register handling only expected for VarArg.");
7786 "Unexpected custom register for argument!");
7807 if (!MemOpChains.
empty())
7812 if (CFlags.IsIndirect) {
7813 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7816 const MVT PtrVT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
7817 const unsigned TOCSaveOffset =
7833 for (
auto Reg : RegsToPass) {
7838 const int SPDiff = 0;
7839 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7840 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7849 CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
7850 return CCInfo.CheckReturn(
7865 CCInfo.AnalyzeReturn(Outs,
7874 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7878 SDValue Arg = OutVals[RealResIdx];
7893 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7916 RetOps.push_back(Glue);
7922PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7927 EVT IntVT =
Op.getValueType();
7931 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7933 SDValue Ops[2] = {Chain, FPSIdx};
7947 bool isPPC64 = Subtarget.
isPPC64();
7948 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7968 bool isPPC64 = Subtarget.
isPPC64();
7989PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
7991 bool isPPC64 = Subtarget.
isPPC64();
8025 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
8026 SDValue Ops[3] = { Chain, NegSize, FPSIdx };
8037 bool isPPC64 = Subtarget.
isPPC64();
8049 Op.getOperand(0),
Op.getOperand(1));
8056 Op.getOperand(0),
Op.getOperand(1));
8060 if (
Op.getValueType().isVector())
8061 return LowerVectorLoad(
Op, DAG);
8063 assert(
Op.getValueType() == MVT::i1 &&
8064 "Custom lowering only for i1 loads");
8077 BasePtr, MVT::i8, MMO);
8085 if (
Op.getOperand(1).getValueType().isVector())
8086 return LowerVectorStore(
Op, DAG);
8088 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
8089 "Custom lowering only for i1 stores");
8108 assert(
Op.getValueType() == MVT::i1 &&
8109 "Custom lowering only for i1 results");
8137 EVT TrgVT =
Op.getValueType();
8150 !llvm::has_single_bit<uint32_t>(
8161 if (SrcSize == 256) {
8172 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8180 for (
unsigned i = 0; i < TrgNumElts; ++i)
8183 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8187 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8200 EVT ResVT =
Op.getValueType();
8201 EVT CmpVT =
Op.getOperand(0).getValueType();
8203 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8209 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8226 if (Subtarget.hasP9Vector() && LHS == TV && RHS == FV) {
8258 if (
LHS.getValueType() == MVT::f32)
8271 if (
LHS.getValueType() == MVT::f32)
8280 if (
LHS.getValueType() == MVT::f32)
8294 if (
Cmp.getValueType() == MVT::f32)
8304 if (
Cmp.getValueType() == MVT::f32)
8310 if (
Cmp.getValueType() == MVT::f32)
8316 if (
Cmp.getValueType() == MVT::f32)
8322 if (
Cmp.getValueType() == MVT::f32)
8355 bool IsStrict =
Op->isStrictFPOpcode();
8361 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8364 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8366 MVT DestTy =
Op.getSimpleValueType();
8367 assert(Src.getValueType().isFloatingPoint() &&
8368 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8369 DestTy == MVT::i64) &&
8370 "Invalid FP_TO_INT types");
8371 if (Src.getValueType() == MVT::f32) {
8375 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8376 Chain = Src.getValue(1);
8380 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8381 DestTy = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
8390 assert((IsSigned || Subtarget.hasFPCVT()) &&
8391 "i64 FP_TO_UINT is supported only with FPCVT");
8394 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8398 Conv = DAG.
getNode(Opc, dl, DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src},
8401 Conv = DAG.
getNode(Opc, dl, ConvTy, Src);
8406void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8408 const SDLoc &dl)
const {
8412 bool IsStrict =
Op->isStrictFPOpcode();
8415 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8416 (IsSigned || Subtarget.hasFPCVT());
8418 int FI = cast<FrameIndexSDNode>(FIPtr)->getIndex();
8427 Alignment =
Align(4);
8430 SDValue Ops[] = { Chain, Tmp, FIPtr };
8432 DAG.
getVTList(MVT::Other), Ops, MVT::i32, MMO);
8434 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8438 if (
Op.getValueType() == MVT::i32 && !i32Stack) {
8447 RLI.Alignment = Alignment;
8455 const SDLoc &dl)
const {
8458 if (
Op->isStrictFPOpcode())
8465 const SDLoc &dl)
const {
8466 bool IsStrict =
Op->isStrictFPOpcode();
8469 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8470 EVT SrcVT = Src.getValueType();
8471 EVT DstVT =
Op.getValueType();
8474 if (SrcVT == MVT::f128)
8475 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8479 if (SrcVT == MVT::ppcf128) {
8480 if (DstVT == MVT::i32) {
8485 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8496 {Op.getOperand(0), Lo, Hi}, Flags);
8499 {Res.getValue(1), Res}, Flags);
8505 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8529 {Chain, Src, FltOfs}, Flags);
8533 {Chain, Val}, Flags);
8536 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8554 if (Subtarget.hasDirectMove() && Subtarget.
isPPC64())
8555 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8558 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8560 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8561 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8572bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8577 if (
Op->isStrictFPOpcode())
8582 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8586 Op.getOperand(0).getValueType())) {
8588 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8593 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8594 LD->isNonTemporal())
8596 if (
LD->getMemoryVT() != MemVT)
8606 RLI.Ptr =
LD->getBasePtr();
8607 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8609 "Non-pre-inc AM on PPC?");
8614 RLI.Chain =
LD->getChain();
8615 RLI.MPI =
LD->getPointerInfo();
8616 RLI.IsDereferenceable =
LD->isDereferenceable();
8617 RLI.IsInvariant =
LD->isInvariant();
8618 RLI.Alignment =
LD->getAlign();
8619 RLI.AAInfo =
LD->getAAInfo();
8620 RLI.Ranges =
LD->getRanges();
8622 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8630void PPCTargetLowering::spliceIntoChain(
SDValue ResChain,
8636 SDLoc dl(NewResChain);
8639 NewResChain, DAG.
getUNDEF(MVT::Other));
8641 "A new TF really is required here");
8650bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8651 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8658 if (!Subtarget.hasP9Vector() &&
8667 if (UI.getUse().get().getResNo() != 0)
8689 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8693 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8696 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8697 if (
Op->isStrictFPOpcode()) {
8699 Chain =
Op.getOperand(0);
8701 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8703 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8711 const SDLoc &dl)
const {
8712 assert((
Op.getValueType() == MVT::f32 ||
8713 Op.getValueType() == MVT::f64) &&
8714 "Invalid floating point type as target of conversion");
8715 assert(Subtarget.hasFPCVT() &&
8716 "Int to FP conversions with direct moves require FPCVT");
8717 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8718 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8740 for (
unsigned i = 1; i < NumConcat; ++i)
8747 const SDLoc &dl)
const {
8748 bool IsStrict =
Op->isStrictFPOpcode();
8749 unsigned Opc =
Op.getOpcode();
8750 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8753 "Unexpected conversion type");
8754 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8755 "Supports conversions to v2f64/v4f32 only.");
8759 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8762 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8767 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8770 for (
unsigned i = 0; i < WideNumElts; ++i)
8773 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8774 int SaveElts = FourEltRes ? 4 : 2;
8776 for (
int i = 0; i < SaveElts; i++)
8777 ShuffV[i * Stride] = i;
8779 for (
int i = 1; i <= SaveElts; i++)
8780 ShuffV[i * Stride - 1] = i - 1;
8788 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8789 EVT ExtVT = Src.getValueType();
8790 if (Subtarget.hasP9Altivec())
8801 {Op.getOperand(0), Extend}, Flags);
8803 return DAG.
getNode(Opc, dl,
Op.getValueType(), Extend);
8811 bool IsStrict =
Op->isStrictFPOpcode();
8812 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8817 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8819 EVT InVT = Src.getValueType();
8820 EVT OutVT =
Op.getValueType();
8823 return LowerINT_TO_FPVector(
Op, DAG, dl);
8826 if (
Op.getValueType() == MVT::f128)
8827 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8830 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8833 if (Src.getValueType() == MVT::i1) {
8845 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8846 Subtarget.
isPPC64() && Subtarget.hasFPCVT())
8847 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8849 assert((IsSigned || Subtarget.hasFPCVT()) &&
8850 "UINT_TO_FP is supported only with FPCVT");
8852 if (Src.getValueType() == MVT::i64) {
8864 if (
Op.getValueType() == MVT::f32 &&
8865 !Subtarget.hasFPCVT() &&
8906 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8907 Bits = DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8908 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8909 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8910 }
else if (Subtarget.hasLFIWAX() &&
8911 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8914 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8915 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8918 Ops, MVT::i32, MMO);
8919 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8920 }
else if (Subtarget.hasFPCVT() &&
8921 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8924 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8925 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8928 Ops, MVT::i32, MMO);
8929 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8930 }
else if (((Subtarget.hasLFIWAX() &&
8932 (Subtarget.hasFPCVT() &&
8946 assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
8947 "Expected an i32 store");
8953 RLI.Alignment =
Align(4);
8957 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8958 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8961 dl, DAG.
getVTList(MVT::f64, MVT::Other),
8962 Ops, MVT::i32, MMO);
8963 Chain =
Bits.getValue(1);
8969 Chain =
FP.getValue(1);
8971 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8975 {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
8983 assert(Src.getValueType() == MVT::i32 &&
8984 "Unhandled INT_TO_FP type in custom expander!");
8994 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
8997 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
9006 assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
9007 "Expected an i32 store");
9013 RLI.Alignment =
Align(4);
9018 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
9019 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
9021 DAG.
getVTList(MVT::f64, MVT::Other), Ops,
9025 spliceIntoChain(RLI.ResChain, Ld.
getValue(1), DAG);
9028 "i32->FP without LFIWAX supported only on PPC64");
9037 Chain, dl, Ext64, FIdx,
9043 MVT::f64, dl, Chain, FIdx,
9051 Chain =
FP.getValue(1);
9052 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
9056 {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
9087 EVT VT =
Op.getValueType();
9093 Chain =
MFFS.getValue(1);
9107 "Stack slot adjustment is valid only on big endian subtargets!");
9137 EVT VT =
Op.getValueType();
9141 VT ==
Op.getOperand(1).getValueType() &&
9161 SDValue OutOps[] = { OutLo, OutHi };
9166 EVT VT =
Op.getValueType();
9170 VT ==
Op.getOperand(1).getValueType() &&
9190 SDValue OutOps[] = { OutLo, OutHi };
9196 EVT VT =
Op.getValueType();
9199 VT ==
Op.getOperand(1).getValueType() &&
9219 SDValue OutOps[] = { OutLo, OutHi };
9226 EVT VT =
Op.getValueType();
9233 EVT AmtVT =
Z.getValueType();
9256 static const MVT VTys[] = {
9257 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9260 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9263 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9268 EVT CanonicalVT = VTys[SplatSize-1];
9277 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9278 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9287 EVT DestVT = MVT::Other) {
9288 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9297 EVT DestVT = MVT::Other) {
9300 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9312 for (
unsigned i = 0; i != 16; ++i)
9333 EVT VecVT = V->getValueType(0);
9334 bool RightType = VecVT == MVT::v2f64 ||
9335 (HasP8Vector && VecVT == MVT::v4f32) ||
9336 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9340 bool IsSplat =
true;
9341 bool IsLoad =
false;
9342 SDValue Op0 = V->getOperand(0);
9347 if (V->isConstant())
9349 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9350 if (V->getOperand(i).isUndef())
9354 if (V->getOperand(i).getOpcode() ==
ISD::LOAD ||
9356 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9358 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9360 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD))
9364 if (V->getOperand(i) != Op0 ||
9365 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9368 return !(IsSplat && IsLoad);
9380 if ((
Op.getValueType() != MVT::f128) ||
9382 (
Hi.getValueType() != MVT::i64) || !Subtarget.
isPPC64())
9402 LoadSDNode *LD = cast<LoadSDNode>(*InputLoad);
9410 APFloat APFloatToConvert = ArgAPFloat;
9411 bool LosesInfo =
true;
9416 ArgAPFloat = APFloatToConvert;
9438 APFloat APFloatToConvert = ArgAPFloat;
9439 bool LosesInfo =
true;
9443 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9448 LoadSDNode *InputNode = dyn_cast<LoadSDNode>(
Op.getOperand(0));
9452 EVT Ty =
Op->getValueType(0);
9455 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9464 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9468 if (Ty == MVT::v2i64) {
9471 if (MemVT == MVT::i32) {
9491 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9494 APInt APSplatBits, APSplatUndef;
9495 unsigned SplatBitSize;
9497 bool BVNIsConstantSplat =
9505 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9506 Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
9509 if ((
Op->getValueType(0) == MVT::v2f64) &&
9544 if (!BVNIsConstantSplat || SplatBitSize > 32) {
9551 const SDValue *InputLoad = &
Op.getOperand(0);
9556 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9557 unsigned ElementSize =
9560 assert(((ElementSize == 2 * MemorySize)
9564 "Unmatched element size and opcode!\n");
9569 unsigned NumUsesOfInputLD = 128 / ElementSize;
9571 if (BVInOp.isUndef())
9586 if (NumUsesOfInputLD == 1 &&
9589 Subtarget.hasLFIWAX()))
9598 Subtarget.isISA3_1() && ElementSize <= 16)
9601 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9603 Subtarget.hasVSX()) {
9610 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other), Ops,
9611 LD->getMemoryVT(),
LD->getMemOperand());
9623 if (Subtarget.hasVSX() && Subtarget.
isPPC64() &&
9625 Subtarget.hasP8Vector()))
9632 unsigned SplatSize = SplatBitSize / 8;
9637 if (SplatBits == 0) {
9639 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9651 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 2)
9653 Op.getValueType(), DAG, dl);
9655 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 4)
9660 if (Subtarget.hasP9Vector() && SplatSize == 1)
9665 int32_t SextVal= (int32_t(SplatBits << (32-SplatBitSize)) >>
9667 if (SextVal >= -16 && SextVal <= 15)
9680 if (SextVal >= -32 && SextVal <= 31) {
9685 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9686 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9689 if (VT ==
Op.getValueType())
9698 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9712 static const signed char SplatCsts[] = {
9713 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9714 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9717 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9720 int i = SplatCsts[idx];
9724 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9727 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9729 static const unsigned IIDs[] = {
9730 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9731 Intrinsic::ppc_altivec_vslw
9738 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9740 static const unsigned IIDs[] = {
9741 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9742 Intrinsic::ppc_altivec_vsrw
9749 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9750 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9752 static const unsigned IIDs[] = {
9753 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
9754 Intrinsic::ppc_altivec_vrlw
9761 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
9767 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
9773 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
9788 unsigned OpNum = (PFEntry >> 26) & 0x0F;
9789 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
9790 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
9806 if (LHSID == (1*9+2)*9+3)
return LHS;
9807 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
9819 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
9820 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
9821 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
9822 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
9825 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
9826 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
9827 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
9828 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
9831 for (
unsigned i = 0; i != 16; ++i)
9832 ShufIdxs[i] = (i&3)+0;
9835 for (
unsigned i = 0; i != 16; ++i)
9836 ShufIdxs[i] = (i&3)+4;
9839 for (
unsigned i = 0; i != 16; ++i)
9840 ShufIdxs[i] = (i&3)+8;
9843 for (
unsigned i = 0; i != 16; ++i)
9844 ShufIdxs[i] = (i&3)+12;
9865 const unsigned BytesInVector = 16;
9870 unsigned ShiftElts = 0, InsertAtByte = 0;
9874 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
9875 0, 15, 14, 13, 12, 11, 10, 9};
9876 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
9877 1, 2, 3, 4, 5, 6, 7, 8};
9880 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
9892 bool FoundCandidate =
false;
9896 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
9899 for (
unsigned i = 0; i < BytesInVector; ++i) {
9900 unsigned CurrentElement =
Mask[i];
9903 if (
V2.isUndef() && CurrentElement != VINSERTBSrcElem)
9906 bool OtherElementsInOrder =
true;
9909 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
9916 (!
V2.isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
9917 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
9918 OtherElementsInOrder =
false;
9925 if (OtherElementsInOrder) {
9932 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
9933 : BigEndianShifts[CurrentElement & 0xF];
9934 Swap = CurrentElement < BytesInVector;
9936 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
9937 FoundCandidate =
true;
9942 if (!FoundCandidate)
9966 const unsigned NumHalfWords = 8;
9967 const unsigned BytesInVector = NumHalfWords * 2;
9976 unsigned ShiftElts = 0, InsertAtByte = 0;
9980 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
9981 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
9984 uint32_t OriginalOrderLow = 0x1234567;
9985 uint32_t OriginalOrderHigh = 0x89ABCDEF;
9988 for (
unsigned i = 0; i < NumHalfWords; ++i) {
9989 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10006 bool FoundCandidate =
false;
10009 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10010 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10018 if (
V2.isUndef()) {
10020 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
10021 TargetOrder = OriginalOrderLow;
10025 if (MaskOneElt == VINSERTHSrcElem &&
10026 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10027 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10028 FoundCandidate =
true;
10034 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
10036 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10038 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
10039 : BigEndianShifts[MaskOneElt & 0x7];
10040 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10041 Swap = MaskOneElt < NumHalfWords;
10042 FoundCandidate =
true;
10048 if (!FoundCandidate)
10083 auto ShuffleMask = SVN->
getMask();
10098 ShuffleMask = CommutedSV->
getMask();
10107 APInt APSplatValue, APSplatUndef;
10108 unsigned SplatBitSize;
10124 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
10125 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
10126 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
10128 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
10129 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
10130 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
10138 for (; SplatBitSize < 32; SplatBitSize <<= 1)
10139 SplatVal |= (SplatVal << SplatBitSize);
10153 assert(
Op.getValueType() == MVT::v1i128 &&
10154 "Only set v1i128 as custom, other type shouldn't reach here!");
10159 if (SHLAmt % 8 == 0) {
10160 std::array<int, 16>
Mask;
10161 std::iota(
Mask.begin(),
Mask.end(), 0);
10162 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10191 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10192 if (!isa<ShuffleVectorSDNode>(NewShuffle))
10195 SVOp = cast<ShuffleVectorSDNode>(
Op);
10196 V1 =
Op.getOperand(0);
10197 V2 =
Op.getOperand(1);
10199 EVT VT =
Op.getValueType();
10202 unsigned ShiftElts, InsertAtByte;
10208 bool IsPermutedLoad =
false;
10210 if (InputLoad && Subtarget.hasVSX() &&
V2.isUndef() &&
10220 if (IsPermutedLoad) {
10221 assert((isLittleEndian || IsFourByte) &&
10222 "Unexpected size for permuted load on big endian target");
10223 SplatIdx += IsFourByte ? 2 : 1;
10224 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10225 "Splat of a value outside of the loaded memory");
10230 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10233 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10235 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10239 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10252 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10255 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10264 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10267 if (Subtarget.hasP9Vector() &&
10288 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
10290 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10291 return SplatInsertNode;
10294 if (Subtarget.hasP9Altivec()) {
10296 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10299 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10303 if (Subtarget.hasVSX() &&
10316 if (Subtarget.hasVSX() &&
10329 if (Subtarget.hasP9Vector()) {
10349 if (Subtarget.hasVSX()) {
10370 if (
V2.isUndef()) {
10383 (Subtarget.hasP8Altivec() && (
10394 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10404 (Subtarget.hasP8Altivec() && (
10415 unsigned PFIndexes[4];
10416 bool isFourElementShuffle =
true;
10417 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10419 unsigned EltNo = 8;
10420 for (
unsigned j = 0;
j != 4; ++
j) {
10421 if (PermMask[i * 4 + j] < 0)
10424 unsigned ByteSource = PermMask[i * 4 +
j];
10425 if ((ByteSource & 3) != j) {
10426 isFourElementShuffle =
false;
10431 EltNo = ByteSource / 4;
10432 }
else if (EltNo != ByteSource / 4) {
10433 isFourElementShuffle =
false;
10437 PFIndexes[i] = EltNo;
10445 if (isFourElementShuffle) {
10447 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10448 PFIndexes[2] * 9 + PFIndexes[3];
10451 unsigned Cost = (PFEntry >> 30);
10471 if (
V2.isUndef())
V2 = V1;
10473 return LowerVPERM(
Op, DAG, PermMask, VT, V1, V2);
10482 bool NeedSwap =
false;
10484 bool isPPC64 = Subtarget.
isPPC64();
10486 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10488 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10489 "XXPERM instead\n");
10495 if ((!isLittleEndian && !
V2->hasOneUse() && V1->
hasOneUse()) ||
10496 (isLittleEndian && !V1->
hasOneUse() &&
V2->hasOneUse())) {
10498 NeedSwap = !NeedSwap;
10533 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10535 if (V1HasXXSWAPD) {
10538 else if (SrcElt < 16)
10541 if (V2HasXXSWAPD) {
10544 else if (SrcElt > 15)
10553 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10554 if (isLittleEndian)
10556 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10559 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10562 if (V1HasXXSWAPD) {
10566 if (V2HasXXSWAPD) {
10567 dl =
SDLoc(
V2->getOperand(0));
10568 V2 =
V2->getOperand(0)->getOperand(1);
10571 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10572 if (ValType != MVT::v2f64)
10574 if (
V2.getValueType() != MVT::v2f64)
10578 ShufflesHandledWithVPERM++;
10583 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10585 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10588 dbgs() <<
"With the following permute control vector:\n";
10593 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10597 if (isLittleEndian)
10603 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10615 switch (IntrinsicID) {
10619 case Intrinsic::ppc_altivec_vcmpbfp_p:
10623 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10627 case Intrinsic::ppc_altivec_vcmpequb_p:
10631 case Intrinsic::ppc_altivec_vcmpequh_p:
10635 case Intrinsic::ppc_altivec_vcmpequw_p:
10639 case Intrinsic::ppc_altivec_vcmpequd_p:
10640 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10646 case Intrinsic::ppc_altivec_vcmpneb_p:
10647 case Intrinsic::ppc_altivec_vcmpneh_p:
10648 case Intrinsic::ppc_altivec_vcmpnew_p:
10649 case Intrinsic::ppc_altivec_vcmpnezb_p:
10650 case Intrinsic::ppc_altivec_vcmpnezh_p:
10651 case Intrinsic::ppc_altivec_vcmpnezw_p:
10652 if (Subtarget.hasP9Altivec()) {
10653 switch (IntrinsicID) {
10656 case Intrinsic::ppc_altivec_vcmpneb_p:
10659 case Intrinsic::ppc_altivec_vcmpneh_p:
10662 case Intrinsic::ppc_altivec_vcmpnew_p:
10665 case Intrinsic::ppc_altivec_vcmpnezb_p:
10668 case Intrinsic::ppc_altivec_vcmpnezh_p:
10671 case Intrinsic::ppc_altivec_vcmpnezw_p:
10679 case Intrinsic::ppc_altivec_vcmpgefp_p:
10683 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10687 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10691 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10695 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10699 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10700 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10706 case Intrinsic::ppc_altivec_vcmpgtub_p:
10710 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10714 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10718 case Intrinsic::ppc_altivec_vcmpgtud_p:
10719 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10726 case Intrinsic::ppc_altivec_vcmpequq:
10727 case Intrinsic::ppc_altivec_vcmpgtsq:
10728 case Intrinsic::ppc_altivec_vcmpgtuq:
10729 if (!Subtarget.isISA3_1())
10731 switch (IntrinsicID) {
10734 case Intrinsic::ppc_altivec_vcmpequq:
10737 case Intrinsic::ppc_altivec_vcmpgtsq:
10740 case Intrinsic::ppc_altivec_vcmpgtuq:
10747 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10748 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10749 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10750 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10751 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10752 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10753 if (Subtarget.hasVSX()) {
10754 switch (IntrinsicID) {
10755 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10758 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10761 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10764 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10767 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10770 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10780 case Intrinsic::ppc_altivec_vcmpbfp:
10783 case Intrinsic::ppc_altivec_vcmpeqfp:
10786 case Intrinsic::ppc_altivec_vcmpequb:
10789 case Intrinsic::ppc_altivec_vcmpequh:
10792 case Intrinsic::ppc_altivec_vcmpequw:
10795 case Intrinsic::ppc_altivec_vcmpequd:
10796 if (Subtarget.hasP8Altivec())
10801 case Intrinsic::ppc_altivec_vcmpneb:
10802 case Intrinsic::ppc_altivec_vcmpneh:
10803 case Intrinsic::ppc_altivec_vcmpnew:
10804 case Intrinsic::ppc_altivec_vcmpnezb:
10805 case Intrinsic::ppc_altivec_vcmpnezh:
10806 case Intrinsic::ppc_altivec_vcmpnezw:
10807 if (Subtarget.hasP9Altivec())
10808 switch (IntrinsicID) {
10811 case Intrinsic::ppc_altivec_vcmpneb:
10814 case Intrinsic::ppc_altivec_vcmpneh:
10817 case Intrinsic::ppc_altivec_vcmpnew:
10820 case Intrinsic::ppc_altivec_vcmpnezb:
10823 case Intrinsic::ppc_altivec_vcmpnezh:
10826 case Intrinsic::ppc_altivec_vcmpnezw:
10833 case Intrinsic::ppc_altivec_vcmpgefp:
10836 case Intrinsic::ppc_altivec_vcmpgtfp:
10839 case Intrinsic::ppc_altivec_vcmpgtsb:
10842 case Intrinsic::ppc_altivec_vcmpgtsh:
10845 case Intrinsic::ppc_altivec_vcmpgtsw:
10848 case Intrinsic::ppc_altivec_vcmpgtsd:
10849 if (Subtarget.hasP8Altivec())
10854 case Intrinsic::ppc_altivec_vcmpgtub:
10857 case Intrinsic::ppc_altivec_vcmpgtuh:
10860 case Intrinsic::ppc_altivec_vcmpgtuw:
10863 case Intrinsic::ppc_altivec_vcmpgtud:
10864 if (Subtarget.hasP8Altivec())
10869 case Intrinsic::ppc_altivec_vcmpequq_p:
10870 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10871 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10872 if (!Subtarget.isISA3_1())
10874 switch (IntrinsicID) {
10877 case Intrinsic::ppc_altivec_vcmpequq_p:
10880 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10883 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10897 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
10901 switch (IntrinsicID) {
10902 case Intrinsic::thread_pointer:
10908 case Intrinsic::ppc_rldimi: {
10909 assert(Subtarget.
isPPC64() &&
"rldimi is only available in 64-bit!");
10913 return Op.getOperand(2);
10914 if (
Mask.isAllOnes())
10917 unsigned MB = 0, ME = 0;
10921 if (ME < 63 - SH) {
10924 }
else if (ME > 63 - SH) {
10930 {Op.getOperand(2), Src,
10931 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
10932 DAG.getTargetConstant(MB, dl, MVT::i32)}),
10936 case Intrinsic::ppc_rlwimi: {
10939 return Op.getOperand(2);
10940 if (
Mask.isAllOnes())
10943 unsigned MB = 0, ME = 0;
10947 PPC::RLWIMI, dl, MVT::i32,
10948 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
10949 DAG.getTargetConstant(MB, dl, MVT::i32),
10950 DAG.getTargetConstant(ME, dl, MVT::i32)}),
10954 case Intrinsic::ppc_rlwnm: {
10955 if (
Op.getConstantOperandVal(3) == 0)
10957 unsigned MB = 0, ME = 0;
10962 {Op.getOperand(1), Op.getOperand(2),
10963 DAG.getTargetConstant(MB, dl, MVT::i32),
10964 DAG.getTargetConstant(ME, dl, MVT::i32)}),
10968 case Intrinsic::ppc_mma_disassemble_acc: {
10969 if (Subtarget.isISAFuture()) {
10970 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11008 case Intrinsic::ppc_vsx_disassemble_pair: {
11011 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
11016 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
11027 case Intrinsic::ppc_mma_xxmfacc:
11028 case Intrinsic::ppc_mma_xxmtacc: {
11030 if (!Subtarget.isISAFuture())
11041 case Intrinsic::ppc_unpack_longdouble: {
11042 auto *
Idx = dyn_cast<ConstantSDNode>(
Op.getOperand(2));
11043 assert(
Idx && (
Idx->getSExtValue() == 0 ||
Idx->getSExtValue() == 1) &&
11044 "Argument of long double unpack must be 0 or 1!");
11047 Idx->getValueType(0)));
11050 case Intrinsic::ppc_compare_exp_lt:
11051 case Intrinsic::ppc_compare_exp_gt:
11052 case Intrinsic::ppc_compare_exp_eq:
11053 case Intrinsic::ppc_compare_exp_uo: {
11055 switch (IntrinsicID) {
11056 case Intrinsic::ppc_compare_exp_lt:
11059 case Intrinsic::ppc_compare_exp_gt:
11062 case Intrinsic::ppc_compare_exp_eq:
11065 case Intrinsic::ppc_compare_exp_uo:
11071 PPC::SELECT_CC_I4, dl, MVT::i32,
11072 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
11073 Op.getOperand(1), Op.getOperand(2)),
11075 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11076 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
11079 case Intrinsic::ppc_test_data_class: {
11080 EVT OpVT =
Op.getOperand(1).getValueType();
11081 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
11082 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
11086 PPC::SELECT_CC_I4, dl, MVT::i32,
11087 {SDValue(DAG.getMachineNode(CmprOpc, dl, MVT::i32, Op.getOperand(2),
11090 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11091 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
11094 case Intrinsic::ppc_fnmsub: {
11095 EVT VT =
Op.getOperand(1).getValueType();
11096 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
11102 Op.getOperand(2),
Op.getOperand(3));
11104 case Intrinsic::ppc_convert_f128_to_ppcf128:
11105 case Intrinsic::ppc_convert_ppcf128_to_f128: {
11106 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
11107 ? RTLIB::CONVERT_PPCF128_F128
11108 : RTLIB::CONVERT_F128_PPCF128;
11109 MakeLibCallOptions CallOptions;
11110 std::pair<SDValue, SDValue>
Result =
11111 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
11115 case Intrinsic::ppc_maxfe:
11116 case Intrinsic::ppc_maxfl:
11117 case Intrinsic::ppc_maxfs:
11118 case Intrinsic::ppc_minfe:
11119 case Intrinsic::ppc_minfl:
11120 case Intrinsic::ppc_minfs: {
11121 EVT VT =
Op.getValueType();
11124 [VT](
const SDUse &
Use) { return Use.getValueType() == VT; }) &&
11125 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
11128 if (IntrinsicID == Intrinsic::ppc_minfe ||
11129 IntrinsicID == Intrinsic::ppc_minfl ||
11130 IntrinsicID == Intrinsic::ppc_minfs)
11152 Op.getOperand(1),
Op.getOperand(2),
11163 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11175 switch (
Op.getConstantOperandVal(1)) {
11178 BitNo = 0; InvertBit =
false;
11181 BitNo = 0; InvertBit =
true;
11184 BitNo = 2; InvertBit =
false;
11187 BitNo = 2; InvertBit =
true;
11209 int ArgStart = isa<ConstantSDNode>(
Op.getOperand(0)) ? 0 : 1;
11211 switch (
Op.getConstantOperandVal(ArgStart)) {
11212 case Intrinsic::ppc_cfence: {
11213 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11214 SDValue Val =
Op.getOperand(ArgStart + 1);
11216 if (Ty == MVT::i128) {
11221 unsigned Opcode = Subtarget.
isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11222 EVT FTy = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
11246 int VectorIndex = 0;
11259 "Expecting an atomic compare-and-swap here.");
11261 auto *AtomicNode = cast<AtomicSDNode>(
Op.getNode());
11262 EVT MemVT = AtomicNode->getMemoryVT();
11280 for (
int i = 0, e = AtomicNode->getNumOperands(); i <
e; i++)
11281 Ops.
push_back(AtomicNode->getOperand(i));
11293 EVT MemVT =
N->getMemoryVT();
11295 "Expect quadword atomic operations");
11297 unsigned Opc =
N->getOpcode();
11305 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11306 for (
int I = 1, E =
N->getNumOperands();
I < E; ++
I)
11309 Ops, MemVT,
N->getMemOperand());
11316 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11326 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11336 N->getMemOperand());
11348 enum DataClassMask {
11350 DC_NEG_INF = 1 << 4,
11351 DC_POS_INF = 1 << 5,
11352 DC_NEG_ZERO = 1 << 2,
11353 DC_POS_ZERO = 1 << 3,
11354 DC_NEG_SUBNORM = 1,
11355 DC_POS_SUBNORM = 1 << 1,
11358 EVT VT =
Op.getValueType();
11360 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11361 : VT == MVT::f64 ? PPC::XSTSTDCDP
11372 return DAG.
getNOT(Dl, Rev, MVT::i1);
11379 TestOp, Dl, MVT::i32,
11381 DC_NEG_ZERO | DC_POS_ZERO |
11382 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11388 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11394 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11399 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11412 bool IsQuiet = Mask &
fcQNan;
11418 if (VT == MVT::f128) {
11422 QuietMask = 0x8000;
11423 }
else if (VT == MVT::f64) {
11435 QuietMask = 0x80000;
11436 }
else if (VT == MVT::f32) {
11438 QuietMask = 0x400000;
11454 unsigned NativeMask = 0;
11456 NativeMask |= DC_NAN;
11458 NativeMask |= DC_NEG_INF;
11460 NativeMask |= DC_POS_INF;
11462 NativeMask |= DC_NEG_ZERO;
11464 NativeMask |= DC_POS_ZERO;
11466 NativeMask |= DC_NEG_SUBNORM;
11468 NativeMask |= DC_POS_SUBNORM;
11471 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11473 TestOp, Dl, MVT::i32,
11482 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11484 uint64_t RHSC =
Op.getConstantOperandVal(1);
11512 64 -
Op.getValueType().getScalarSizeInBits(), dl, ShiftAmountTy);
11519 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx,
11533 "Should only be called for ISD::INSERT_VECTOR_ELT");
11537 EVT VT =
Op.getValueType();
11542 if (VT == MVT::v2f64 &&
C)
11545 if (Subtarget.hasP9Vector()) {
11554 if ((VT == MVT::v4f32) && (
V2.getValueType() == MVT::f32) &&
11555 (isa<LoadSDNode>(V2))) {
11560 BitcastLoad,
Op.getOperand(2));
11561 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
11565 if (Subtarget.isISA3_1()) {
11566 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.
isPPC64())
11570 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
11571 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
11581 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
11584 unsigned InsertAtElement =
C->getZExtValue();
11585 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
11587 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
11601 EVT VT =
Op.getValueType();
11603 if (VT != MVT::v256i1 && VT != MVT::v512i1)
11609 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
11610 "Type unsupported without MMA");
11611 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
11612 "Type unsupported without paired vector support");
11617 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
11619 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
11629 std::reverse(Loads.
begin(), Loads.
end());
11630 std::reverse(LoadChains.
begin(), LoadChains.
end());
11648 EVT StoreVT =
Value.getValueType();
11650 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
11656 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
11657 "Type unsupported without MMA");
11658 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
11659 "Type unsupported without paired vector support");
11662 unsigned NumVecs = 2;
11663 if (StoreVT == MVT::v512i1) {
11664 if (Subtarget.isISAFuture()) {
11665 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11667 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
11670 Value2 =
SDValue(ExtNode, 1);
11675 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
11678 if (Subtarget.isISAFuture()) {
11688 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
11702 if (
Op.getValueType() == MVT::v4i32) {
11719 LHS, RHS, DAG, dl, MVT::v4i32);
11722 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
11727 }
else if (
Op.getValueType() == MVT::v16i8) {
11733 LHS, RHS, DAG, dl, MVT::v8i16);
11738 LHS, RHS, DAG, dl, MVT::v8i16);
11746 for (
unsigned i = 0; i != 8; ++i) {
11747 if (isLittleEndian) {
11749 Ops[i*2+1] = 2*i+16;
11752 Ops[i*2+1] = 2*i+1+16;
11755 if (isLittleEndian)
11765 bool IsStrict =
Op->isStrictFPOpcode();
11766 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
11767 !Subtarget.hasP9Vector())
11777 "Should only be called for ISD::FP_EXTEND");
11781 if (
Op.getValueType() != MVT::v2f64 ||
11782 Op.getOperand(0).getValueType() != MVT::v2f32)
11794 "Node should have 2 operands with second one being a constant!");
11806 int DWord =
Idx >> 1;
11829 LD->getMemoryVT(),
LD->getMemOperand());
11842 LD->getMemoryVT(),
LD->getMemOperand());
11853 switch (
Op.getOpcode()) {
11882 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
11908 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
11909 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
11921 return LowerFP_ROUND(
Op, DAG);
11934 return LowerINTRINSIC_VOID(
Op, DAG);
11936 return LowerBSWAP(
Op, DAG);
11938 return LowerATOMIC_CMP_SWAP(
Op, DAG);
11940 return LowerATOMIC_LOAD_STORE(
Op, DAG);
11942 return LowerIS_FPCLASS(
Op, DAG);
11950 switch (
N->getOpcode()) {
11952 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
11969 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
11972 assert(
N->getValueType(0) == MVT::i1 &&
11973 "Unexpected result type for CTR decrement intrinsic");
11975 N->getValueType(0));
11985 switch (
N->getConstantOperandVal(0)) {
11986 case Intrinsic::ppc_pack_longdouble:
11988 N->getOperand(2),
N->getOperand(1)));
11990 case Intrinsic::ppc_maxfe:
11991 case Intrinsic::ppc_minfe:
11992 case Intrinsic::ppc_fnmsub:
11993 case Intrinsic::ppc_convert_f128_to_ppcf128:
12003 EVT VT =
N->getValueType(0);
12005 if (VT == MVT::i64) {
12018 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
12022 Results.push_back(LoweredValue);
12023 if (
N->isStrictFPOpcode())
12028 if (!
N->getValueType(0).isVector())
12079 if (isa<LoadInst>(Inst))
12083 Intrinsic::ppc_cfence, {Inst->getType()}),
12093 unsigned AtomicSize,
12094 unsigned BinOpcode,
12095 unsigned CmpOpcode,
12096 unsigned CmpPred)
const {
12100 auto LoadMnemonic = PPC::LDARX;
12101 auto StoreMnemonic = PPC::STDCX;
12102 switch (AtomicSize) {
12106 LoadMnemonic = PPC::LBARX;
12107 StoreMnemonic = PPC::STBCX;
12108 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12111 LoadMnemonic = PPC::LHARX;
12112 StoreMnemonic = PPC::STHCX;
12113 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12116 LoadMnemonic = PPC::LWARX;
12117 StoreMnemonic = PPC::STWCX;
12120 LoadMnemonic = PPC::LDARX;
12121 StoreMnemonic = PPC::STDCX;
12137 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12139 F->insert(It, loopMBB);
12141 F->insert(It, loop2MBB);
12142 F->insert(It, exitMBB);
12148 Register TmpReg = (!BinOpcode) ? incr :
12150 : &PPC::GPRCRegClass);
12175 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
12182 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
12184 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
12212 switch(
MI.getOpcode()) {
12216 return TII->isSignExtended(
MI.getOperand(1).getReg(),
12217 &
MI.getMF()->getRegInfo());
12241 case PPC::EXTSB8_32_64:
12242 case PPC::EXTSB8_rec:
12243 case PPC::EXTSB_rec:
12246 case PPC::EXTSH8_32_64:
12247 case PPC::EXTSH8_rec:
12248 case PPC::EXTSH_rec:
12250 case PPC::EXTSWSLI:
12251 case PPC::EXTSWSLI_32_64:
12252 case PPC::EXTSWSLI_32_64_rec:
12253 case PPC::EXTSWSLI_rec:
12254 case PPC::EXTSW_32:
12255 case PPC::EXTSW_32_64:
12256 case PPC::EXTSW_32_64_rec:
12257 case PPC::EXTSW_rec:
12260 case PPC::SRAWI_rec:
12261 case PPC::SRAW_rec:
12270 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
12280 bool IsSignExtended =
12283 if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
12285 BuildMI(*BB,
MI, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
12286 .
addReg(
MI.getOperand(3).getReg());
12287 MI.getOperand(3).setReg(ValueReg);
12291 if (Subtarget.hasPartwordAtomics())
12299 bool is64bit = Subtarget.
isPPC64();
12301 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
12312 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12314 F->insert(It, loopMBB);
12316 F->insert(It, loop2MBB);
12317 F->insert(It, exitMBB);
12323 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12368 if (ptrA != ZeroReg) {
12370 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
12378 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
12379 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
12382 .
addImm(is8bit ? 28 : 27);
12383 if (!isLittleEndian)
12384 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
12386 .
addImm(is8bit ? 24 : 16);
12388 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
12393 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
12403 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
12407 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
12412 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
12416 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
12419 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
12431 unsigned ValueReg = SReg;
12432 unsigned CmpReg = Incr2Reg;
12433 if (CmpOpcode == PPC::CMPW) {
12435 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
12439 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
12441 ValueReg = ValueSReg;
12473 .
addImm(is8bit ? 24 : 16)
12494 Register DstReg =
MI.getOperand(0).getReg();
12496 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
12497 Register mainDstReg =
MRI.createVirtualRegister(RC);
12498 Register restoreDstReg =
MRI.createVirtualRegister(RC);
12501 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
12502 "Invalid Pointer Size!");
12550 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
12551 Register BufReg =
MI.getOperand(1).getReg();
12566 BaseReg = Subtarget.
isPPC64() ? PPC::X1 : PPC::R1;
12568 BaseReg = Subtarget.
isPPC64() ? PPC::BP8 : PPC::BP;
12571 TII->get(Subtarget.
isPPC64() ? PPC::STD : PPC::STW))
12594 TII->get(Subtarget.
isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
12615 TII->get(PPC::PHI), DstReg)
12619 MI.eraseFromParent();
12633 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
12634 "Invalid Pointer Size!");
12637 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12640 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
12641 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
12655 Register BufReg =
MI.getOperand(0).getReg();
12660 if (PVT == MVT::i64) {
12672 if (PVT == MVT::i64) {
12684 if (PVT == MVT::i64) {
12696 if (PVT == MVT::i64) {
12708 if (PVT == MVT::i64 && Subtarget.
isSVR4ABI()) {
12718 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
12721 MI.eraseFromParent();
12737 "Unexpected stack alignment");
12741 unsigned StackProbeSize =
12744 StackProbeSize &= ~(StackAlign - 1);
12745 return StackProbeSize ? StackProbeSize : StackAlign;
12757 const bool isPPC64 = Subtarget.
isPPC64();
12789 MF->
insert(MBBIter, TestMBB);
12790 MF->
insert(MBBIter, BlockMBB);
12791 MF->
insert(MBBIter, TailMBB);
12796 Register DstReg =
MI.getOperand(0).getReg();
12797 Register NegSizeReg =
MI.getOperand(1).getReg();
12798 Register SPReg = isPPC64 ? PPC::X1 : PPC::R1;
12799 Register FinalStackPtr =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12800 Register FramePointer =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12801 Register ActualNegSizeReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12807 if (!
MRI.hasOneNonDBGUse(NegSizeReg))
12809 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
12815 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
12816 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
12818 .
addDef(ActualNegSizeReg)
12820 .
add(
MI.getOperand(2))
12821 .
add(
MI.getOperand(3));
12827 .
addReg(ActualNegSizeReg);
12830 int64_t NegProbeSize = -(int64_t)ProbeSize;
12831 assert(isInt<32>(NegProbeSize) &&
"Unhandled probe size!");
12832 Register ScratchReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12833 if (!isInt<16>(NegProbeSize)) {
12834 Register TempReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12836 .
addImm(NegProbeSize >> 16);
12840 .
addImm(NegProbeSize & 0xFFFF);
12847 Register Div =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12849 .
addReg(ActualNegSizeReg)
12851 Register Mul =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12855 Register NegMod =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12858 .
addReg(ActualNegSizeReg);
12867 Register CmpResult =
MRI.createVirtualRegister(&PPC::CRRCRegClass);
12868 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
12882 BuildMI(BlockMBB,
DL,
TII->get(isPPC64 ? PPC::STDUX : PPC::STWUX), SPReg)
12893 MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12895 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
12896 MaxCallFrameSizeReg)
12897 .
add(
MI.getOperand(2))
12898 .
add(
MI.getOperand(3));
12899 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
12901 .
addReg(MaxCallFrameSizeReg);
12910 MI.eraseFromParent();
12912 ++NumDynamicAllocaProbed;
12917 switch (
MI.getOpcode()) {
12918 case PPC::SELECT_CC_I4:
12919 case PPC::SELECT_CC_I8:
12920 case PPC::SELECT_CC_F4:
12921 case PPC::SELECT_CC_F8:
12922 case PPC::SELECT_CC_F16:
12923 case PPC::SELECT_CC_VRRC:
12924 case PPC::SELECT_CC_VSFRC:
12925 case PPC::SELECT_CC_VSSRC:
12926 case PPC::SELECT_CC_VSRC:
12927 case PPC::SELECT_CC_SPE4:
12928 case PPC::SELECT_CC_SPE:
12936 switch (
MI.getOpcode()) {
12937 case PPC::SELECT_I4:
12938 case PPC::SELECT_I8:
12939 case PPC::SELECT_F4:
12940 case PPC::SELECT_F8:
12941 case PPC::SELECT_F16:
12942 case PPC::SELECT_SPE:
12943 case PPC::SELECT_SPE4:
12944 case PPC::SELECT_VRRC:
12945 case PPC::SELECT_VSFRC:
12946 case PPC::SELECT_VSSRC:
12947 case PPC::SELECT_VSRC:
12957 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
12958 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
12960 MI.getOpcode() == TargetOpcode::PATCHPOINT &&
12973 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
12974 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
12976 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
12977 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
12991 if (Subtarget.hasISEL() &&
12992 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
12993 MI.getOpcode() == PPC::SELECT_CC_I8 ||
12994 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
12996 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
12997 MI.getOpcode() == PPC::SELECT_CC_I8)
12998 Cond.push_back(
MI.getOperand(4));
13001 Cond.push_back(
MI.getOperand(1));
13004 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
13005 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
13021 F->insert(It, copy0MBB);
13022 F->insert(It, sinkMBB);
13026 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
13041 .
addReg(
MI.getOperand(1).getReg())
13044 unsigned SelectPred =
MI.getOperand(4).getImm();
13047 .
addReg(
MI.getOperand(1).getReg())
13064 .
addReg(
MI.getOperand(3).getReg())
13066 .
addReg(
MI.getOperand(2).getReg())
13068 }
else if (
MI.getOpcode() == PPC::ReadTB) {
13084 F->insert(It, readMBB);
13085 F->insert(It, sinkMBB);
13106 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
13116 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
13118 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
13120 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
13122 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
13125 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
13127 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
13129 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
13131 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
13134 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
13136 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
13138 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
13140 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
13143 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
13145 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
13147 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
13149 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
13152 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
13154 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
13156 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
13158 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
13161 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
13163 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
13165 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
13167 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
13170 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
13172 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
13174 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
13176 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
13179 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
13181 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
13183 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
13185 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
13188 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
13190 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
13192 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
13194 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
13197 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
13199 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
13201 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
13203 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
13206 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
13208 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
13210 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
13212 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
13214 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
13215 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
13216 (Subtarget.hasPartwordAtomics() &&
13217 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
13218 (Subtarget.hasPartwordAtomics() &&
13219 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
13220 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
13222 auto LoadMnemonic = PPC::LDARX;
13223 auto StoreMnemonic = PPC::STDCX;
13224 switch (
MI.getOpcode()) {
13227 case PPC::ATOMIC_CMP_SWAP_I8:
13228 LoadMnemonic = PPC::LBARX;
13229 StoreMnemonic = PPC::STBCX;
13230 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13232 case PPC::ATOMIC_CMP_SWAP_I16:
13233 LoadMnemonic = PPC::LHARX;
13234 StoreMnemonic = PPC::STHCX;
13235 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13237 case PPC::ATOMIC_CMP_SWAP_I32:
13238 LoadMnemonic = PPC::LWARX;
13239 StoreMnemonic = PPC::STWCX;
13241 case PPC::ATOMIC_CMP_SWAP_I64:
13242 LoadMnemonic = PPC::LDARX;
13243 StoreMnemonic = PPC::STDCX;
13251 Register oldval =
MI.getOperand(3).getReg();
13252 Register newval =
MI.getOperand(4).getReg();
13258 F->insert(It, loop1MBB);
13259 F->insert(It, loop2MBB);
13260 F->insert(It, exitMBB);
13281 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
13307 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
13308 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
13312 bool is64bit = Subtarget.
isPPC64();
13314 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
13319 Register oldval =
MI.getOperand(3).getReg();
13320 Register newval =
MI.getOperand(4).getReg();
13326 F->insert(It, loop1MBB);
13327 F->insert(It, loop2MBB);
13328 F->insert(It, exitMBB);
13335 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13354 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13386 if (ptrA != ZeroReg) {
13388 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13397 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13398 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
13401 .
addImm(is8bit ? 28 : 27);
13402 if (!isLittleEndian)
13403 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13405 .
addImm(is8bit ? 24 : 16);
13407 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13412 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13417 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
13420 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
13427 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13431 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13434 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
13437 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
13442 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13459 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13483 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
13508 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
13516 }
else if (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
13517 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT ||
13518 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
13519 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
13520 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
13521 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
13524 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
13525 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
13529 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
13533 .
addReg(
MI.getOperand(1).getReg())
13536 MI.getOperand(0).getReg())
13537 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
13538 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
13544 MI.getOperand(0).getReg())
13546 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
13548 unsigned Imm =
MI.getOperand(1).getImm();
13551 MI.getOperand(0).getReg())
13553 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
13555 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13558 if (
MRI.use_empty(OldFPSCRReg))
13559 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
13561 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13572 unsigned Mode =
MI.getOperand(1).getImm();
13573 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
13577 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
13580 }
else if (
MI.getOpcode() == PPC::SETRND) {
13588 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
13589 if (Subtarget.hasDirectMove()) {
13590 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
13594 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
13597 if (RC == &PPC::F8RCRegClass) {
13600 "Unsupported RegClass.");
13602 StoreOp = PPC::STFD;
13607 (RegInfo.
getRegClass(DestReg) == &PPC::F8RCRegClass) &&
13608 "Unsupported RegClass.");
13641 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13644 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13658 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
13666 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
13667 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
13673 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
13680 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
13689 }
else if (
MI.getOpcode() == PPC::SETFLM) {
13693 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13694 if (
MRI.use_empty(OldFPSCRReg))
13695 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
13697 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13700 Register NewFPSCRReg =
MI.getOperand(1).getReg();
13706 }
else if (
MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
13707 MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
13709 }
else if (
MI.getOpcode() == PPC::SPLIT_QUADWORD) {
13716 .
addUse(Src, 0, PPC::sub_gp8_x1);
13719 .
addUse(Src, 0, PPC::sub_gp8_x0);
13720 }
else if (
MI.getOpcode() == PPC::LQX_PSEUDO ||
13721 MI.getOpcode() == PPC::STQX_PSEUDO) {
13727 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
13733 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
13734 :
TII->get(PPC::STQ))
13742 MI.eraseFromParent();
13755 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
13758 return RefinementSteps;
13764 EVT VT =
Op.getValueType();
13767 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
13791PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
13794 EVT VT =
Op.getValueType();
13795 if (VT != MVT::f64 &&
13796 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
13803 int Enabled,
int &RefinementSteps,
13804 bool &UseOneConstNR,
13805 bool Reciprocal)
const {
13807 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
13808 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
13809 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
13810 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
13816 UseOneConstNR = !Subtarget.needsTwoConstNR();
13824 int &RefinementSteps)
const {
13826 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
13827 (VT == MVT::f64 && Subtarget.hasFRE()) ||
13828 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
13829 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
13837unsigned PPCTargetLowering::combineRepeatedFPDivisors()
const {
13875 unsigned Bytes,
int Dist,
13885 int FI = cast<FrameIndexSDNode>(Loc)->getIndex();
13886 int BFI = cast<FrameIndexSDNode>(BaseLoc)->getIndex();
13889 if (FS != BFS || FS != (
int)Bytes)
return false;
13893 SDValue Base1 = Loc, Base2 = BaseLoc;
13894 int64_t Offset1 = 0, Offset2 = 0;
13897 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
13907 if (isGA1 && isGA2 && GV1 == GV2)
13908 return Offset1 == (Offset2 + Dist*Bytes);
13915 unsigned Bytes,
int Dist,
13918 EVT VT = LS->getMemoryVT();
13919 SDValue Loc = LS->getBasePtr();
13925 switch (
N->getConstantOperandVal(1)) {
13926 default:
return false;
13927 case Intrinsic::ppc_altivec_lvx:
13928 case Intrinsic::ppc_altivec_lvxl:
13929 case Intrinsic::ppc_vsx_lxvw4x:
13930 case Intrinsic::ppc_vsx_lxvw4x_be:
13933 case Intrinsic::ppc_vsx_lxvd2x:
13934 case Intrinsic::ppc_vsx_lxvd2x_be:
13937 case Intrinsic::ppc_altivec_lvebx:
13940 case Intrinsic::ppc_altivec_lvehx:
13943 case Intrinsic::ppc_altivec_lvewx:
13953 switch (
N->getConstantOperandVal(1)) {
13954 default:
return false;
13955 case Intrinsic::ppc_altivec_stvx:
13956 case Intrinsic::ppc_altivec_stvxl:
13957 case Intrinsic::ppc_vsx_stxvw4x:
13960 case Intrinsic::ppc_vsx_stxvd2x:
13963 case Intrinsic::ppc_vsx_stxvw4x_be:
13966 case Intrinsic::ppc_vsx_stxvd2x_be:
13969 case Intrinsic::ppc_altivec_stvebx:
13972 case Intrinsic::ppc_altivec_stvehx:
13975 case Intrinsic::ppc_altivec_stvewx:
13992 SDValue Chain = LD->getChain();
13993 EVT VT = LD->getMemoryVT();
14002 while (!Queue.empty()) {
14003 SDNode *ChainNext = Queue.pop_back_val();
14004 if (!Visited.
insert(ChainNext).second)
14007 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(ChainNext)) {
14011 if (!Visited.
count(ChainLD->getChain().getNode()))
14012 Queue.push_back(ChainLD->getChain().getNode());
14014 for (
const SDUse &O : ChainNext->
ops())
14015 if (!Visited.
count(O.getNode()))
14016 Queue.push_back(O.getNode());
14018 LoadRoots.
insert(ChainNext);
14029 for (
SDNode *
I : LoadRoots) {
14030 Queue.push_back(
I);
14032 while (!Queue.empty()) {
14033 SDNode *LoadRoot = Queue.pop_back_val();
14034 if (!Visited.
insert(LoadRoot).second)
14037 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(LoadRoot))
14042 if (((isa<MemSDNode>(U) &&
14043 cast<MemSDNode>(U)->getChain().
getNode() == LoadRoot) ||
14046 Queue.push_back(U);
14079 auto Final = Shifted;
14090 DAGCombinerInfo &DCI)
const {
14098 if (!DCI.isAfterLegalizeDAG())
14103 for (
const SDNode *U :
N->uses())
14108 auto OpSize =
N->getOperand(0).getValueSizeInBits();
14112 if (OpSize <
Size) {
14130 DAGCombinerInfo &DCI)
const {
14134 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
14145 N->getValueType(0) != MVT::i1)
14148 if (
N->getOperand(0).getValueType() != MVT::i32 &&
14149 N->getOperand(0).getValueType() != MVT::i64)
14157 cast<CondCodeSDNode>(
N->getOperand(
14159 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
14170 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
14193 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
14194 N->getOperand(0).getOpcode() !=
ISD::OR &&
14195 N->getOperand(0).getOpcode() !=
ISD::XOR &&
14205 N->getOperand(1).getOpcode() !=
ISD::AND &&
14206 N->getOperand(1).getOpcode() !=
ISD::OR &&
14207 N->getOperand(1).getOpcode() !=
ISD::XOR &&
14220 for (
unsigned i = 0; i < 2; ++i) {
14224 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
14225 isa<ConstantSDNode>(
N->getOperand(i)))
14236 while (!BinOps.
empty()) {
14244 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
14278 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14279 if (isa<ConstantSDNode>(Inputs[i]))
14302 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
14324 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14327 if (isa<ConstantSDNode>(Inputs[i]))
14333 std::list<HandleSDNode> PromOpHandles;
14334 for (
auto &PromOp : PromOps)
14335 PromOpHandles.emplace_back(PromOp);
14342 while (!PromOpHandles.empty()) {
14344 PromOpHandles.pop_back();
14350 if (!isa<ConstantSDNode>(PromOp.
getOperand(0)) &&
14353 PromOpHandles.emplace_front(PromOp);
14358 if (isa<ConstantSDNode>(RepValue))
14367 default:
C = 0;
break;
14372 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
14380 PromOpHandles.emplace_front(PromOp);
14387 for (
unsigned i = 0; i < 2; ++i)
14388 if (isa<ConstantSDNode>(Ops[
C+i]))
14397 return N->getOperand(0);
14405 DAGCombinerInfo &DCI)
const {
14423 if (
N->getValueType(0) != MVT::i32 &&
14424 N->getValueType(0) != MVT::i64)
14427 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
14428 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.
isPPC64())))
14431 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
14432 N->getOperand(0).getOpcode() !=
ISD::OR &&
14433 N->getOperand(0).getOpcode() !=
ISD::XOR &&
14444 while (!BinOps.
empty()) {
14452 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
14483 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14484 if (isa<ConstantSDNode>(Inputs[i]))
14495 SelectTruncOp[0].
insert(std::make_pair(
User,
14499 SelectTruncOp[0].
insert(std::make_pair(
User,
14502 SelectTruncOp[1].
insert(std::make_pair(
User,
14508 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
14517 SelectTruncOp[0].
insert(std::make_pair(
User,
14521 SelectTruncOp[0].
insert(std::make_pair(
User,
14524 SelectTruncOp[1].
insert(std::make_pair(
User,
14530 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
14531 bool ReallyNeedsExt =
false;
14535 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14536 if (isa<ConstantSDNode>(Inputs[i]))
14540 Inputs[i].getOperand(0).getValueSizeInBits();
14541 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
14546 OpBits-PromBits))) ||
14549 (OpBits-(PromBits-1)))) {
14550 ReallyNeedsExt =
true;
14558 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14562 if (isa<ConstantSDNode>(Inputs[i]))
14565 SDValue InSrc = Inputs[i].getOperand(0);
14579 std::list<HandleSDNode> PromOpHandles;
14580 for (
auto &PromOp : PromOps)
14581 PromOpHandles.emplace_back(PromOp);
14587 while (!PromOpHandles.empty()) {
14589 PromOpHandles.pop_back();
14593 default:
C = 0;
break;
14598 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
14606 PromOpHandles.emplace_front(PromOp);
14616 (SelectTruncOp[1].count(PromOp.
getNode()) &&
14618 PromOpHandles.emplace_front(PromOp);
14627 for (
unsigned i = 0; i < 2; ++i) {
14628 if (!isa<ConstantSDNode>(Ops[
C+i]))
14645 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
14646 if (SI0 != SelectTruncOp[0].
end())
14648 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
14649 if (SI1 != SelectTruncOp[1].
end())
14658 if (!ReallyNeedsExt)
14659 return N->getOperand(0);
14666 N->getValueSizeInBits(0), PromBits),
14667 dl,
N->getValueType(0)));
14670 "Invalid extension type");
14673 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
14681 DAGCombinerInfo &DCI)
const {
14683 "Should be called with a SETCC node");
14701 EVT VT =
N->getValueType(0);
14702 EVT OpVT =
LHS.getValueType();
14708 return DAGCombineTruncBoolExt(
N, DCI);
14713 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(
Op.getNode()))
14715 Op.getValueType() == MVT::f64;
14727combineElementTruncationToVectorTruncation(
SDNode *
N,
14728 DAGCombinerInfo &DCI)
const {
14730 "Should be called with a BUILD_VECTOR node");
14735 SDValue FirstInput =
N->getOperand(0);
14737 "The input operand must be an fp-to-int conversion.");
14746 bool IsSplat =
true;
14751 EVT TargetVT =
N->getValueType(0);
14752 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
14753 SDValue NextOp =
N->getOperand(i);
14757 if (NextConversion != FirstConversion)
14765 if (
N->getOperand(i) != FirstInput)
14776 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
14777 SDValue In =
N->getOperand(i).getOperand(0);
14800 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
14802 return DAG.
getNode(Opcode, dl, TargetVT, BV);
14815 "Should be called with a BUILD_VECTOR node");
14820 if (!
N->getValueType(0).getVectorElementType().isByteSized())
14823 bool InputsAreConsecutiveLoads =
true;
14824 bool InputsAreReverseConsecutive =
true;
14825 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
14826 SDValue FirstInput =
N->getOperand(0);
14827 bool IsRoundOfExtLoad =
false;
14832 FirstLoad = cast<LoadSDNode>(FirstInput.
getOperand(0));
14837 N->getNumOperands() == 1)
14840 if (!IsRoundOfExtLoad)
14841 FirstLoad = cast<LoadSDNode>(FirstInput);
14845 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
14847 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
14850 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
14856 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
14857 LoadSDNode *LD1 = cast<LoadSDNode>(PreviousInput);
14858 LoadSDNode *LD2 = cast<LoadSDNode>(NextInput);
14867 InputsAreConsecutiveLoads =
false;
14869 InputsAreReverseConsecutive =
false;
14872 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
14877 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
14878 "The loads cannot be both consecutive and reverse consecutive.");
14882 if (InputsAreConsecutiveLoads) {
14883 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
14887 ReturnSDVal = WideLoad;
14888 }
else if (InputsAreReverseConsecutive) {
14890 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
14895 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
14899 DAG.
getUNDEF(
N->getValueType(0)), Ops);
14903 for (
auto *LD : InputLoads)
14905 return ReturnSDVal;
14922 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
14924 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
14926 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
14927 CorrectElems = CorrectElems >> 8;
14928 Elems = Elems >> 8;
14935 EVT VT =
N->getValueType(0);
14973 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
14993 if (Input && Input != Extract.
getOperand(0))
14999 Elems = Elems << 8;
15008 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
15009 if (!isSExtOfVecExtract(
N->getOperand(i))) {
15016 int TgtElemArrayIdx;
15018 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
15019 if (InputSize + OutputSize == 40)
15020 TgtElemArrayIdx = 0;
15021 else if (InputSize + OutputSize == 72)
15022 TgtElemArrayIdx = 1;
15023 else if (InputSize + OutputSize == 48)
15024 TgtElemArrayIdx = 2;
15025 else if (InputSize + OutputSize == 80)
15026 TgtElemArrayIdx = 3;
15027 else if (InputSize + OutputSize == 96)
15028 TgtElemArrayIdx = 4;
15032 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
15034 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
15035 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
15036 if (Elems != CorrectElems) {
15052 if (
N->getValueType(0) != MVT::v1i128)
15055 SDValue Operand =
N->getOperand(0);
15061 auto *LD = cast<LoadSDNode>(Operand);
15062 EVT MemoryType = LD->getMemoryVT();
15066 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
15067 MemoryType == MVT::i32 || MemoryType == MVT::i64;
15070 if (!ValidLDType ||
15076 LD->getChain(), LD->getBasePtr(),
15080 DAG.
getVTList(MVT::v1i128, MVT::Other),
15081 LoadOps, MemoryType, LD->getMemOperand());
15085 DAGCombinerInfo &DCI)
const {
15087 "Should be called with a BUILD_VECTOR node");
15092 if (!Subtarget.hasVSX())
15098 SDValue FirstInput =
N->getOperand(0);
15100 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
15115 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
15124 if (Subtarget.isISA3_1()) {
15130 if (
N->getValueType(0) != MVT::v2f64)
15141 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
15145 SDValue Ext2 =
N->getOperand(1).getOperand(0);
15152 if (!Ext1Op || !Ext2Op)
15161 if (FirstElem == 0 && SecondElem == 1)
15163 else if (FirstElem == 2 && SecondElem == 3)
15171 return DAG.
getNode(NodeType, dl, MVT::v2f64,
15176 DAGCombinerInfo &DCI)
const {
15179 "Need an int -> FP conversion node here");
15190 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
15192 if (!
Op.getOperand(0).getValueType().isSimple())
15194 if (
Op.getOperand(0).getValueType().getSimpleVT() <=
MVT(MVT::i1) ||
15195 Op.getOperand(0).getValueType().getSimpleVT() >
MVT(MVT::i64))
15198 SDValue FirstOperand(
Op.getOperand(0));
15199 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
15200 (FirstOperand.getValueType() == MVT::i8 ||
15201 FirstOperand.getValueType() == MVT::i16);
15202 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
15204 bool DstDouble =
Op.getValueType() == MVT::f64;
15205 unsigned ConvOp =
Signed ?
15211 LoadSDNode *LDN = cast<LoadSDNode>(FirstOperand.getNode());
15220 SDValue ExtOps[] = { Ld, WidthConst };
15222 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
15224 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
15232 if (
Op.getOperand(0).getValueType() == MVT::i32)
15236 "UINT_TO_FP is supported only with FPCVT");
15240 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
15245 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
15252 Subtarget.hasFPCVT()) ||
15254 SDValue Src =
Op.getOperand(0).getOperand(0);
15255 if (Src.getValueType() == MVT::f32) {
15257 DCI.AddToWorklist(Src.getNode());
15258 }
else if (Src.getValueType() != MVT::f64) {
15270 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
15273 DCI.AddToWorklist(
FP.getNode());
15297 switch (
N->getOpcode()) {
15302 Chain = LD->getChain();
15303 Base = LD->getBasePtr();
15304 MMO = LD->getMemOperand();
15323 MVT VecTy =
N->getValueType(0).getSimpleVT();
15331 Chain = Load.getValue(1);
15337 if (VecTy != MVT::v2f64) {
15364 switch (
N->getOpcode()) {
15369 Chain = ST->getChain();
15370 Base = ST->getBasePtr();
15371 MMO = ST->getMemOperand();
15391 SDValue Src =
N->getOperand(SrcOpnd);
15392 MVT VecTy = Src.getValueType().getSimpleVT();
15395 if (VecTy != MVT::v2f64) {
15401 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
15407 StoreOps, VecTy, MMO);
15414 DAGCombinerInfo &DCI)
const {
15417 unsigned Opcode =
N->getOperand(1).getOpcode();
15419 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
15423 &&
"Not a FP_TO_INT Instruction!");
15425 SDValue Val =
N->getOperand(1).getOperand(Strict ? 1 : 0);
15426 EVT Op1VT =
N->getOperand(1).getValueType();
15429 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
15433 bool ValidTypeForStoreFltAsInt =
15434 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.
isPPC64()) ||
15435 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
15438 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
15441 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
15442 cast<StoreSDNode>(
N)->isTruncatingStore() || !ValidTypeForStoreFltAsInt)
15449 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
15455 cast<StoreSDNode>(
N)->getMemoryVT(),
15456 cast<StoreSDNode>(
N)->getMemOperand());
15464 bool PrevElemFromFirstVec = Mask[0] < NumElts;
15465 for (
int i = 1, e = Mask.size(); i < e; i++) {
15466 if (PrevElemFromFirstVec && Mask[i] < NumElts)
15468 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
15470 PrevElemFromFirstVec = !PrevElemFromFirstVec;
15482 FirstOp =
Op.getOperand(i);
15489 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
15499 Op =
Op.getOperand(0);
15514 int LHSMaxIdx,
int RHSMinIdx,
15515 int RHSMaxIdx,
int HalfVec,
15516 unsigned ValidLaneWidth,
15518 for (
int i = 0, e = ShuffV.
size(); i < e; i++) {
15519 int Idx = ShuffV[i];
15520 if ((
Idx >= 0 &&
Idx < LHSMaxIdx) || (
Idx >= RHSMinIdx &&
Idx < RHSMaxIdx))
15522 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - ValidLaneWidth;
15533 SDLoc dl(OrigSToV);
15536 "Expecting a SCALAR_TO_VECTOR here");
15549 "Cannot produce a permuted scalar_to_vector for one element vector");
15551 unsigned ResultInElt = NumElts / 2;
15553 NewMask[ResultInElt] =
Idx->getZExtValue();
15578 int NumElts =
LHS.getValueType().getVectorNumElements();
15588 if (!Subtarget.hasDirectMove())
15598 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
15607 if (SToVLHS || SToVRHS) {
15614 if (SToVLHS && SToVRHS &&
15621 int NumEltsOut = ShuffV.
size();
15626 unsigned ValidLaneWidth =
15628 LHS.getValueType().getScalarSizeInBits()
15630 RHS.getValueType().getScalarSizeInBits();
15634 int LHSMaxIdx = -1;
15635 int RHSMinIdx = -1;
15636 int RHSMaxIdx = -1;
15637 int HalfVec =
LHS.getValueType().getVectorNumElements() / 2;
15649 LHSMaxIdx = NumEltsOut / NumEltsIn;
15658 RHSMinIdx = NumEltsOut;
15659 RHSMaxIdx = NumEltsOut / NumEltsIn + RHSMinIdx;
15672 HalfVec, ValidLaneWidth, Subtarget);
15677 if (!isa<ShuffleVectorSDNode>(Res))
15679 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
15698 if (IsLittleEndian) {
15701 if (Mask[0] < NumElts)
15702 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
15706 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
15711 for (
int i = 0, e =
Mask.size(); i <
e; i += 2) {
15715 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
15720 if (Mask[0] < NumElts)
15721 for (
int i = 0, e =
Mask.size(); i <
e; i += 2) {
15725 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
15730 for (
int i = 1, e =
Mask.size(); i <
e; i += 2) {
15734 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
15741 cast<BuildVectorSDNode>(TheSplat.
getNode())->getSplatValue();
15744 if (IsLittleEndian)
15753 DAGCombinerInfo &DCI)
const {
15755 "Not a reverse memop pattern!");
15760 auto I =
Mask.rbegin();
15761 auto E =
Mask.rend();
15763 for (;
I != E; ++
I) {
15780 if (!Subtarget.hasP9Vector())
15783 if(!IsElementReverse(SVN))
15822 if (IntrinsicID == Intrinsic::ppc_stdcx)
15824 else if (IntrinsicID == Intrinsic::ppc_stwcx)
15826 else if (IntrinsicID == Intrinsic::ppc_sthcx)
15828 else if (IntrinsicID == Intrinsic::ppc_stbcx)
15839 switch (
N->getOpcode()) {
15842 return combineADD(
N, DCI);
15851 !isa<ConstantSDNode>(Op2) ||
N->getValueType(0) != MVT::i64 ||
15861 if (!isUInt<32>(Imm))
15868 return combineSHL(
N, DCI);
15870 return combineSRA(
N, DCI);
15872 return combineSRL(
N, DCI);
15874 return combineMUL(
N, DCI);
15877 return combineFMALike(
N, DCI);
15880 return N->getOperand(0);
15884 return N->getOperand(0);
15890 return N->getOperand(0);
15896 return DAGCombineExtBoolTrunc(
N, DCI);
15898 return combineTRUNCATE(
N, DCI);
15900 if (
SDValue CSCC = combineSetCC(
N, DCI))
15904 return DAGCombineTruncBoolExt(
N, DCI);
15907 return combineFPToIntToFP(
N, DCI);
15910 LSBaseSDNode* LSBase = cast<LSBaseSDNode>(
N->getOperand(0));
15911 return combineVReverseMemOP(cast<ShuffleVectorSDNode>(
N), LSBase, DCI);
15913 return combineVectorShuffle(cast<ShuffleVectorSDNode>(
N), DCI.
DAG);
15916 EVT Op1VT =
N->getOperand(1).getValueType();
15917 unsigned Opcode =
N->getOperand(1).getOpcode();
15921 SDValue Val = combineStoreFPToInt(
N, DCI);
15928 SDValue Val= combineVReverseMemOP(SVN, cast<LSBaseSDNode>(
N), DCI);
15934 if (cast<StoreSDNode>(
N)->isUnindexed() && Opcode ==
ISD::BSWAP &&
15935 N->getOperand(1).getNode()->hasOneUse() &&
15936 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
15937 (Subtarget.hasLDBRX() && Subtarget.
isPPC64() && Op1VT == MVT::i64))) {
15941 EVT mVT = cast<StoreSDNode>(
N)->getMemoryVT();
15945 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
15952 if (Op1VT.
bitsGT(mVT)) {
15957 if (Op1VT == MVT::i64)
15962 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
15966 Ops, cast<StoreSDNode>(
N)->getMemoryVT(),
15967 cast<StoreSDNode>(
N)->getMemOperand());
15973 isa<ConstantSDNode>(
N->getOperand(1)) && Op1VT == MVT::i32) {
15975 EVT MemVT = cast<StoreSDNode>(
N)->getMemoryVT();
15985 cast<StoreSDNode>(
N)->setTruncatingStore(
true);
15994 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
15995 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
16002 EVT VT = LD->getValueType(0);
16009 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
16010 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
16021 auto ReplaceTwoFloatLoad = [&]() {
16022 if (VT != MVT::i64)
16037 if (!LD->hasNUsesOfValue(2, 0))
16040 auto UI = LD->use_begin();
16041 while (UI.getUse().getResNo() != 0) ++UI;
16043 while (UI.getUse().getResNo() != 0) ++UI;
16044 SDNode *RightShift = *UI;
16052 if (RightShift->getOpcode() !=
ISD::SRL ||
16053 !isa<ConstantSDNode>(RightShift->getOperand(1)) ||
16054 RightShift->getConstantOperandVal(1) != 32 ||
16055 !RightShift->hasOneUse())
16058 SDNode *Trunc2 = *RightShift->use_begin();
16068 Bitcast->getValueType(0) != MVT::f32)
16080 SDValue BasePtr = LD->getBasePtr();
16081 if (LD->isIndexed()) {
16083 "Non-pre-inc AM on PPC?");
16091 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
16092 LD->getPointerInfo(), LD->getAlign(),
16093 MMOFlags, LD->getAAInfo());
16099 LD->getPointerInfo().getWithOffset(4),
16102 if (LD->isIndexed()) {
16116 if (ReplaceTwoFloatLoad())
16119 EVT MemVT = LD->getMemoryVT();
16122 if (LD->isUnindexed() && VT.
isVector() &&
16125 !Subtarget.hasP8Vector() &&
16126 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
16127 VT == MVT::v4f32))) &&
16128 LD->getAlign() < ABIAlignment) {
16130 SDValue Chain = LD->getChain();
16159 MVT PermCntlTy, PermTy, LDTy;
16160 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
16161 : Intrinsic::ppc_altivec_lvsl;
16162 IntrLD = Intrinsic::ppc_altivec_lvx;
16163 IntrPerm = Intrinsic::ppc_altivec_vperm;
16164 PermCntlTy = MVT::v16i8;
16165 PermTy = MVT::v4i32;
16184 SDValue BaseLoadOps[] = { Chain, LDXIntID,
Ptr };
16188 BaseLoadOps, LDTy, BaseMMO);
16197 int IncValue = IncOffset;
16214 SDValue ExtraLoadOps[] = { Chain, LDXIntID,
Ptr };
16218 ExtraLoadOps, LDTy, ExtraMMO);
16229 if (isLittleEndian)
16231 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
16234 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
16237 Perm = Subtarget.hasAltivec()
16253 unsigned IID =
N->getConstantOperandVal(0);
16255 : Intrinsic::ppc_altivec_lvsl);
16256 if (IID ==
Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
16263 .
zext(
Add.getScalarValueSizeInBits()))) {
16264 SDNode *BasePtr =
Add->getOperand(0).getNode();
16265 for (
SDNode *U : BasePtr->uses()) {
16267 U->getConstantOperandVal(0) == IID) {
16277 if (isa<ConstantSDNode>(
Add->getOperand(1))) {
16278 SDNode *BasePtr =
Add->getOperand(0).getNode();
16279 for (
SDNode *U : BasePtr->uses()) {
16281 isa<ConstantSDNode>(U->getOperand(1)) &&
16282 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
16288 V->getConstantOperandVal(0) == IID) {
16300 (IID == Intrinsic::ppc_altivec_vmaxsw ||
16301 IID == Intrinsic::ppc_altivec_vmaxsh ||
16302 IID == Intrinsic::ppc_altivec_vmaxsb)) {
16318 V2.getOperand(1) == V1) {
16333 switch (
N->getConstantOperandVal(1)) {
16336 case Intrinsic::ppc_altivec_vsum4sbs:
16337 case Intrinsic::ppc_altivec_vsum4shs:
16338 case Intrinsic::ppc_altivec_vsum4ubs: {
16344 dyn_cast<BuildVectorSDNode>(
N->getOperand(3))) {
16345 APInt APSplatBits, APSplatUndef;
16346 unsigned SplatBitSize;
16349 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
16352 if (BVNIsConstantSplat && APSplatBits == 0)
16357 case Intrinsic::ppc_vsx_lxvw4x:
16358 case Intrinsic::ppc_vsx_lxvd2x:
16370 switch (
N->getConstantOperandVal(1)) {
16373 case Intrinsic::ppc_vsx_stxvw4x:
16374 case Intrinsic::ppc_vsx_stxvd2x:
16383 bool Is64BitBswapOn64BitTgt =
16384 Subtarget.
isPPC64() &&
N->getValueType(0) == MVT::i64;
16386 N->getOperand(0).hasOneUse();
16387 if (IsSingleUseNormalLd &&
16388 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
16389 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
16400 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
16401 MVT::i64 : MVT::i32, MVT::Other),
16402 Ops, LD->getMemoryVT(), LD->getMemOperand());
16406 if (
N->getValueType(0) == MVT::i16)
16423 !IsSingleUseNormalLd)
16425 LoadSDNode *LD = cast<LoadSDNode>(
N->getOperand(0));
16428 if (!LD->isSimple())
16430 SDValue BasePtr = LD->getBasePtr();
16432 LD->getPointerInfo(), LD->getAlign());
16437 LD->getMemOperand(), 4, 4);
16447 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
16456 if (!
N->getOperand(0).hasOneUse() &&
16457 !
N->getOperand(1).hasOneUse() &&
16458 !
N->getOperand(2).hasOneUse()) {
16461 SDNode *VCMPrecNode =
nullptr;
16463 SDNode *LHSN =
N->getOperand(0).getNode();
16467 UI->getOperand(1) ==
N->getOperand(1) &&
16468 UI->getOperand(2) ==
N->getOperand(2) &&
16469 UI->getOperand(0) ==
N->getOperand(0)) {
16482 SDNode *FlagUser =
nullptr;
16484 FlagUser ==
nullptr; ++UI) {
16485 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
16498 return SDValue(VCMPrecNode, 0);
16520 auto RHSAPInt =
RHS->getAsAPIntVal();
16521 if (!RHSAPInt.isIntN(64))
16524 unsigned Val = RHSAPInt.getZExtValue();
16525 auto isImpossibleCompare = [&]() {
16528 if (Val != 0 && Val != 1) {
16530 return N->getOperand(0);
16533 N->getOperand(0),
N->getOperand(4));
16538 unsigned StoreWidth = 0;
16541 if (
SDValue Impossible = isImpossibleCompare())
16555 auto *MemNode = cast<MemSDNode>(
LHS);
16558 DAG.
getVTList(MVT::i32, MVT::Other, MVT::Glue), Ops,
16559 MemNode->getMemoryVT(), MemNode->getMemOperand());
16563 if (
N->getOperand(0) ==
LHS.getValue(1))
16564 InChain =
LHS.getOperand(0);
16576 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
16582 assert(isDot &&
"Can't compare against a vector result!");
16584 if (
SDValue Impossible = isImpossibleCompare())
16587 bool BranchOnWhenPredTrue = (
CC ==
ISD::SETEQ) ^ (Val == 0);
16594 EVT VTs[] = {
LHS.getOperand(2).getValueType(), MVT::Glue };
16599 switch (
LHS.getConstantOperandVal(1)) {
16618 N->getOperand(4), CompNode.
getValue(1));
16623 return DAGCombineBuildVector(
N, DCI);
16634 EVT VT =
N->getValueType(0);
16635 if (VT == MVT::i64 && !Subtarget.
isPPC64())
16637 if ((VT != MVT::i32 && VT != MVT::i64) ||
16645 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
16665 const APInt &DemandedElts,
16667 unsigned Depth)
const {
16669 switch (
Op.getOpcode()) {
16673 if (cast<VTSDNode>(
Op.getOperand(2))->getVT() == MVT::i16)
16674 Known.
Zero = 0xFFFF0000;
16678 switch (
Op.getConstantOperandVal(0)) {
16680 case Intrinsic::ppc_altivec_vcmpbfp_p:
16681 case Intrinsic::ppc_altivec_vcmpeqfp_p:
16682 case Intrinsic::ppc_altivec_vcmpequb_p:
16683 case Intrinsic::ppc_altivec_vcmpequh_p:
16684 case Intrinsic::ppc_altivec_vcmpequw_p:
16685 case Intrinsic::ppc_altivec_vcmpequd_p:
16686 case Intrinsic::ppc_altivec_vcmpequq_p:
16687 case Intrinsic::ppc_altivec_vcmpgefp_p:
16688 case Intrinsic::ppc_altivec_vcmpgtfp_p:
16689 case Intrinsic::ppc_altivec_vcmpgtsb_p:
16690 case Intrinsic::ppc_altivec_vcmpgtsh_p:
16691 case Intrinsic::ppc_altivec_vcmpgtsw_p:
16692 case Intrinsic::ppc_altivec_vcmpgtsd_p:
16693 case Intrinsic::ppc_altivec_vcmpgtsq_p:
16694 case Intrinsic::ppc_altivec_vcmpgtub_p:
16695 case Intrinsic::ppc_altivec_vcmpgtuh_p:
16696 case Intrinsic::ppc_altivec_vcmpgtuw_p:
16697 case Intrinsic::ppc_altivec_vcmpgtud_p:
16698 case Intrinsic::ppc_altivec_vcmpgtuq_p:
16705 switch (
Op.getConstantOperandVal(1)) {
16708 case Intrinsic::ppc_load2r:
16710 Known.
Zero = 0xFFFF0000;
16741 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
16750 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
16752 LoopSize +=
TII->getInstSizeInBytes(J);
16757 if (LoopSize > 16 && LoopSize <= 32)
16771 if (Constraint.
size() == 1) {
16772 switch (Constraint[0]) {
16790 }
else if (Constraint ==
"wc") {
16792 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
16793 Constraint ==
"wf" || Constraint ==
"ws" ||
16794 Constraint ==
"wi" || Constraint ==
"ww") {
16807 Value *CallOperandVal =
info.CallOperandVal;
16810 if (!CallOperandVal)
16817 else if ((
StringRef(constraint) ==
"wa" ||
16829 switch (*constraint) {
16859std::pair<unsigned, const TargetRegisterClass *>
16863 if (Constraint.
size() == 1) {
16865 switch (Constraint[0]) {
16867 if (VT == MVT::i64 && Subtarget.
isPPC64())
16868 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
16869 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
16871 if (VT == MVT::i64 && Subtarget.
isPPC64())
16872 return std::make_pair(0U, &PPC::G8RCRegClass);
16873 return std::make_pair(0U, &PPC::GPRCRegClass);
16879 if (Subtarget.hasSPE()) {
16880 if (VT == MVT::f32 || VT == MVT::i32)
16881 return std::make_pair(0U, &PPC::GPRCRegClass);
16882 if (VT == MVT::f64 || VT == MVT::i64)
16883 return std::make_pair(0U, &PPC::SPERCRegClass);
16885 if (VT == MVT::f32 || VT == MVT::i32)
16886 return std::make_pair(0U, &PPC::F4RCRegClass);
16887 if (VT == MVT::f64 || VT == MVT::i64)
16888 return std::make_pair(0U, &PPC::F8RCRegClass);
16892 if (Subtarget.hasAltivec() && VT.
isVector())
16893 return std::make_pair(0U, &PPC::VRRCRegClass);
16894 else if (Subtarget.hasVSX())
16896 return std::make_pair(0U, &PPC::VFRCRegClass);
16899 return std::make_pair(0U, &PPC::CRRCRegClass);
16901 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
16903 return std::make_pair(0U, &PPC::CRBITRCRegClass);
16904 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
16905 Constraint ==
"wf" || Constraint ==
"wi") &&
16906 Subtarget.hasVSX()) {
16910 return std::make_pair(0U, &PPC::VSRCRegClass);
16911 if (VT == MVT::f32 && Subtarget.hasP8Vector())
16912 return std::make_pair(0U, &PPC::VSSRCRegClass);
16913 return std::make_pair(0U, &PPC::VSFRCRegClass);
16914 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
16915 if (VT == MVT::f32 && Subtarget.hasP8Vector())
16916 return std::make_pair(0U, &PPC::VSSRCRegClass);
16918 return std::make_pair(0U, &PPC::VSFRCRegClass);
16919 }
else if (Constraint ==
"lr") {
16920 if (VT == MVT::i64)
16921 return std::make_pair(0U, &PPC::LR8RCRegClass);
16923 return std::make_pair(0U, &PPC::LRRCRegClass);
16928 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
16932 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
16933 int VSNum = atoi(Constraint.
data() + 3);
16934 assert(VSNum >= 0 && VSNum <= 63 &&
16935 "Attempted to access a vsr out of range");
16937 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
16938 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
16943 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
16944 int RegNum = atoi(Constraint.
data() + 2);
16945 if (RegNum > 31 || RegNum < 0)
16947 if (VT == MVT::f32 || VT == MVT::i32)
16948 return Subtarget.hasSPE()
16949 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
16950 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
16951 if (VT == MVT::f64 || VT == MVT::i64)
16952 return Subtarget.hasSPE()
16953 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
16954 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
16958 std::pair<unsigned, const TargetRegisterClass *> R =
16967 if (R.first && VT == MVT::i64 && Subtarget.
isPPC64() &&
16968 PPC::GPRCRegClass.contains(R.first))
16969 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
16970 PPC::sub_32, &PPC::G8RCRegClass),
16971 &PPC::G8RCRegClass);
16974 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
16975 R.first = PPC::CR0;
16976 R.second = &PPC::CRRCRegClass;
16980 if (Subtarget.
isAIXABI() && !
TM.getAIXExtendedAltivecABI()) {
16981 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
16982 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
16983 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
16984 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
16985 "default AIX AltiVec ABI and cannot be used\n";
16995 std::vector<SDValue> &Ops,
17000 if (Constraint.
size() > 1)
17003 char Letter = Constraint[0];
17018 EVT TCVT = MVT::i64;
17023 if (isInt<16>(
Value))
17027 if (isShiftedUInt<16, 16>(
Value))
17031 if (isShiftedInt<16, 16>(
Value))
17035 if (isUInt<16>(
Value))
17051 if (isInt<16>(-
Value))
17059 if (Result.getNode()) {
17060 Ops.push_back(Result);
17071 if (
I.getNumOperands() <= 1)
17073 if (!isa<ConstantSDNode>(Ops[1].
getNode()))
17075 auto IntrinsicID = Ops[1].getNode()->getAsZExtVal();
17076 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
17077 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
17080 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
17108 switch (AM.
Scale) {
17139 unsigned Depth =
Op.getConstantOperandVal(0);
17145 bool isPPC64 = Subtarget.
isPPC64();
17157 isPPC64 ? MVT::i64 : MVT::i32);
17164 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
17172 unsigned Depth =
Op.getConstantOperandVal(0);
17179 bool isPPC64 = PtrVT == MVT::i64;
17185 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
17187 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
17201 bool isPPC64 = Subtarget.
isPPC64();
17235 if (isa<JumpTableSDNode>(GA) || isa<BlockAddressSDNode>(GA))
17253 unsigned Intrinsic)
const {
17254 switch (Intrinsic) {
17255 case Intrinsic::ppc_atomicrmw_xchg_i128:
17256 case Intrinsic::ppc_atomicrmw_add_i128:
17257 case Intrinsic::ppc_atomicrmw_sub_i128:
17258 case Intrinsic::ppc_atomicrmw_nand_i128:
17259 case Intrinsic::ppc_atomicrmw_and_i128:
17260 case Intrinsic::ppc_atomicrmw_or_i128:
17261 case Intrinsic::ppc_atomicrmw_xor_i128:
17262 case Intrinsic::ppc_cmpxchg_i128:
17264 Info.memVT = MVT::i128;
17265 Info.ptrVal =
I.getArgOperand(0);
17271 case Intrinsic::ppc_atomic_load_i128:
17273 Info.memVT = MVT::i128;
17274 Info.ptrVal =
I.getArgOperand(0);
17279 case Intrinsic::ppc_atomic_store_i128:
17281 Info.memVT = MVT::i128;
17282 Info.ptrVal =
I.getArgOperand(2);
17287 case Intrinsic::ppc_altivec_lvx:
17288 case Intrinsic::ppc_altivec_lvxl:
17289 case Intrinsic::ppc_altivec_lvebx:
17290 case Intrinsic::ppc_altivec_lvehx:
17291 case Intrinsic::ppc_altivec_lvewx:
17292 case Intrinsic::ppc_vsx_lxvd2x:
17293 case Intrinsic::ppc_vsx_lxvw4x:
17294 case Intrinsic::ppc_vsx_lxvd2x_be:
17295 case Intrinsic::ppc_vsx_lxvw4x_be:
17296 case Intrinsic::ppc_vsx_lxvl:
17297 case Intrinsic::ppc_vsx_lxvll: {
17299 switch (Intrinsic) {
17300 case Intrinsic::ppc_altivec_lvebx:
17303 case Intrinsic::ppc_altivec_lvehx:
17306 case Intrinsic::ppc_altivec_lvewx:
17309 case Intrinsic::ppc_vsx_lxvd2x:
17310 case Intrinsic::ppc_vsx_lxvd2x_be:
17320 Info.ptrVal =
I.getArgOperand(0);
17327 case Intrinsic::ppc_altivec_stvx:
17328 case Intrinsic::ppc_altivec_stvxl:
17329 case Intrinsic::ppc_altivec_stvebx:
17330 case Intrinsic::ppc_altivec_stvehx:
17331 case Intrinsic::ppc_altivec_stvewx:
17332 case Intrinsic::ppc_vsx_stxvd2x:
17333 case Intrinsic::ppc_vsx_stxvw4x:
17334 case Intrinsic::ppc_vsx_stxvd2x_be:
17335 case Intrinsic::ppc_vsx_stxvw4x_be:
17336 case Intrinsic::ppc_vsx_stxvl:
17337 case Intrinsic::ppc_vsx_stxvll: {
17339 switch (Intrinsic) {
17340 case Intrinsic::ppc_altivec_stvebx:
17343 case Intrinsic::ppc_altivec_stvehx:
17346 case Intrinsic::ppc_altivec_stvewx:
17349 case Intrinsic::ppc_vsx_stxvd2x:
17350 case Intrinsic::ppc_vsx_stxvd2x_be:
17360 Info.ptrVal =
I.getArgOperand(1);
17367 case Intrinsic::ppc_stdcx:
17368 case Intrinsic::ppc_stwcx:
17369 case Intrinsic::ppc_sthcx:
17370 case Intrinsic::ppc_stbcx: {
17372 auto Alignment =
Align(8);
17373 switch (Intrinsic) {
17374 case Intrinsic::ppc_stdcx:
17377 case Intrinsic::ppc_stwcx:
17379 Alignment =
Align(4);
17381 case Intrinsic::ppc_sthcx:
17383 Alignment =
Align(2);
17385 case Intrinsic::ppc_stbcx:
17387 Alignment =
Align(1);
17392 Info.ptrVal =
I.getArgOperand(0);
17394 Info.align = Alignment;
17412 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
17413 if (
Op.isMemset() && Subtarget.hasVSX()) {
17418 if (TailSize > 2 && TailSize <= 4) {
17423 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
17442 return !(BitSize == 0 || BitSize > 64);
17450 return NumBits1 == 64 && NumBits2 == 32;
17458 return NumBits1 == 64 && NumBits2 == 32;
17464 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(Val)) {
17465 EVT MemVT = LD->getMemoryVT();
17466 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
17467 (Subtarget.
isPPC64() && MemVT == MVT::i32)) &&
17483 "invalid fpext types");
17485 if (DestVT == MVT::f128)
17491 return isInt<16>(Imm) || isUInt<16>(Imm);
17495 return isInt<16>(Imm) || isUInt<16>(Imm);
17500 unsigned *
Fast)
const {
17514 !Subtarget.allowsUnalignedFPAccess())
17518 if (Subtarget.hasVSX()) {
17519 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
17520 VT != MVT::v4f32 && VT != MVT::v4i32)
17527 if (VT == MVT::ppcf128)
17541 if (
auto *ConstNode = dyn_cast<ConstantSDNode>(
C.getNode())) {
17542 if (!ConstNode->getAPIntValue().isSignedIntN(64))
17550 int64_t Imm = ConstNode->getSExtValue();
17551 unsigned Shift = llvm::countr_zero<uint64_t>(Imm);
17553 if (isInt<16>(Imm))
17578 return Subtarget.hasP9Vector();
17586 if (!
I->hasOneUse())
17590 assert(
User &&
"A single use instruction with no uses.");
17592 switch (
I->getOpcode()) {
17593 case Instruction::FMul: {
17595 if (
User->getOpcode() != Instruction::FSub &&
17596 User->getOpcode() != Instruction::FAdd)
17609 case Instruction::Load: {
17622 if (
User->getOpcode() != Instruction::Store)
17642 static const MCPhysReg ScratchRegs[] = {
17643 PPC::X12, PPC::LR8, PPC::CTR8, 0
17646 return ScratchRegs;
17650 const Constant *PersonalityFn)
const {
17651 return Subtarget.
isPPC64() ? PPC::X3 : PPC::R3;
17655 const Constant *PersonalityFn)
const {
17656 return Subtarget.
isPPC64() ? PPC::X4 : PPC::R4;
17661 EVT VT ,
unsigned DefinedValues)
const {
17662 if (VT == MVT::v2i64)
17663 return Subtarget.hasDirectMove();
17665 if (Subtarget.hasVSX())
17699 bool LegalOps,
bool OptForSize,
17701 unsigned Depth)
const {
17705 unsigned Opc =
Op.getOpcode();
17706 EVT VT =
Op.getValueType();
17731 if (Flags.hasNoSignedZeros() ||
Options.NoSignedZerosFPMath) {
17735 N0Cost,
Depth + 1);
17739 N1Cost,
Depth + 1);
17741 if (NegN0 && N0Cost <= N1Cost) {
17742 Cost = std::min(N0Cost, N2Cost);
17743 return DAG.
getNode(Opc, Loc, VT, NegN0, N1, NegN2, Flags);
17744 }
else if (NegN1) {
17745 Cost = std::min(N1Cost, N2Cost);
17746 return DAG.
getNode(Opc, Loc, VT, N0, NegN1, NegN2, Flags);
17789 bool ForCodeSize)
const {
17790 if (!VT.
isSimple() || !Subtarget.hasVSX())
17800 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
17805 APSInt IntResult(16,
false);
17810 if (IsExact && IntResult <= 15 && IntResult >= -16)
17812 return Imm.isZero();
17815 return Imm.isPosZero();
17827 unsigned Opcode =
N->getOpcode();
17828 unsigned TargetOpcode;
17847 if (Mask->getZExtValue() == OpSizeInBits - 1)
17853SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17859 if (!Subtarget.isISA3_0() || !Subtarget.
isPPC64() ||
17862 N->getValueType(0) != MVT::i64)
17877 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
17883SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17890SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17909 auto isZextOfCompareWithConstant = [](
SDValue Op) {
17911 Op.getValueType() != MVT::i64)
17915 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
17916 Cmp.getOperand(0).getValueType() != MVT::i64)
17919 if (
auto *
Constant = dyn_cast<ConstantSDNode>(Cmp.getOperand(1))) {
17920 int64_t NegConstant = 0 -
Constant->getSExtValue();
17923 return isInt<16>(NegConstant);
17929 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
17930 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
17933 if (LHSHasPattern && !RHSHasPattern)
17935 else if (!LHSHasPattern && !RHSHasPattern)
17941 SDValue Z = Cmp.getOperand(0);
17942 auto *
Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
17943 int64_t NegConstant = 0 -
Constant->getSExtValue();
17945 switch(cast<CondCodeSDNode>(Cmp.getOperand(2))->get()) {
17956 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
17971 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
18008 if (!GSDN || !ConstNode)
18015 if (!isInt<34>(NewOffset))
18028SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18048 DAGCombinerInfo &DCI)
const {
18050 if (Subtarget.useCRBits()) {
18052 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
18053 return CRTruncValue;
18060 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
18063 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
18073 EltToExtract = EltToExtract ? 0 : 1;
18083 return DCI.DAG.getNode(
18085 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
18090SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18094 if (!ConstOpOrElement)
18102 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne,
EVT VT) ->
bool {
18126 return IsAddOne && IsNeg ? VT.
isVector() :
true;
18130 EVT VT =
N->getValueType(0);
18137 if ((MulAmtAbs - 1).isPowerOf2()) {
18141 if (!IsProfitable(IsNeg,
true, VT))
18154 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
18158 if (!IsProfitable(IsNeg,
false, VT))
18179 DAGCombinerInfo &DCI)
const {
18184 EVT VT =
N->getValueType(0);
18187 unsigned Opc =
N->getOpcode();
18189 bool LegalOps = !DCI.isBeforeLegalizeOps();
18197 if (!
Flags.hasNoSignedZeros() && !
Options.NoSignedZerosFPMath)
18213bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
18230 if (!Callee ||
Callee->isVarArg())
18243bool PPCTargetLowering::
18244isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
18247 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(Mask)) {
18249 if (CI->getBitWidth() > 64)
18251 int64_t ConstVal = CI->getZExtValue();
18252 return isUInt<16>(ConstVal) ||
18253 (isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
18262PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
18268 if ((Flags & FlagSet) == FlagSet)
18271 if ((Flags & FlagSet) == FlagSet)
18274 if ((Flags & FlagSet) == FlagSet)
18277 if ((Flags & FlagSet) == FlagSet)
18298 if ((FrameIndexAlign % 4) != 0)
18299 FlagSet &= ~PPC::MOF_RPlusSImm16Mult4;
18300 if ((FrameIndexAlign % 16) != 0)
18301 FlagSet &= ~PPC::MOF_RPlusSImm16Mult16;
18305 if ((FrameIndexAlign % 4) == 0)
18307 if ((FrameIndexAlign % 16) == 0)
18320 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
18321 if ((Imm & 0x3) == 0)
18323 if ((Imm & 0xf) == 0)
18329 const APInt &ConstImm = CN->getAPIntValue();
18348 const APInt &ConstImm = CN->getAPIntValue();
18358 }
else if (
RHS.getOpcode() ==
PPCISD::Lo && !
RHS.getConstantOperandVal(1))
18370 isValidPCRelNode<ConstantPoolSDNode>(
N) ||
18371 isValidPCRelNode<GlobalAddressSDNode>(
N) ||
18372 isValidPCRelNode<JumpTableSDNode>(
N) ||
18373 isValidPCRelNode<BlockAddressSDNode>(
N));
18378unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
18383 if (!Subtarget.hasP9Vector())
18388 if (Subtarget.hasPrefixInstrs())
18391 if (Subtarget.hasSPE())
18400 unsigned ParentOp = Parent->
getOpcode();
18404 if ((
ID == Intrinsic::ppc_vsx_lxvp) || (
ID == Intrinsic::ppc_vsx_stxvp)) {
18405 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
18416 if (
const LSBaseSDNode *LSB = dyn_cast<LSBaseSDNode>(Parent))
18417 if (LSB->isIndexed())
18422 const MemSDNode *MN = dyn_cast<MemSDNode>(Parent);
18423 assert(MN &&
"Parent should be a MemSDNode!");
18428 "Not expecting scalar integers larger than 16 bytes!");
18431 else if (
Size == 32)
18438 else if (
Size == 256) {
18439 assert(Subtarget.pairedVectorMemops() &&
18440 "256-bit vectors are only available when paired vector memops is "
18448 else if (MemVT == MVT::f128 || MemVT.
isVector())
18458 if (
const LoadSDNode *LN = dyn_cast<LoadSDNode>(Parent)) {
18479 FlagSet &= ~PPC::MOF_NoExt;
18484 bool IsNonP1034BitConst =
18488 IsNonP1034BitConst)
18501 int16_t ForceXFormImm = 0;
18504 Disp =
N.getOperand(0);
18505 Base =
N.getOperand(1);
18516 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
18517 Disp =
N.getOperand(0);
18518 Base =
N.getOperand(1);
18532 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID>
CC)
const {
18538 if (PartVT == MVT::f64 &&
18539 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
18548SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
18552 EVT RetVT =
Op.getValueType();
18560 EVT ArgVT =
N.getValueType();
18565 Entry.IsZExt = !Entry.IsSExt;
18566 Args.push_back(Entry);
18574 (
RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
18580 .setTailCall(isTailCall)
18587SDValue PPCTargetLowering::lowerLibCallBasedOnType(
18588 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
18590 if (
Op.getValueType() == MVT::f32)
18591 return lowerToLibCall(LibCallFloatName,
Op, DAG);
18593 if (
Op.getValueType() == MVT::f64)
18594 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
18599bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
18601 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
18605bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
18606 return Op.getNode()->getFlags().hasApproximateFuncs();
18609bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
18613SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
18614 const char *LibCallFloatName,
18615 const char *LibCallDoubleNameFinite,
18616 const char *LibCallFloatNameFinite,
18619 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
18622 if (!isLowringToMASSFiniteSafe(
Op))
18623 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
18626 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
18627 LibCallDoubleNameFinite,
Op, DAG);
18631 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
18632 "__xl_powf_finite",
Op, DAG);
18636 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
18637 "__xl_sinf_finite",
Op, DAG);
18641 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
18642 "__xl_cosf_finite",
Op, DAG);
18646 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
18647 "__xl_logf_finite",
Op, DAG);
18651 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
18652 "__xl_log10f_finite",
Op, DAG);
18656 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
18657 "__xl_expf_finite",
Op, DAG);
18664 if (!isa<FrameIndexSDNode>(
N))
18682 unsigned Flags = computeMOFlags(Parent,
N, DAG);
18694 "Must be using PC-Relative calls when a valid PC-Relative node is "
18724 Disp =
N.getOperand(1).getOperand(0);
18729 Base =
N.getOperand(0);
18736 auto *CN = cast<ConstantSDNode>(
N);
18737 EVT CNType = CN->getValueType(0);
18738 uint64_t CNImm = CN->getZExtValue();
18749 if ((CNType == MVT::i32 || isInt<32>(CNImm)) &&
18751 int32_t
Addr = (int32_t)CNImm;
18756 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
18772 unsigned Opcode =
N.getOpcode();
18780 Base =
N.getOperand(0);
18799 Base = FI ?
N :
N.getOperand(1);
18811 bool IsVarArg)
const {
18821 return Subtarget.
isPPC64() && Subtarget.hasQuadwordAtomics();
18855 return Intrinsic::ppc_atomicrmw_xchg_i128;
18857 return Intrinsic::ppc_atomicrmw_add_i128;
18859 return Intrinsic::ppc_atomicrmw_sub_i128;
18861 return Intrinsic::ppc_atomicrmw_and_i128;
18863 return Intrinsic::ppc_atomicrmw_or_i128;
18865 return Intrinsic::ppc_atomicrmw_xor_i128;
18867 return Intrinsic::ppc_atomicrmw_nand_i128;
18884 Value *LoHi = Builder.
CreateCall(RMW, {AlignedAddr, IncrLo, IncrHi});
18890 Lo, Builder.
CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
18911 Builder.
CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
18918 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.
uint64_t IntrinsicInst * II
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 char LLVMTargetMachineRef TM
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.
InstListType::const_iterator const_iterator
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.
BasicBlockListType::const_iterator const_iterator
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)
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)
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)