69#include "llvm/IR/IntrinsicsPowerPC.h"
103#define DEBUG_TYPE "ppc-lowering"
106 "disable-p10-store-forward",
130 cl::desc(
"disable vector permute decomposition"),
134 "disable-auto-paired-vec-st",
135 cl::desc(
"disable automatically generated 32byte paired vector stores"),
140 cl::desc(
"Set minimum number of entries to use a jump table on PPC"));
144 cl::desc(
"Set minimum of largest number of comparisons to use bit test for "
149 cl::desc(
"max depth when checking alias info in GatherAllAliases()"));
153 cl::desc(
"Set inclusive limit count of TLS local-dynamic access(es) in a "
154 "function to use initial-exec"));
159 "Number of shuffles lowered to a VPERM or XXPERM");
160STATISTIC(NumDynamicAllocaProbed,
"Number of dynamic stack allocation probed");
167 unsigned OpIdx,
bool IsByte,
185 initializeAddrModeMap();
188 bool isPPC64 = Subtarget.isPPC64();
190 const MVT RegVT = Subtarget.getScalarIntVT();
198 if (!Subtarget.hasEFPU2())
215 if (!Subtarget.hasP10Vector()) {
244 if (Subtarget.isISA3_0()) {
277 if (!Subtarget.hasSPE()) {
284 if (Subtarget.useCRBits()) {
287 if (isPPC64 || Subtarget.hasFPCVT()) {
353 if (Subtarget.isISA3_0()) {
388 if (!Subtarget.hasSPE()) {
393 if (Subtarget.hasVSX()) {
398 if (Subtarget.hasFSQRT()) {
403 if (Subtarget.hasFPRND()) {
444 if (Subtarget.hasSPE()) {
454 if (Subtarget.hasSPE())
458 if (!Subtarget.hasFSQRT() && !(Subtarget.hasFRSQRTE() && Subtarget.hasFRE()))
461 if (!Subtarget.hasFSQRT() &&
462 !(Subtarget.hasFRSQRTES() && Subtarget.hasFRES()))
465 if (Subtarget.hasFCPSGN()) {
473 if (Subtarget.hasFPRND()) {
487 if (Subtarget.isISA3_1()) {
493 ((Subtarget.hasP8Vector()) && isPPC64) ?
Custom
498 if (Subtarget.isISA3_0()) {
518 if (!Subtarget.useCRBits()) {
531 if (!Subtarget.useCRBits())
534 if (Subtarget.hasFPU()) {
545 if (!Subtarget.useCRBits())
550 if (Subtarget.hasSPE()) {
582 if (Subtarget.hasDirectMove() && isPPC64) {
644 if (Subtarget.is64BitELFABI()) {
655 }
else if (Subtarget.is32BitELFABI()) {
663 if (Subtarget.is32BitELFABI())
679 if (Subtarget.isISA3_0() && isPPC64) {
707 if (Subtarget.hasSPE()) {
729 if (Subtarget.has64BitSupport()) {
744 if (Subtarget.hasLFIWAX() || isPPC64) {
750 if (Subtarget.hasSPE()) {
760 if (Subtarget.hasFPCVT()) {
761 if (Subtarget.has64BitSupport()) {
782 if (Subtarget.use64BitRegs()) {
800 if (Subtarget.has64BitSupport()) {
807 if (Subtarget.hasVSX()) {
820 if (Subtarget.hasAltivec()) {
821 for (
MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
838 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
851 if (Subtarget.hasVSX()) {
860 if (Subtarget.hasP8Altivec() && (VT.SimpleTy != MVT::v1i128)) {
870 if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
944 if (!Subtarget.hasP8Vector()) {
986 if (Subtarget.hasAltivec())
987 for (
auto VT : {MVT::v4i32, MVT::v8i16, MVT::v16i8})
990 if (Subtarget.hasP8Altivec())
1001 if (Subtarget.hasVSX()) {
1007 if (Subtarget.hasP8Altivec())
1012 if (Subtarget.isISA3_1()) {
1058 if (Subtarget.hasVSX()) {
1061 if (Subtarget.hasP8Vector()) {
1065 if (Subtarget.hasDirectMove() && isPPC64) {
1114 if (Subtarget.hasP8Vector())
1123 if (Subtarget.hasP8Altivec()) {
1150 if (Subtarget.isISA3_1())
1253 if (Subtarget.hasP8Altivec()) {
1258 if (Subtarget.hasP9Vector()) {
1263 if (Subtarget.useCRBits()) {
1323 }
else if (Subtarget.hasVSX()) {
1348 for (
MVT VT : {MVT::f32, MVT::f64}) {
1367 if (Subtarget.hasP9Altivec()) {
1368 if (Subtarget.isISA3_1()) {
1391 if (Subtarget.hasP10Vector()) {
1406 if (Subtarget.pairedVectorMemops()) {
1411 if (Subtarget.hasMMA()) {
1412 if (Subtarget.isISAFuture()) {
1428 if (Subtarget.has64BitSupport())
1431 if (Subtarget.isISA3_1())
1449 if (Subtarget.hasAltivec()) {
1467 if (Subtarget.hasFPCVT())
1470 if (Subtarget.useCRBits())
1479 if (Subtarget.useCRBits()) {
1483 if (Subtarget.hasP8Vector())
1488 if (Subtarget.useCRBits()) {
1504 auto CPUDirective = Subtarget.getCPUDirective();
1505 switch (CPUDirective) {
1528 if (Subtarget.enableMachineScheduler())
1602void PPCTargetLowering::initializeAddrModeMap() {
1653 if (MaxAlign == MaxMaxAlign)
1656 if (MaxMaxAlign >= 32 &&
1657 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1658 MaxAlign =
Align(32);
1659 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1661 MaxAlign =
Align(16);
1665 if (EltAlign > MaxAlign)
1666 MaxAlign = EltAlign;
1668 for (
auto *EltTy : STy->elements()) {
1671 if (EltAlign > MaxAlign)
1672 MaxAlign = EltAlign;
1673 if (MaxAlign == MaxMaxAlign)
1686 if (Subtarget.hasAltivec())
1692 return Subtarget.useSoftFloat();
1696 return Subtarget.hasSPE();
1704 Type *VectorTy,
unsigned ElemSizeInBits,
unsigned &Index)
const {
1705 if (!Subtarget.isPPC64() || !Subtarget.hasVSX())
1709 if (VTy->getScalarType()->isIntegerTy()) {
1711 if (ElemSizeInBits == 32) {
1712 Index = Subtarget.isLittleEndian() ? 2 : 1;
1715 if (ElemSizeInBits == 64) {
1716 Index = Subtarget.isLittleEndian() ? 1 : 0;
1727 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1744 return CFP->getValueAPF().isZero();
1749 return CFP->getValueAPF().isZero();
1757 return Op < 0 ||
Op == Val;
1769 if (ShuffleKind == 0) {
1772 for (
unsigned i = 0; i != 16; ++i)
1775 }
else if (ShuffleKind == 2) {
1778 for (
unsigned i = 0; i != 16; ++i)
1781 }
else if (ShuffleKind == 1) {
1782 unsigned j = IsLE ? 0 : 1;
1783 for (
unsigned i = 0; i != 8; ++i)
1800 if (ShuffleKind == 0) {
1803 for (
unsigned i = 0; i != 16; i += 2)
1807 }
else if (ShuffleKind == 2) {
1810 for (
unsigned i = 0; i != 16; i += 2)
1814 }
else if (ShuffleKind == 1) {
1815 unsigned j = IsLE ? 0 : 2;
1816 for (
unsigned i = 0; i != 8; i += 2)
1837 if (!Subtarget.hasP8Vector())
1841 if (ShuffleKind == 0) {
1844 for (
unsigned i = 0; i != 16; i += 4)
1850 }
else if (ShuffleKind == 2) {
1853 for (
unsigned i = 0; i != 16; i += 4)
1859 }
else if (ShuffleKind == 1) {
1860 unsigned j = IsLE ? 0 : 4;
1861 for (
unsigned i = 0; i != 8; i += 4)
1878 unsigned LHSStart,
unsigned RHSStart) {
1879 if (
N->getValueType(0) != MVT::v16i8)
1881 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
1882 "Unsupported merge size!");
1884 for (
unsigned i = 0; i != 8/UnitSize; ++i)
1885 for (
unsigned j = 0; j != UnitSize; ++j) {
1887 LHSStart+j+i*UnitSize) ||
1889 RHSStart+j+i*UnitSize))
1904 if (ShuffleKind == 1)
1906 else if (ShuffleKind == 2)
1911 if (ShuffleKind == 1)
1913 else if (ShuffleKind == 0)
1929 if (ShuffleKind == 1)
1931 else if (ShuffleKind == 2)
1936 if (ShuffleKind == 1)
1938 else if (ShuffleKind == 0)
1988 unsigned RHSStartValue) {
1989 if (
N->getValueType(0) != MVT::v16i8)
1992 for (
unsigned i = 0; i < 2; ++i)
1993 for (
unsigned j = 0; j < 4; ++j)
1995 i*RHSStartValue+j+IndexOffset) ||
1997 i*RHSStartValue+j+IndexOffset+8))
2019 unsigned indexOffset = CheckEven ? 4 : 0;
2020 if (ShuffleKind == 1)
2022 else if (ShuffleKind == 2)
2028 unsigned indexOffset = CheckEven ? 0 : 4;
2029 if (ShuffleKind == 1)
2031 else if (ShuffleKind == 0)
2047 if (
N->getValueType(0) != MVT::v16i8)
2054 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2057 if (i == 16)
return -1;
2062 if (ShiftAmt < i)
return -1;
2067 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2069 for (++i; i != 16; ++i)
2072 }
else if (ShuffleKind == 1) {
2074 for (++i; i != 16; ++i)
2081 ShiftAmt = 16 - ShiftAmt;
2090 EVT VT =
N->getValueType(0);
2091 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2092 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2095 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2099 if (
N->getMaskElt(0) % EltSize != 0)
2104 unsigned ElementBase =
N->getMaskElt(0);
2107 if (ElementBase >= 16)
2112 for (
unsigned i = 1; i != EltSize; ++i)
2113 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2116 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2118 if (
N->getMaskElt(i) < 0) {
2119 for (
unsigned j = 1; j != EltSize; ++j)
2120 if (
N->getMaskElt(i + j) >= 0)
2123 for (
unsigned j = 0; j != EltSize; ++j)
2124 if (
N->getMaskElt(i + j) !=
N->getMaskElt(j))
2141 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2142 "Unexpected element width.");
2143 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2145 unsigned NumOfElem = 16 / Width;
2146 unsigned MaskVal[16];
2147 for (
unsigned i = 0; i < NumOfElem; ++i) {
2148 MaskVal[0] =
N->getMaskElt(i * Width);
2149 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2151 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2155 for (
unsigned int j = 1; j < Width; ++j) {
2156 MaskVal[j] =
N->getMaskElt(i * Width + j);
2157 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2167 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2172 unsigned M0 =
N->getMaskElt(0) / 4;
2173 unsigned M1 =
N->getMaskElt(4) / 4;
2174 unsigned M2 =
N->getMaskElt(8) / 4;
2175 unsigned M3 =
N->getMaskElt(12) / 4;
2176 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2177 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2182 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2183 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2184 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2185 InsertAtByte = IsLE ? 12 : 0;
2190 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2191 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2192 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2193 InsertAtByte = IsLE ? 8 : 4;
2198 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2199 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2200 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2201 InsertAtByte = IsLE ? 4 : 8;
2206 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2207 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2208 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2209 InsertAtByte = IsLE ? 0 : 12;
2216 if (
N->getOperand(1).isUndef()) {
2219 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2220 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2221 InsertAtByte = IsLE ? 12 : 0;
2224 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2225 InsertAtByte = IsLE ? 8 : 4;
2228 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2229 InsertAtByte = IsLE ? 4 : 8;
2232 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2233 InsertAtByte = IsLE ? 0 : 12;
2242 bool &Swap,
bool IsLE) {
2243 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2249 unsigned M0 =
N->getMaskElt(0) / 4;
2250 unsigned M1 =
N->getMaskElt(4) / 4;
2251 unsigned M2 =
N->getMaskElt(8) / 4;
2252 unsigned M3 =
N->getMaskElt(12) / 4;
2256 if (
N->getOperand(1).isUndef()) {
2257 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2258 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2261 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2267 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2271 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2276 ShiftElts = (8 -
M0) % 8;
2277 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2282 ShiftElts = (4 -
M0) % 4;
2287 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2292 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2304 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2309 for (
int i = 0; i < 16; i += Width)
2310 if (
N->getMaskElt(i) != i + Width - 1)
2341 bool &Swap,
bool IsLE) {
2342 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2348 unsigned M0 =
N->getMaskElt(0) / 8;
2349 unsigned M1 =
N->getMaskElt(8) / 8;
2350 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2354 if (
N->getOperand(1).isUndef()) {
2355 if ((
M0 |
M1) < 2) {
2356 DM = IsLE ? (((
~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2364 if (
M0 > 1 &&
M1 < 2) {
2374 DM = (((
~M1) & 1) << 1) + ((~
M0) & 1);
2379 }
else if (
M0 > 1 &&
M1 < 2) {
2387 DM = (
M0 << 1) + (
M1 & 1);
2402 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2407 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2423 unsigned EltSize = 16/
N->getNumOperands();
2424 if (EltSize < ByteSize) {
2425 unsigned Multiple = ByteSize/EltSize;
2427 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2430 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2431 if (
N->getOperand(i).isUndef())
continue;
2435 if (!UniquedVals[i&(Multiple-1)].
getNode())
2436 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2437 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2447 bool LeadingZero =
true;
2448 bool LeadingOnes =
true;
2449 for (
unsigned i = 0; i != Multiple-1; ++i) {
2450 if (!UniquedVals[i].
getNode())
continue;
2457 if (!UniquedVals[Multiple-1].
getNode())
2464 if (!UniquedVals[Multiple-1].
getNode())
2475 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2476 if (
N->getOperand(i).isUndef())
continue;
2478 OpVal =
N->getOperand(i);
2479 else if (OpVal !=
N->getOperand(i))
2485 unsigned ValSizeInBytes = EltSize;
2488 Value = CN->getZExtValue();
2490 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2497 if (ValSizeInBytes < ByteSize)
return SDValue();
2508 if (MaskVal == 0)
return SDValue();
2528 Imm = (int16_t)
N->getAsZExtVal();
2529 if (
N->getValueType(0) == MVT::i32)
2530 return Imm == (int32_t)
N->getAsZExtVal();
2532 return Imm == (int64_t)
N->getAsZExtVal();
2550 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2558 for (
SDNode *U :
N->users()) {
2560 if (Memop->getMemoryVT() == MVT::f64) {
2561 Base =
N.getOperand(0);
2562 Index =
N.getOperand(1);
2605 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2607 if (
N.getOperand(1).getOpcode() == PPCISD::Lo)
2610 Base =
N.getOperand(0);
2611 Index =
N.getOperand(1);
2613 }
else if (
N.getOpcode() ==
ISD::OR) {
2615 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2627 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2628 Base =
N.getOperand(0);
2629 Index =
N.getOperand(1);
2699 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2705 Base =
N.getOperand(0);
2708 }
else if (
N.getOperand(1).getOpcode() == PPCISD::Lo) {
2710 assert(!
N.getOperand(1).getConstantOperandVal(1) &&
2711 "Cannot handle constant offsets yet!");
2712 Disp =
N.getOperand(1).getOperand(0);
2717 Base =
N.getOperand(0);
2720 }
else if (
N.getOpcode() ==
ISD::OR) {
2723 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2737 Base =
N.getOperand(0);
2750 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm))) {
2753 CN->getValueType(0));
2758 if ((CN->getValueType(0) == MVT::i32 ||
2759 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2760 (!EncodingAlignment ||
2761 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2762 int Addr = (int)CN->getZExtValue();
2769 unsigned Opc = CN->getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2790 if (
N.getValueType() != MVT::i64)
2803 Base =
N.getOperand(0);
2819 Base =
N.getOperand(0);
2852 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2853 Base =
N.getOperand(0);
2854 Index =
N.getOperand(1);
2876 if (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR)
2897 EVT MemVT = LD->getMemoryVT();
2904 if (!ST.hasP8Vector())
2909 if (!ST.hasP9Vector())
2921 if (
Use.getResNo() == 0 &&
2923 Use.
getUser()->getOpcode() != PPCISD::SCALAR_TO_VECTOR_PERMUTED)
2943 Ptr = LD->getBasePtr();
2944 VT = LD->getMemoryVT();
2945 Alignment = LD->getAlign();
2947 Ptr = ST->getBasePtr();
2948 VT = ST->getMemoryVT();
2949 Alignment = ST->getAlign();
2988 if (VT != MVT::i64) {
2993 if (Alignment <
Align(4))
3003 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
3020 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3062 EVT VT = Subtarget.getScalarIntVT();
3064 : Subtarget.isAIXABI()
3069 PPCISD::TOC_ENTRY, dl, DAG.
getVTList(VT, MVT::Other),
Ops, VT,
3076 EVT PtrVT =
Op.getValueType();
3082 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3083 if (Subtarget.isUsingPCRelativeCalls()) {
3088 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, ConstPool);
3092 return getTOCEntry(DAG, SDLoc(CP), GA);
3095 unsigned MOHiFlag, MOLoFlag;
3099 if (IsPIC && Subtarget.isSVR4ABI()) {
3102 return getTOCEntry(DAG, SDLoc(CP), GA);
3125 if (Subtarget.isPPC64() || Subtarget.isAIXABI())
3132 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3149 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3162 EVT PtrVT =
Op.getValueType();
3180 return getTOCEntry(DAG,
SDLoc(JT), GA);
3183 unsigned MOHiFlag, MOLoFlag;
3187 if (IsPIC && Subtarget.isSVR4ABI()) {
3190 return getTOCEntry(DAG, SDLoc(GA), GA);
3200 EVT PtrVT =
Op.getValueType();
3205 if (Subtarget.isUsingPCRelativeCalls()) {
3216 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3219 return getTOCEntry(DAG, SDLoc(BASDN), GA);
3228 unsigned MOHiFlag, MOLoFlag;
3238 if (Subtarget.isAIXABI())
3239 return LowerGlobalTLSAddressAIX(
Op, DAG);
3241 return LowerGlobalTLSAddressLinux(
Op, DAG);
3263 if (
I.getOpcode() == Instruction::Call)
3265 if (
Function *CF = CI->getCalledFunction())
3266 if (CF->isDeclaration() &&
3267 CF->getIntrinsicID() == Intrinsic::threadlocal_address)
3275 unsigned TLSGVCnt = TLSGV.
size();
3285 <<
" function is using the TLS-IE model for TLS-LD access.\n");
3298 const GlobalValue *GV = GA->
getGlobal();
3300 bool Is64Bit = Subtarget.isPPC64();
3304 if (Subtarget.hasAIXShLibTLSModelOpt())
3314 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3315 bool HasAIXSmallTLSGlobalAttr =
false;
3318 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3322 if (GVar->hasAttribute(
"aix-small-tls"))
3323 HasAIXSmallTLSGlobalAttr =
true;
3342 if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) &&
3343 IsTLSLocalExecModel) {
3348 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA, TLSReg);
3358 TLSReg = DAG.
getNode(PPCISD::GET_TPOINTER, dl, PtrVT);
3363 if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr)
3365 "currently only supported on AIX (64-bit mode).");
3367 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, VariableOffset);
3371 bool HasAIXSmallLocalDynamicTLS = Subtarget.hasAIXSmallLocalDynamicTLS();
3375 if (!Is64Bit && HasAIXSmallLocalDynamicTLS)
3377 "currently only supported on AIX (64-bit mode).");
3385 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3388 GlobalVariable *TLSGV =
3392 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3395 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3397 DAG.
getNode(PPCISD::TLSLD_AIX, dl, PtrVT, ModuleHandleTOC);
3406 if (HasAIXSmallLocalDynamicTLS) {
3411 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA,
3415 return DAG.
getNode(
ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
3428 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3429 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3430 return DAG.
getNode(PPCISD::TLSGD_AIX, dl, PtrVT, VariableOffset,
3445 const GlobalValue *GV = GA->
getGlobal();
3447 bool is64bit = Subtarget.isPPC64();
3455 if (Subtarget.isUsingPCRelativeCalls()) {
3460 DAG.
getNode(PPCISD::TLS_LOCAL_EXEC_MAT_ADDR, dl, PtrVT, TGA);
3461 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, MatAddr);
3472 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, TGALo,
Hi);
3476 bool IsPCRel = Subtarget.isUsingPCRelativeCalls();
3483 SDValue MatPCRel = DAG.
getNode(PPCISD::MAT_PCREL_ADDR, dl, PtrVT, TGA);
3485 MachinePointerInfo());
3492 DAG.
getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl, PtrVT, GOTReg, TGA);
3494 if (!TM.isPositionIndependent())
3495 GOTPtr = DAG.
getNode(PPCISD::PPC32_GOT, dl, PtrVT);
3501 TPOffset = DAG.
getNode(PPCISD::LD_GOT_TPREL_L, dl, PtrVT, TGA, GOTPtr);
3507 if (Subtarget.isUsingPCRelativeCalls()) {
3510 return DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3518 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSGD_HA, dl, PtrVT,
3526 return DAG.
getNode(PPCISD::ADDI_TLSGD_L_ADDR, dl, PtrVT,
3531 if (Subtarget.isUsingPCRelativeCalls()) {
3535 DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3536 return DAG.
getNode(PPCISD::PADDI_DTPREL, dl, PtrVT, MatPCRel, TGA);
3544 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSLD_HA, dl, PtrVT,
3553 PtrVT, GOTPtr, TGA, TGA);
3555 PtrVT, TLSAddr, TGA);
3556 return DAG.
getNode(PPCISD::ADDI_DTPREL_L, dl, PtrVT, DtvOffsetHi, TGA);
3564 EVT PtrVT =
Op.getValueType();
3567 const GlobalValue *GV = GSDN->
getGlobal();
3571 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3572 if (Subtarget.isUsingPCRelativeCalls()) {
3579 MachinePointerInfo());
3584 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, GA);
3589 return getTOCEntry(DAG,
DL, GA);
3592 unsigned MOHiFlag, MOLoFlag;
3596 if (IsPIC && Subtarget.isSVR4ABI()) {
3600 return getTOCEntry(DAG,
DL, GA);
3612 bool IsStrict =
Op->isStrictFPOpcode();
3613 const SDNodeFlags
Flags =
Op.getNode()->getFlags();
3619 EVT LHSVT =
LHS.getValueType();
3623 if (LHSVT == MVT::f128 ||
3624 (Subtarget.hasSPE() && (LHSVT == MVT::f32 || LHSVT == MVT::f64) &&
3625 (!
Flags.hasNoNaNs() || !
Flags.hasNoInfs()))) {
3626 assert(!Subtarget.hasP9Vector() &&
3627 "SETCC for f128 is already legal under Power9!");
3636 }
else if (LHSVT == MVT::f32 || LHSVT == MVT::f64) {
3640 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3642 if (
Op.getValueType() == MVT::v2i64) {
3645 if (
LHS.getValueType() == MVT::v2i64) {
3653 int ShuffV[] = {1, 0, 3, 2};
3658 dl, MVT::v4i32, Shuff, SetCC32));
3675 if (
C->isAllOnes() ||
C->isZero())
3685 EVT VT =
Op.getValueType();
3693 const SDNodeFlags
Flags =
Op->getFlags();
3699 EVT LHSVT =
LHS.getValueType();
3702 assert(Subtarget.hasSPE() &&
"LowerBR_CC used only for targets with SPE");
3704 if ((LHSVT == MVT::f32 || LHSVT == MVT::f64) &&
Flags.hasNoNaNs() &&
3722 SDNode *
Node =
Op.getNode();
3723 EVT VT =
Node->getValueType(0);
3730 assert(!Subtarget.isPPC64() &&
"LowerVAARG is PPC32 only");
3734 VAListPtr, MachinePointerInfo(SV), MVT::i8);
3737 if (VT == MVT::i64) {
3756 FprPtr, MachinePointerInfo(SV), MVT::i8);
3767 DAG.
getLoad(MVT::i32, dl, InChain, OverflowAreaPtr, MachinePointerInfo());
3768 InChain = OverflowArea.
getValue(1);
3771 DAG.
getLoad(MVT::i32, dl, InChain, RegSaveAreaPtr, MachinePointerInfo());
3801 MachinePointerInfo(SV), MVT::i8);
3814 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3815 MachinePointerInfo(), MVT::i32);
3817 return DAG.
getLoad(VT, dl, InChain, Result, MachinePointerInfo());
3821 assert(!Subtarget.isPPC64() &&
"LowerVACOPY is PPC32 only");
3827 Align(8),
false,
true,
nullptr, std::nullopt,
3828 MachinePointerInfo(), MachinePointerInfo());
3833 return Op.getOperand(0);
3838 PPCFunctionInfo &MFI = *MF.
getInfo<PPCFunctionInfo>();
3842 "Expecting Inline ASM node.");
3852 if (
Op.getOperand(
NumOps - 1).getValueType() == MVT::Glue)
3857 const InlineAsm::Flag
Flags(
Op.getConstantOperandVal(i));
3858 unsigned NumVals =
Flags.getNumOperandRegisters();
3861 switch (
Flags.getKind()) {
3872 for (; NumVals; --NumVals, ++i) {
3874 if (
Reg != PPC::LR &&
Reg != PPC::LR8)
3897 if (Subtarget.isAIXABI()) {
3901 uint64_t
PointerSize = Subtarget.isPPC64() ? 8 : 4;
3902 MaybeAlign PointerAlign(PointerSize);
3903 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
3906 : MachineMemOperand::MONone;
3913 const Value *TrampolineAddr =
3923 DAG.
getLoad(PtrVT, dl, Chain, FPtr, MachinePointerInfo(Func, 0),
3924 PointerAlign, MMOFlags);
3926 OutChains[0] = DAG.
getStore(EPLoadChain, dl, LoadEntryPoint, Trmp,
3927 MachinePointerInfo(TrampolineAddr, 0));
3931 SDValue TOCFromDescriptorPtr =
3933 SDValue TOCReg = DAG.
getLoad(PtrVT, dl, Chain, TOCFromDescriptorPtr,
3934 MachinePointerInfo(Func, TOCPointerOffset),
3935 PointerAlign, MMOFlags);
3936 SDValue TrampolineTOCPointer =
3940 DAG.
getStore(TOCLoadChain, dl, TOCReg, TrampolineTOCPointer,
3941 MachinePointerInfo(TrampolineAddr, TOCPointerOffset));
3947 DAG.
getStore(Chain, dl, Nest, EnvPointer,
3948 MachinePointerInfo(TrampolineAddr, EnvPointerOffset));
3955 bool isPPC64 = (PtrVT == MVT::i64);
3962 DAG.
getConstant(isPPC64 ? 48 : 40, dl, Subtarget.getScalarIntVT()),
3968 TargetLowering::CallLoweringInfo CLI(DAG);
3969 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3973 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
3974 return CallResult.second;
3979 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
3984 if (Subtarget.isPPC64() || Subtarget.isAIXABI()) {
3989 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
3990 MachinePointerInfo(SV));
4024 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
4027 uint64_t StackOffset = PtrVT.getSizeInBits()/8 - 1;
4030 uint64_t FPROffset = 1;
4038 MachinePointerInfo(SV), MVT::i8);
4039 uint64_t nextOffset = FPROffset;
4046 MachinePointerInfo(SV, nextOffset), MVT::i8);
4047 nextOffset += StackOffset;
4048 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
4051 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
4052 MachinePointerInfo(SV, nextOffset));
4053 nextOffset += FrameOffset;
4054 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
4057 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
4058 MachinePointerInfo(SV, nextOffset));
4063static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
4064 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
4065 PPC::F11, PPC::F12, PPC::F13};
4070 unsigned PtrByteSize) {
4072 if (Flags.isByVal())
4073 ArgSize = Flags.getByValSize();
4077 if (!Flags.isInConsecutiveRegs())
4078 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4087 unsigned PtrByteSize) {
4088 Align Alignment(PtrByteSize);
4091 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4092 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4093 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4094 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4095 Alignment =
Align(16);
4098 if (Flags.isByVal()) {
4099 auto BVAlign = Flags.getNonZeroByValAlign();
4100 if (BVAlign > PtrByteSize) {
4101 if (BVAlign.value() % PtrByteSize != 0)
4103 "ByVal alignment is not a multiple of the pointer size");
4105 Alignment = BVAlign;
4110 if (Flags.isInConsecutiveRegs()) {
4114 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4128 unsigned PtrByteSize,
unsigned LinkageSize,
4129 unsigned ParamAreaSize,
unsigned &ArgOffset,
4130 unsigned &AvailableFPRs,
4131 unsigned &AvailableVRs) {
4132 bool UseMemory =
false;
4137 ArgOffset =
alignTo(ArgOffset, Alignment);
4140 if (ArgOffset >= LinkageSize + ParamAreaSize)
4145 if (Flags.isInConsecutiveRegsLast())
4146 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4149 if (ArgOffset > LinkageSize + ParamAreaSize)
4154 if (!Flags.isByVal()) {
4155 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4156 if (AvailableFPRs > 0) {
4160 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4161 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4162 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4163 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4164 if (AvailableVRs > 0) {
4176 unsigned NumBytes) {
4180SDValue PPCTargetLowering::LowerFormalArguments(
4184 if (Subtarget.isAIXABI())
4185 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4187 if (Subtarget.is64BitELFABI())
4188 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4190 assert(Subtarget.is32BitELFABI());
4191 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4195SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4231 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4237 const Align PtrAlign(4);
4245 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4246 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4249 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4250 CCValAssign &VA = ArgLocs[i];
4262 RC = &PPC::GPRCRegClass;
4265 if (Subtarget.hasP8Vector())
4266 RC = &PPC::VSSRCRegClass;
4267 else if (Subtarget.hasSPE())
4268 RC = &PPC::GPRCRegClass;
4270 RC = &PPC::F4RCRegClass;
4273 if (Subtarget.hasVSX())
4274 RC = &PPC::VSFRCRegClass;
4275 else if (Subtarget.hasSPE())
4277 RC = &PPC::GPRCRegClass;
4279 RC = &PPC::F8RCRegClass;
4284 RC = &PPC::VRRCRegClass;
4287 RC = &PPC::VRRCRegClass;
4291 RC = &PPC::VRRCRegClass;
4298 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4299 assert(i + 1 < e &&
"No second half of double precision argument");
4304 if (!Subtarget.isLittleEndian())
4306 ArgValue = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64, ArgValueLo,
4311 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4312 if (ValVT == MVT::i1)
4327 ArgOffset += ArgSize - ObjSize;
4345 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4350 unsigned MinReservedArea = CCByValInfo.getStackSize();
4351 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4367 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4368 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4370 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4373 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4376 unsigned NumFPArgRegs = std::size(FPArgRegs);
4385 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4386 NumFPArgRegs * MVT(MVT::f64).getSizeInBits()/8;
4389 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4402 VReg = MF.
addLiveIn(GPArgReg, &PPC::GPRCRegClass);
4417 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4421 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4434 if (!MemOps.
empty())
4445 const SDLoc &dl)
const {
4449 else if (
Flags.isZExt())
4456SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4462 bool isELFv2ABI = Subtarget.isELFv2ABI();
4463 bool isLittleEndian = Subtarget.isLittleEndian();
4466 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4469 "fastcc not supported on varargs functions");
4475 unsigned PtrByteSize = 8;
4476 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4479 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4480 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4483 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4484 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4487 const unsigned Num_GPR_Regs = std::size(GPR);
4489 const unsigned Num_VR_Regs = std::size(VR);
4497 bool HasParameterArea = !isELFv2ABI || isVarArg;
4498 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4499 unsigned NumBytes = LinkageSize;
4500 unsigned AvailableFPRs = Num_FPR_Regs;
4501 unsigned AvailableVRs = Num_VR_Regs;
4502 for (
const ISD::InputArg &In : Ins) {
4503 if (
In.Flags.isNest())
4507 LinkageSize, ParamAreaSize, NumBytes,
4508 AvailableFPRs, AvailableVRs))
4509 HasParameterArea =
true;
4516 unsigned ArgOffset = LinkageSize;
4517 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4520 unsigned CurArgIdx = 0;
4521 for (
unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) {
4523 bool needsLoad =
false;
4524 EVT ObjectVT = Ins[ArgNo].VT;
4525 EVT OrigVT = Ins[ArgNo].ArgVT;
4527 unsigned ArgSize = ObjSize;
4528 ISD::ArgFlagsTy
Flags = Ins[ArgNo].Flags;
4529 if (Ins[ArgNo].isOrigArg()) {
4530 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4531 CurArgIdx = Ins[ArgNo].getOrigArgIndex();
4536 unsigned CurArgOffset;
4538 auto ComputeArgOffset = [&]() {
4542 ArgOffset =
alignTo(ArgOffset, Alignment);
4543 CurArgOffset = ArgOffset;
4550 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4551 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4556 if (
Flags.isByVal()) {
4557 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4563 ObjSize =
Flags.getByValSize();
4564 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4586 if (HasParameterArea ||
4587 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4594 if (ObjSize < PtrByteSize) {
4598 if (!isLittleEndian) {
4604 if (GPR_idx != Num_GPR_Regs) {
4611 MachinePointerInfo(&*FuncArg), ObjType);
4616 ArgOffset += PtrByteSize;
4625 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4626 if (GPR_idx == Num_GPR_Regs)
4637 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4641 MachinePointerInfo(&*FuncArg, j), ObjType);
4645 ArgOffset += ArgSize;
4654 if (
Flags.isNest()) {
4659 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4660 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4668 if (GPR_idx != Num_GPR_Regs) {
4673 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4676 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4682 ArgSize = PtrByteSize;
4693 if (FPR_idx != Num_FPR_Regs) {
4696 if (ObjectVT == MVT::f32)
4698 Subtarget.hasP8Vector()
4699 ? &PPC::VSSRCRegClass
4700 : &PPC::F4RCRegClass);
4703 ? &PPC::VSFRCRegClass
4704 : &PPC::F8RCRegClass);
4719 if (ObjectVT == MVT::f32) {
4720 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4738 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4739 ArgOffset += ArgSize;
4740 if (
Flags.isInConsecutiveRegsLast())
4741 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4755 if (VR_idx != Num_VR_Regs) {
4772 if (ObjSize < ArgSize && !isLittleEndian)
4773 CurArgOffset += ArgSize - ObjSize;
4776 ArgVal = DAG.
getLoad(ObjectVT, dl, Chain, FIN, MachinePointerInfo());
4783 unsigned MinReservedArea;
4784 if (HasParameterArea)
4785 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4787 MinReservedArea = LinkageSize;
4804 int Depth = ArgOffset;
4813 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4814 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4826 if (!MemOps.
empty())
4835 unsigned ParamSize) {
4837 if (!isTailCall)
return 0;
4841 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4843 if (SPDiff < FI->getTailCallSPDelta())
4859 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4918 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
4921 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4933 const unsigned PtrByteSize = 8;
4937 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4938 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4941 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4942 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4945 const unsigned NumGPRs = std::size(GPR);
4946 const unsigned NumFPRs = 13;
4947 const unsigned NumVRs = std::size(VR);
4948 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4950 unsigned NumBytes = LinkageSize;
4951 unsigned AvailableFPRs = NumFPRs;
4952 unsigned AvailableVRs = NumVRs;
4955 if (Param.Flags.isNest())
continue;
4958 LinkageSize, ParamAreaSize, NumBytes,
4959 AvailableFPRs, AvailableVRs))
4970 auto CalleeArgEnd = CB.
arg_end();
4973 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
4974 const Value* CalleeArg = *CalleeArgIter;
4975 const Value* CallerArg = &(*CallerArgIter);
4976 if (CalleeArg == CallerArg)
5002 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
5012bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
5017 bool isCalleeExternalSymbol)
const {
5020 if (
DisableSCO && !TailCallOpt)
return false;
5023 if (isVarArg)
return false;
5030 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5066 if (!Subtarget.isUsingPCRelativeCalls() &&
5071 if (!Subtarget.isUsingPCRelativeCalls() &&
5099bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5112 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5133 if (!
C)
return nullptr;
5135 int Addr =
C->getZExtValue();
5136 if ((Addr & 3) != 0 ||
5142 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5149struct TailCallArgumentInfo {
5154 TailCallArgumentInfo() =
default;
5164 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5165 SDValue Arg = TailCallArgs[i].Arg;
5166 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5167 int FI = TailCallArgs[i].FrameIdx;
5170 Chain, dl, Arg, FIN,
5179 int SPDiff,
const SDLoc &dl) {
5185 int SlotSize = Subtarget.isPPC64() ? 8 : 4;
5186 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5188 NewRetAddrLoc,
true);
5191 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5201 int SPDiff,
unsigned ArgOffset,
5203 int Offset = ArgOffset + SPDiff;
5206 EVT VT = IsPPC64 ? MVT::i64 : MVT::i32;
5208 TailCallArgumentInfo Info;
5210 Info.FrameIdxOp = FIN;
5218SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5223 LROpOut = getReturnAddrFrameIndex(DAG);
5224 LROpOut = DAG.
getLoad(Subtarget.getScalarIntVT(), dl, Chain, LROpOut,
5225 MachinePointerInfo());
5241 Align Alignment = Flags.getNonZeroByValAlign();
5243 Chain, dl, Dst, Src, SizeNode, Alignment, Alignment,
false,
false,
5251 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5275 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5285 if (!MemOpChains2.
empty())
5309SDValue PPCTargetLowering::LowerCallResult(
5317 CCRetInfo.AnalyzeCallResult(
5323 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5324 CCValAssign &VA = RVLocs[i];
5329 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5339 if (!Subtarget.isLittleEndian())
5341 Val = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64,
Lo,
Hi);
5407 bool IsStrictFPCall =
false) {
5409 return PPCISD::TC_RETURN;
5411 unsigned RetOpc = 0;
5422 if (Subtarget.usePointerGlueHelper())
5423 RetOpc = PPCISD::BL_LOAD_TOC;
5429 RetOpc = PPCISD::CALL_NOTOC;
5444 RetOpc = PPCISD::CALL;
5445 if (IsStrictFPCall) {
5449 case PPCISD::BCTRL_LOAD_TOC:
5450 RetOpc = PPCISD::BCTRL_LOAD_TOC_RM;
5453 RetOpc = PPCISD::BCTRL_RM;
5455 case PPCISD::BL_LOAD_TOC:
5456 RetOpc = PPCISD::BL_LOAD_TOC_RM;
5458 case PPCISD::CALL_NOTOC:
5459 RetOpc = PPCISD::CALL_NOTOC_RM;
5462 RetOpc = PPCISD::CALL_RM;
5464 case PPCISD::CALL_NOP:
5465 RetOpc = PPCISD::CALL_NOP_RM;
5479 auto isLocalCallee = [&]() {
5495 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5511 return getAIXFuncEntryPointSymbolSDNode(GV);
5518 const char *SymName = S->getSymbol();
5525 return getAIXFuncEntryPointSymbolSDNode(
F);
5531 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5539 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5546 assert(Callee.getNode() &&
"What no callee?");
5552 "Expected a CALLSEQ_STARTSDNode.");
5569 SDValue MTCTROps[] = {Chain, Callee, Glue};
5570 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5571 Chain = DAG.
getNode(PPCISD::MTCTR, dl, ReturnTypes,
5611 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5630 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5631 Alignment, MMOFlags);
5638 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5645 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5657 "Nest parameter is not supported on AIX.");
5672 const SDLoc &dl,
bool hasNest,
5682 Chain = MoveToPhysicalReg.
getValue(0);
5683 Glue = MoveToPhysicalReg.
getValue(1);
5690 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5693 const bool IsPPC64 = Subtarget.isPPC64();
5698 Ops.push_back(Chain);
5702 Ops.push_back(Callee);
5703 else if (Subtarget.usePointerGlueHelper()) {
5704 Ops.push_back(Callee);
5727 Ops.push_back(AddTOC);
5738 Ops.push_back(DAG.
getRegister(IsPPC64 ? PPC::CTR8 : PPC::CTR, RegVT));
5747 for (
const auto &[
Reg,
N] : RegsToPass)
5765 assert(Mask &&
"Missing call preserved mask for calling convention");
5770 Ops.push_back(Glue);
5773SDValue PPCTargetLowering::FinishCall(
5780 if ((Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls()) ||
5781 Subtarget.isAIXABI())
5788 if (!CFlags.IsIndirect)
5790 else if (Subtarget.usesFunctionDescriptors()) {
5791 if (Subtarget.usePointerGlueHelper()) {
5793 CFlags.HasNest, Subtarget);
5799 dl, CFlags.HasNest, Subtarget);
5811 if (CFlags.IsTailCall) {
5819 (CFlags.IsIndirect && Subtarget.isUsingPCRelativeCalls())) &&
5820 "Expecting a global address, external symbol, absolute value, "
5821 "register or an indirect tail call when PC Relative calls are "
5824 assert(CallOpc == PPCISD::TC_RETURN &&
5825 "Unexpected call opcode for a tail call.");
5832 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5833 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes,
Ops);
5845 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5848 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5868 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5869 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5873bool PPCTargetLowering::isEligibleForTCO(
5878 bool isCalleeExternalSymbol)
const {
5882 if (Subtarget.
isSVR4ABI() && Subtarget.isPPC64())
5883 return IsEligibleForTailCallOptimization_64SVR4(
5884 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5885 isCalleeExternalSymbol);
5887 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5915 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5930 "Callee should be an llvm::Function object.");
5933 <<
"\nTCO callee: ");
5940 "site marked musttail");
5947 Callee = LowerGlobalAddress(Callee, DAG);
5950 CallConv, isTailCall, isVarArg, isPatchPoint,
5953 Subtarget.is64BitELFABI() &&
5957 if (Subtarget.isAIXABI())
5958 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5961 assert(Subtarget.isSVR4ABI());
5962 if (Subtarget.isPPC64())
5963 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5965 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5969SDValue PPCTargetLowering::LowerCall_32SVR4(
5980 const bool IsVarArg = CFlags.IsVarArg;
5981 const bool IsTailCall = CFlags.IsTailCall;
5987 const Align PtrAlign(4);
5998 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
6006 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.
getContext());
6009 CCInfo.AllocateStack(Subtarget.getFrameLowering()->getLinkageSize(),
6016 unsigned NumArgs = Outs.
size();
6018 for (
unsigned i = 0; i != NumArgs; ++i) {
6019 MVT ArgVT = Outs[i].VT;
6020 ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
6025 Outs[i].OrigTy, CCInfo);
6028 ArgFlags, Outs[i].OrigTy, CCInfo);
6033 errs() <<
"Call operand #" << i <<
" has unhandled type "
6046 CCState CCByValInfo(CallConv, IsVarArg, MF, ByValArgLocs, *DAG.
getContext());
6049 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
6056 unsigned NumBytes = CCByValInfo.getStackSize();
6070 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6081 bool seenFloatArg =
false;
6086 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
6088 ++i, ++RealArgIdx) {
6089 CCValAssign &VA = ArgLocs[i];
6090 SDValue Arg = OutVals[RealArgIdx];
6091 ISD::ArgFlagsTy
Flags = Outs[RealArgIdx].Flags;
6093 if (
Flags.isByVal()) {
6098 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
6099 CCValAssign &ByValVA = ByValArgLocs[
j++];
6121 Chain = CallSeqStart = NewCallSeqStart;
6140 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6141 bool IsLE = Subtarget.isLittleEndian();
6142 SDValue SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6145 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6147 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6162 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()));
6171 if (!MemOpChains.
empty())
6177 for (
const auto &[
Reg,
N] : RegsToPass) {
6185 SDVTList VTs = DAG.
getVTList(MVT::Other, MVT::Glue);
6188 Chain = DAG.
getNode(seenFloatArg ? PPCISD::CR6SET : PPCISD::CR6UNSET, dl,
6198 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6199 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6204SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6216 return NewCallSeqStart;
6219SDValue PPCTargetLowering::LowerCall_64SVR4(
6226 bool isELFv2ABI = Subtarget.isELFv2ABI();
6227 bool isLittleEndian = Subtarget.isLittleEndian();
6229 bool IsSibCall =
false;
6233 unsigned PtrByteSize = 8;
6246 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
6248 assert(!(IsFastCall && CFlags.IsVarArg) &&
6249 "fastcc not supported on varargs functions");
6255 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
6256 unsigned NumBytes = LinkageSize;
6257 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6260 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6261 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6264 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6265 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6268 const unsigned NumGPRs = std::size(GPR);
6270 const unsigned NumVRs = std::size(VR);
6276 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6277 if (!HasParameterArea) {
6278 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6279 unsigned AvailableFPRs = NumFPRs;
6280 unsigned AvailableVRs = NumVRs;
6281 unsigned NumBytesTmp = NumBytes;
6282 for (
unsigned i = 0; i !=
NumOps; ++i) {
6283 if (Outs[i].
Flags.isNest())
continue;
6285 PtrByteSize, LinkageSize, ParamAreaSize,
6286 NumBytesTmp, AvailableFPRs, AvailableVRs))
6287 HasParameterArea =
true;
6293 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6298 HasParameterArea =
false;
6301 for (
unsigned i = 0; i !=
NumOps; ++i) {
6302 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6303 EVT ArgVT = Outs[i].VT;
6304 EVT OrigVT = Outs[i].ArgVT;
6310 if (
Flags.isByVal()) {
6311 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6312 if (NumGPRsUsed > NumGPRs)
6313 HasParameterArea =
true;
6320 if (++NumGPRsUsed <= NumGPRs)
6330 if (++NumVRsUsed <= NumVRs)
6334 if (++NumVRsUsed <= NumVRs)
6339 if (++NumFPRsUsed <= NumFPRs)
6343 HasParameterArea =
true;
6350 NumBytes =
alignTo(NumBytes, Alignement);
6353 if (
Flags.isInConsecutiveRegsLast())
6354 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6357 unsigned NumBytesActuallyUsed = NumBytes;
6367 if (HasParameterArea)
6368 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6370 NumBytes = LinkageSize;
6385 if (CFlags.IsTailCall)
6397 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6408 unsigned ArgOffset = LinkageSize;
6414 for (
unsigned i = 0; i !=
NumOps; ++i) {
6416 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6417 EVT ArgVT = Outs[i].VT;
6418 EVT OrigVT = Outs[i].ArgVT;
6427 auto ComputePtrOff = [&]() {
6431 ArgOffset =
alignTo(ArgOffset, Alignment);
6442 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6443 GPR_idx = std::min(GPR_idx, NumGPRs);
6450 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6456 if (
Flags.isByVal()) {
6474 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6475 if (GPR_idx != NumGPRs) {
6477 MachinePointerInfo(), VT);
6479 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6481 ArgOffset += PtrByteSize;
6486 if (GPR_idx == NumGPRs &&
Size < 8) {
6488 if (!isLittleEndian) {
6493 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6496 ArgOffset += PtrByteSize;
6505 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6506 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6511 if (
Size < 8 && GPR_idx != NumGPRs) {
6521 if (!isLittleEndian) {
6525 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6531 DAG.
getLoad(PtrVT, dl, Chain, PtrOff, MachinePointerInfo());
6533 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6536 ArgOffset += PtrByteSize;
6542 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6545 if (GPR_idx != NumGPRs) {
6546 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6549 MachinePointerInfo(), ObjType);
6552 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6553 ArgOffset += PtrByteSize;
6555 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6567 if (
Flags.isNest()) {
6569 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6576 if (GPR_idx != NumGPRs) {
6577 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6582 assert(HasParameterArea &&
6583 "Parameter area must exist to pass an argument in memory.");
6585 true, CFlags.IsTailCall,
false, MemOpChains,
6586 TailCallArguments, dl);
6588 ArgOffset += PtrByteSize;
6591 ArgOffset += PtrByteSize;
6604 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6605 bool NeededLoad =
false;
6608 if (FPR_idx != NumFPRs)
6609 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6612 if (!NeedGPROrStack)
6614 else if (GPR_idx != NumGPRs && !IsFastCall) {
6628 }
else if (!
Flags.isInConsecutiveRegs()) {
6634 }
else if (ArgOffset % PtrByteSize != 0) {
6638 if (!isLittleEndian)
6643 }
else if (
Flags.isInConsecutiveRegsLast()) {
6646 if (!isLittleEndian)
6656 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6664 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6669 assert(HasParameterArea &&
6670 "Parameter area must exist to pass an argument in memory.");
6672 true, CFlags.IsTailCall,
false, MemOpChains,
6673 TailCallArguments, dl);
6680 if (!IsFastCall || NeededLoad) {
6682 Flags.isInConsecutiveRegs()) ? 4 : 8;
6683 if (
Flags.isInConsecutiveRegsLast())
6684 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6704 if (CFlags.IsVarArg) {
6705 assert(HasParameterArea &&
6706 "Parameter area must exist if we have a varargs call.");
6710 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
6712 if (VR_idx != NumVRs) {
6714 DAG.
getLoad(MVT::v4f32, dl, Store, PtrOff, MachinePointerInfo());
6716 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6719 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6720 if (GPR_idx == NumGPRs)
6725 DAG.
getLoad(PtrVT, dl, Store, Ix, MachinePointerInfo());
6727 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6733 if (VR_idx != NumVRs) {
6734 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6739 assert(HasParameterArea &&
6740 "Parameter area must exist to pass an argument in memory.");
6742 true, CFlags.IsTailCall,
true, MemOpChains,
6743 TailCallArguments, dl);
6754 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6755 "mismatch in size of parameter area");
6756 (void)NumBytesActuallyUsed;
6758 if (!MemOpChains.
empty())
6764 if (CFlags.IsIndirect) {
6768 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6773 unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
6783 if (isELFv2ABI && !CFlags.IsPatchPoint)
6784 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6790 for (
const auto &[
Reg,
N] : RegsToPass) {
6795 if (CFlags.IsTailCall && !IsSibCall)
6799 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6800 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6807 "Required alignment greater than stack alignment.");
6827 return RequiredAlign <= 8;
6832 return RequiredAlign <= 4;
6840 State.getMachineFunction().getSubtarget());
6841 const bool IsPPC64 = Subtarget.isPPC64();
6842 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6843 const Align PtrAlign(PtrSize);
6844 const Align StackAlign(16);
6847 if (ValVT == MVT::f128)
6851 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6852 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6854 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6855 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6858 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6859 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6860 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6865 MCRegister EnvReg = State.AllocateReg(IsPPC64 ? PPC::X11 : PPC::R11);
6874 if (ByValAlign > StackAlign)
6876 "16 are not supported.");
6879 const Align ObjAlign = ByValAlign > PtrAlign ? ByValAlign : PtrAlign;
6883 if (ByValSize == 0) {
6885 State.getStackSize(), RegVT, LocInfo));
6890 unsigned NextReg = State.getFirstUnallocated(GPRs);
6891 while (NextReg != GPRs.
size() &&
6896 State.AllocateStack(PtrSize, PtrAlign);
6897 assert(
Reg &&
"Alocating register unexpectedly failed.");
6899 NextReg = State.getFirstUnallocated(GPRs);
6902 const unsigned StackSize =
alignTo(ByValSize, ObjAlign);
6903 unsigned Offset = State.AllocateStack(StackSize, ObjAlign);
6923 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6927 const unsigned Offset = State.AllocateStack(PtrSize, PtrAlign);
6946 State.AllocateStack(IsPPC64 ? 8 : StoreSize,
Align(4));
6952 for (
unsigned I = 0;
I < StoreSize;
I += PtrSize) {
6954 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
6955 if (State.isVarArg()) {
6987 const unsigned VecSize = 16;
6988 const Align VecAlign(VecSize);
6990 if (!State.isVarArg()) {
6993 if (
MCRegister VReg = State.AllocateReg(VR)) {
7000 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7005 unsigned NextRegIndex = State.getFirstUnallocated(GPRs);
7008 while (NextRegIndex != GPRs.
size() &&
7012 State.AllocateStack(PtrSize, PtrAlign);
7013 assert(
Reg &&
"Allocating register unexpectedly failed.");
7015 NextRegIndex = State.getFirstUnallocated(GPRs);
7023 if (
MCRegister VReg = State.AllocateReg(VR)) {
7026 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
7027 State.AllocateReg(GPRs);
7028 State.AllocateStack(VecSize, VecAlign);
7032 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7038 if (NextRegIndex == GPRs.
size()) {
7039 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7047 if (GPRs[NextRegIndex] == PPC::R9) {
7048 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7052 const MCRegister FirstReg = State.AllocateReg(PPC::R9);
7053 const MCRegister SecondReg = State.AllocateReg(PPC::R10);
7054 assert(FirstReg && SecondReg &&
7055 "Allocating R9 or R10 unexpectedly failed.");
7066 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7069 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
7071 assert(
Reg &&
"Failed to allocated register for vararg vector argument");
7086 assert((IsPPC64 || SVT != MVT::i64) &&
7087 "i64 should have been split for 32-bit codegen.");
7095 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7097 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
7099 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
7107 return &PPC::VRRCRegClass;
7120 else if (Flags.isZExt())
7132 "Reg must be a valid argument register!");
7133 return LASize + 4 * (
Reg - PPC::R3);
7138 "Reg must be a valid argument register!");
7139 return LASize + 8 * (
Reg - PPC::X3);
7185SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7192 "Unexpected calling convention!");
7200 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7202 const bool IsPPC64 = Subtarget.isPPC64();
7203 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7209 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
7210 CCState CCInfo(CallConv, isVarArg, MF, ArgLocs, *DAG.
getContext());
7214 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7215 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7216 uint64_t SaveStackPos = CCInfo.getStackSize();
7218 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7222 for (
size_t I = 0, End = ArgLocs.
size();
I != End; ) {
7223 CCValAssign &VA = ArgLocs[
I++];
7228 EVT ArgVT = Ins[VA.
getValNo()].ArgVT;
7229 bool ArgSignExt = Ins[VA.
getValNo()].Flags.isSExt();
7241 LocVT.
SimpleTy, IsPPC64, Subtarget.hasP8Vector(), Subtarget.hasVSX());
7243 MVT SaveVT = RegClass == &PPC::G8RCRegClass ? MVT::i64 : LocVT;
7249 MachinePointerInfo(),
Align(PtrByteSize));
7255 unsigned StoreSize =
7257 SaveStackPos =
alignTo(SaveStackPos + StoreSize, PtrByteSize);
7260 auto HandleMemLoc = [&]() {
7263 assert((ValSize <= LocSize) &&
7264 "Object size is larger than size of MemLoc");
7267 if (LocSize > ValSize)
7268 CurArgOffset += LocSize - ValSize;
7270 const bool IsImmutable =
7276 DAG.
getLoad(ValVT, dl, Chain, FIN, MachinePointerInfo());
7310 assert(isVarArg &&
"Only use custom memloc for vararg.");
7313 const unsigned OriginalValNo = VA.
getValNo();
7314 (void)OriginalValNo;
7316 auto HandleCustomVecRegLoc = [&]() {
7317 assert(
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7318 "Missing custom RegLoc.");
7321 "Unexpected Val type for custom RegLoc.");
7323 "ValNo mismatch between custom MemLoc and RegLoc.");
7327 Subtarget.hasVSX()));
7334 HandleCustomVecRegLoc();
7335 HandleCustomVecRegLoc();
7339 if (
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7341 "Only 2 custom RegLocs expected for 64-bit codegen.");
7342 HandleCustomVecRegLoc();
7343 HandleCustomVecRegLoc();
7387 const unsigned Size =
7399 if (
Flags.isByVal()) {
7403 const PPCFrameLowering *FL = Subtarget.getFrameLowering();
7405 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7414 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7416 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7429 CopyFrom.
getValue(1), dl, CopyFrom,
7439 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7442 "RegLocs should be for ByVal argument.");
7444 const CCValAssign RL = ArgLocs[
I++];
7449 if (
Offset != StackSize) {
7451 "Expected MemLoc for remaining bytes.");
7452 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7466 Subtarget.hasVSX()));
7483 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7485 unsigned CallerReservedArea = std::max<unsigned>(
7486 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7492 CallerReservedArea =
7497 int VAListIndex = 0;
7501 if (CCInfo.getStackSize() < (LinkageSize + MinParameterSaveArea)) {
7502 unsigned FixedStackSize =
7503 LinkageSize + MinParameterSaveArea - CCInfo.getStackSize();
7519 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7520 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7522 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7523 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7524 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7530 GPRIndex = (CCInfo.getStackSize() - LinkageSize) / PtrByteSize,
7532 GPRIndex < NumGPArgRegs; ++GPRIndex,
Offset += PtrByteSize) {
7535 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7536 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7539 MachinePointerInfo MPI =
7549 if (!MemOps.
empty())
7555SDValue PPCTargetLowering::LowerCall_AIX(
7568 "Unexpected calling convention!");
7570 if (CFlags.IsPatchPoint)
7573 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7577 CCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7584 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7585 const bool IsPPC64 = Subtarget.isPPC64();
7587 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7588 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7589 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7597 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7598 const unsigned NumBytes = std::max<unsigned>(
7599 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7615 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E;) {
7616 const unsigned ValNo = ArgLocs[
I].getValNo();
7618 ISD::ArgFlagsTy
Flags = Outs[ValNo].Flags;
7620 if (
Flags.isByVal()) {
7621 const unsigned ByValSize =
Flags.getByValSize();
7629 auto GetLoad = [&](EVT VT,
unsigned LoadOffset) {
7635 MachinePointerInfo(), VT);
7638 unsigned LoadOffset = 0;
7641 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7644 LoadOffset += PtrByteSize;
7645 const CCValAssign &ByValVA = ArgLocs[
I++];
7647 "Unexpected location for pass-by-value argument.");
7651 if (LoadOffset == ByValSize)
7655 assert(ArgLocs[
I].getValNo() == ValNo &&
7656 "Expected additional location for by-value argument.");
7658 if (ArgLocs[
I].isMemLoc()) {
7659 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7660 const CCValAssign &ByValVA = ArgLocs[
I++];
7661 ISD::ArgFlagsTy MemcpyFlags =
Flags;
7664 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7670 CallSeqStart, MemcpyFlags, DAG, dl);
7679 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7680 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7681 "Unexpected register residue for by-value argument.");
7683 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7687 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7697 "Unexpected load emitted during handling of pass-by-value "
7705 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7710 const CCValAssign &ByValVA = ArgLocs[
I++];
7715 CCValAssign &VA = ArgLocs[
I++];
7740 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7746 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
7748 const unsigned OriginalValNo = VA.
getValNo();
7750 unsigned LoadOffset = 0;
7751 auto HandleCustomVecRegLoc = [&]() {
7752 assert(
I !=
E &&
"Unexpected end of CCvalAssigns.");
7753 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7754 "Expected custom RegLoc.");
7755 CCValAssign RegVA = ArgLocs[
I++];
7757 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7763 LoadOffset += PtrByteSize;
7769 HandleCustomVecRegLoc();
7770 HandleCustomVecRegLoc();
7772 if (
I !=
E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7773 ArgLocs[
I].getValNo() == OriginalValNo) {
7775 "Only 2 custom RegLocs expected for 64-bit codegen.");
7776 HandleCustomVecRegLoc();
7777 HandleCustomVecRegLoc();
7788 DAG.
getStore(Chain, dl, Arg, PtrOff,
7790 Subtarget.getFrameLowering()->getStackAlign()));
7797 "Unexpected register handling for calling convention.");
7803 "Custom register handling only expected for VarArg.");
7808 if (Arg.getValueType().getStoreSize() == LocVT.
getStoreSize())
7812 else if (Arg.getValueType().getFixedSizeInBits() <
7820 assert(Arg.getValueType() == MVT::f64 && CFlags.IsVarArg && !IsPPC64 &&
7821 "Unexpected custom register for argument!");
7822 CCValAssign &GPR1 = VA;
7831 CCValAssign &PeekArg = ArgLocs[
I];
7834 CCValAssign &GPR2 = ArgLocs[
I++];
7842 if (!MemOpChains.
empty())
7847 if (CFlags.IsIndirect && !Subtarget.usePointerGlueHelper()) {
7848 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7849 const MCRegister TOCBaseReg = Subtarget.getTOCPointerRegister();
7850 const MCRegister StackPtrReg = Subtarget.getStackPointerRegister();
7851 const MVT PtrVT = Subtarget.getScalarIntVT();
7852 const unsigned TOCSaveOffset =
7853 Subtarget.getFrameLowering()->getTOCSaveOffset();
7868 for (
auto Reg : RegsToPass) {
7873 const int SPDiff = 0;
7874 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7875 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7883 const Type *RetTy)
const {
7885 CCState CCInfo(CallConv, isVarArg, MF, RVLocs,
Context);
7886 return CCInfo.CheckReturn(
7901 CCInfo.AnalyzeReturn(Outs,
7910 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7911 CCValAssign &VA = RVLocs[i];
7914 SDValue Arg = OutVals[RealResIdx];
7929 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7930 bool isLittleEndian = Subtarget.isLittleEndian();
7933 DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7937 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7952 RetOps.push_back(Glue);
7954 return DAG.
getNode(PPCISD::RET_GLUE, dl, MVT::Other, RetOps);
7958PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7963 EVT IntVT =
Op.getValueType();
7967 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7971 return DAG.
getNode(PPCISD::DYNAREAOFFSET, dl, VTs,
Ops);
7983 bool isPPC64 = Subtarget.isPPC64();
7984 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7993 DAG.
getLoad(PtrVT, dl, Chain, StackPtr, MachinePointerInfo());
7999 return DAG.
getStore(Chain, dl, LoadLinkSP, StackPtr, MachinePointerInfo());
8004 bool isPPC64 = Subtarget.isPPC64();
8009 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
8015 int LROffset = Subtarget.getFrameLowering()->getReturnSaveOffset();
8025PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
8027 bool isPPC64 = Subtarget.isPPC64();
8032 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
8038 int FPOffset = Subtarget.getFrameLowering()->getFramePointerSaveOffset();
8061 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
8063 SDVTList VTs = DAG.
getVTList(PtrVT, MVT::Other);
8065 return DAG.
getNode(PPCISD::PROBED_ALLOCA, dl, VTs,
Ops);
8066 return DAG.
getNode(PPCISD::DYNALLOC, dl, VTs,
Ops);
8073 bool isPPC64 = Subtarget.isPPC64();
8083 return DAG.
getNode(PPCISD::EH_SJLJ_SETJMP,
DL,
8085 Op.getOperand(0),
Op.getOperand(1));
8091 return DAG.
getNode(PPCISD::EH_SJLJ_LONGJMP,
DL, MVT::Other,
8092 Op.getOperand(0),
Op.getOperand(1));
8096 if (
Op.getValueType().isVector())
8097 return LowerVectorLoad(
Op, DAG);
8099 assert(
Op.getValueType() == MVT::i1 &&
8100 "Custom lowering only for i1 loads");
8109 MachineMemOperand *MMO =
LD->getMemOperand();
8113 BasePtr, MVT::i8, MMO);
8121 if (
Op.getOperand(1).getValueType().isVector())
8122 return LowerVectorStore(
Op, DAG);
8124 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
8125 "Custom lowering only for i1 stores");
8135 MachineMemOperand *MMO =
ST->getMemOperand();
8144 assert(
Op.getValueType() == MVT::i1 &&
8145 "Custom lowering only for i1 results");
8173 EVT TrgVT =
Op.getValueType();
8197 if (SrcSize == 256) {
8208 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8214 SmallVector<int, 16> ShuffV;
8215 if (Subtarget.isLittleEndian())
8216 for (
unsigned i = 0; i < TrgNumElts; ++i)
8219 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8223 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8236 EVT ResVT =
Op.getValueType();
8237 EVT CmpVT =
Op.getOperand(0).getValueType();
8239 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8245 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8258 SDNodeFlags
Flags =
Op.getNode()->getFlags();
8262 if (Subtarget.hasP9Vector() &&
LHS == TV &&
RHS == FV) {
8279 if (!
Flags.hasNoInfs() || !
Flags.hasNoNaNs() || ResVT == MVT::f128)
8292 if (
LHS.getValueType() == MVT::f32)
8294 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8297 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8305 if (
LHS.getValueType() == MVT::f32)
8307 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8314 if (
LHS.getValueType() == MVT::f32)
8316 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8328 if (
Cmp.getValueType() == MVT::f32)
8330 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8333 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8338 if (
Cmp.getValueType() == MVT::f32)
8340 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8344 if (
Cmp.getValueType() == MVT::f32)
8346 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8350 if (
Cmp.getValueType() == MVT::f32)
8352 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8356 if (
Cmp.getValueType() == MVT::f32)
8358 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8367 case PPCISD::FCTIDZ:
8368 return PPCISD::STRICT_FCTIDZ;
8369 case PPCISD::FCTIWZ:
8370 return PPCISD::STRICT_FCTIWZ;
8371 case PPCISD::FCTIDUZ:
8372 return PPCISD::STRICT_FCTIDUZ;
8373 case PPCISD::FCTIWUZ:
8374 return PPCISD::STRICT_FCTIWUZ;
8376 return PPCISD::STRICT_FCFID;
8377 case PPCISD::FCFIDU:
8378 return PPCISD::STRICT_FCFIDU;
8379 case PPCISD::FCFIDS:
8380 return PPCISD::STRICT_FCFIDS;
8381 case PPCISD::FCFIDUS:
8382 return PPCISD::STRICT_FCFIDUS;
8389 bool IsStrict =
Op->isStrictFPOpcode();
8398 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8400 MVT DestTy =
Op.getSimpleValueType();
8401 assert(Src.getValueType().isFloatingPoint() &&
8402 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8403 DestTy == MVT::i64) &&
8404 "Invalid FP_TO_INT types");
8405 if (Src.getValueType() == MVT::f32) {
8409 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8414 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8420 Opc = IsSigned ? PPCISD::FCTIWZ
8421 : (Subtarget.hasFPCVT() ? PPCISD::FCTIWUZ : PPCISD::FCTIDZ);
8424 assert((IsSigned || Subtarget.hasFPCVT()) &&
8425 "i64 FP_TO_UINT is supported only with FPCVT");
8426 Opc = IsSigned ? PPCISD::FCTIDZ : PPCISD::FCTIDUZ;
8428 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8440void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8442 const SDLoc &dl)
const {
8446 bool IsStrict =
Op->isStrictFPOpcode();
8449 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8450 (IsSigned || Subtarget.hasFPCVT());
8453 MachinePointerInfo MPI =
8461 Alignment =
Align(4);
8462 MachineMemOperand *MMO =
8468 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8472 if (
Op.getValueType() == MVT::i32 && !i32Stack &&
8473 !Subtarget.isLittleEndian()) {
8482 RLI.Alignment = Alignment;
8490 const SDLoc &dl)
const {
8493 if (
Op->isStrictFPOpcode())
8500 const SDLoc &dl)
const {
8501 bool IsStrict =
Op->isStrictFPOpcode();
8504 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8505 EVT SrcVT = Src.getValueType();
8506 EVT DstVT =
Op.getValueType();
8509 if (SrcVT == MVT::f128)
8510 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8514 if (SrcVT == MVT::ppcf128) {
8515 if (DstVT == MVT::i32) {
8520 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8531 {Op.getOperand(0), Lo, Hi}, Flags);
8534 {Res.getValue(1), Res}, Flags);
8540 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8564 {Chain, Src, FltOfs}, Flags);
8568 {Chain, Val}, Flags);
8571 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8589 if (Subtarget.hasDirectMove() && Subtarget.isPPC64())
8590 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8593 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8595 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8596 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8607bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8612 if (
Op->isStrictFPOpcode())
8617 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8621 Op.getOperand(0).getValueType())) {
8623 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8628 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8629 LD->isNonTemporal())
8631 if (
LD->getMemoryVT() != MemVT)
8641 RLI.Ptr =
LD->getBasePtr();
8642 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8644 "Non-pre-inc AM on PPC?");
8649 RLI.Chain =
LD->getChain();
8650 RLI.MPI =
LD->getPointerInfo();
8651 RLI.IsDereferenceable =
LD->isDereferenceable();
8652 RLI.IsInvariant =
LD->isInvariant();
8653 RLI.Alignment =
LD->getAlign();
8654 RLI.AAInfo =
LD->getAAInfo();
8655 RLI.Ranges =
LD->getRanges();
8657 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8664bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8665 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8672 if (!Subtarget.hasP9Vector() &&
8676 for (SDUse &Use : Origin->
uses()) {
8679 if (
Use.getResNo() != 0)
8706 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8707 unsigned ConvOpc = IsSingle ? (IsSigned ? PPCISD::FCFIDS : PPCISD::FCFIDUS)
8708 : (IsSigned ? PPCISD::FCFID : PPCISD::FCFIDU);
8709 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8710 if (
Op->isStrictFPOpcode()) {
8712 Chain =
Op.getOperand(0);
8714 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8716 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8724 const SDLoc &dl)
const {
8725 assert((
Op.getValueType() == MVT::f32 ||
8726 Op.getValueType() == MVT::f64) &&
8727 "Invalid floating point type as target of conversion");
8728 assert(Subtarget.hasFPCVT() &&
8729 "Int to FP conversions with direct moves require FPCVT");
8730 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8731 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8734 unsigned MovOpc = (WordInt && !
Signed) ? PPCISD::MTVSRZ : PPCISD::MTVSRA;
8753 for (
unsigned i = 1; i < NumConcat; ++i)
8760 const SDLoc &dl)
const {
8761 bool IsStrict =
Op->isStrictFPOpcode();
8762 unsigned Opc =
Op.getOpcode();
8763 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8766 "Unexpected conversion type");
8767 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8768 "Supports conversions to v2f64/v4f32 only.");
8772 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8775 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8780 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8782 SmallVector<int, 16> ShuffV;
8783 for (
unsigned i = 0; i < WideNumElts; ++i)
8786 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8787 int SaveElts = FourEltRes ? 4 : 2;
8788 if (Subtarget.isLittleEndian())
8789 for (
int i = 0; i < SaveElts; i++)
8790 ShuffV[i * Stride] = i;
8792 for (
int i = 1; i <= SaveElts; i++)
8793 ShuffV[i * Stride - 1] = i - 1;
8801 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8802 EVT ExtVT = Src.getValueType();
8803 if (Subtarget.hasP9Altivec())
8814 {Op.getOperand(0), Extend}, Flags);
8816 return DAG.
getNode(
Opc, dl,
Op.getValueType(), Extend);
8824 bool IsStrict =
Op->isStrictFPOpcode();
8825 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8830 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8832 EVT InVT = Src.getValueType();
8833 EVT OutVT =
Op.getValueType();
8836 return LowerINT_TO_FPVector(
Op, DAG, dl);
8839 if (
Op.getValueType() == MVT::f128)
8840 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8843 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8846 if (Src.getValueType() == MVT::i1) {
8858 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8859 Subtarget.isPPC64() && Subtarget.hasFPCVT())
8860 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8862 assert((IsSigned || Subtarget.hasFPCVT()) &&
8863 "UINT_TO_FP is supported only with FPCVT");
8865 if (Src.getValueType() == MVT::i64) {
8880 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT() &&
8881 !
Op->getFlags().hasApproximateFuncs()) {
8921 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8924 Bits = DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8925 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo,
nullptr);
8928 }
else if (Subtarget.hasLFIWAX() &&
8929 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8930 MachineMemOperand *MMO =
8932 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8936 Ops, MVT::i32, MMO);
8939 }
else if (Subtarget.hasFPCVT() &&
8940 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8941 MachineMemOperand *MMO =
8943 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8947 Ops, MVT::i32, MMO);
8950 }
else if (((Subtarget.hasLFIWAX() &&
8952 (Subtarget.hasFPCVT() &&
8967 "Expected an i32 store");
8973 RLI.Alignment =
Align(4);
8975 MachineMemOperand *MMO =
8977 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8980 PPCISD::LFIWZX : PPCISD::LFIWAX,
8981 dl, DAG.
getVTList(MVT::f64, MVT::Other),
8982 Ops, MVT::i32, MMO);
8983 Chain =
Bits.getValue(1);
8991 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8995 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)},
9004 assert(Src.getValueType() == MVT::i32 &&
9005 "Unhandled INT_TO_FP type in custom expander!");
9015 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
9018 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
9028 "Expected an i32 store");
9034 RLI.Alignment =
Align(4);
9037 MachineMemOperand *MMO =
9039 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
9045 if (ReusingLoad && RLI.ResChain) {
9049 assert(Subtarget.isPPC64() &&
9050 "i32->FP without LFIWAX supported only on PPC64");
9059 Chain, dl, Ext64, FIdx,
9065 MVT::f64, dl, Chain, FIdx,
9074 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
9078 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)}, Flags);
9095 uint64_t
Mode = CVal->getZExtValue();
9096 assert(
Mode < 4 &&
"Unsupported rounding mode!");
9097 unsigned InternalRnd =
Mode ^ (~(
Mode >> 1) & 1);
9098 if (Subtarget.isISA3_0())
9101 PPC::MFFSCRNI, Dl, {MVT::f64, MVT::Other},
9102 {DAG.getConstant(InternalRnd, Dl, MVT::i32, true), Chain}),
9105 (InternalRnd & 2) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9106 {DAG.
getConstant(30, Dl, MVT::i32,
true), Chain});
9108 (InternalRnd & 1) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9126 if (!Subtarget.isISA3_0()) {
9127 MFFS = DAG.
getNode(PPCISD::MFFS, Dl, {MVT::f64, MVT::Other}, Chain);
9131 if (Subtarget.isPPC64()) {
9132 if (Subtarget.isISA3_0()) {
9137 PPC::RLDIMI, Dl, MVT::i64,
9142 NewFPSCR =
SDValue(InsertRN, 0);
9149 SDValue Addr = Subtarget.isLittleEndian()
9153 if (Subtarget.isISA3_0()) {
9154 Chain = DAG.
getStore(Chain, Dl, DstFlag, Addr, MachinePointerInfo());
9156 Chain = DAG.
getStore(Chain, Dl, MFFS, StackSlot, MachinePointerInfo());
9158 DAG.
getLoad(MVT::i32, Dl, Chain, Addr, MachinePointerInfo());
9161 PPC::RLWIMI, Dl, MVT::i32,
9162 {Tmp, DstFlag, DAG.getTargetConstant(0, Dl, MVT::i32),
9163 DAG.getTargetConstant(30, Dl, MVT::i32),
9164 DAG.getTargetConstant(31, Dl, MVT::i32)}),
9166 Chain = DAG.
getStore(Chain, Dl, Tmp, Addr, MachinePointerInfo());
9169 DAG.
getLoad(MVT::f64, Dl, Chain, StackSlot, MachinePointerInfo());
9172 if (Subtarget.isISA3_0())
9178 PPC::MTFSF, Dl, MVT::Other,
9206 EVT VT =
Op.getValueType();
9211 SDValue MFFS = DAG.
getNode(PPCISD::MFFS, dl, {MVT::f64, MVT::Other}, Chain);
9222 Chain = DAG.
getStore(Chain, dl, MFFS, StackSlot, MachinePointerInfo());
9226 "Stack slot adjustment is valid only on big endian subtargets!");
9229 CWD = DAG.
getLoad(MVT::i32, dl, Chain, Addr, MachinePointerInfo());
9256 EVT VT =
Op.getValueType();
9260 VT ==
Op.getOperand(1).getValueType() &&
9280 SDValue OutOps[] = { OutLo, OutHi };
9285 EVT VT =
Op.getValueType();
9289 VT ==
Op.getOperand(1).getValueType() &&
9309 SDValue OutOps[] = { OutLo, OutHi };
9315 EVT VT =
Op.getValueType();
9318 VT ==
Op.getOperand(1).getValueType() &&
9338 SDValue OutOps[] = { OutLo, OutHi };
9345 EVT VT =
Op.getValueType();
9352 EVT AmtVT =
Z.getValueType();
9362 X = DAG.
getNode(PPCISD::SHL, dl, VT,
X, IsFSHL ? Z : SubZ);
9363 Y = DAG.
getNode(PPCISD::SRL, dl, VT,
Y, IsFSHL ? SubZ : Z);
9375 static const MVT VTys[] = {
9376 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9379 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9382 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9387 EVT CanonicalVT = VTys[SplatSize-1];
9400 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9401 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9410 EVT DestVT = MVT::Other) {
9411 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9420 EVT DestVT = MVT::Other) {
9423 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9435 for (
unsigned i = 0; i != 16; ++i)
9456 EVT VecVT = V->getValueType(0);
9457 bool RightType = VecVT == MVT::v2f64 ||
9458 (HasP8Vector && VecVT == MVT::v4f32) ||
9459 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9463 bool IsSplat =
true;
9464 bool IsLoad =
false;
9470 if (V->isConstant())
9472 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9473 if (V->getOperand(i).isUndef())
9477 if (V->getOperand(i).getOpcode() ==
ISD::LOAD ||
9479 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9481 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9483 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD))
9487 if (V->getOperand(i) != Op0 ||
9488 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9491 return !(IsSplat && IsLoad);
9501 (
Op.getValueType() != MVT::f128))
9506 if ((
Lo.getValueType() != MVT::i64) || (
Hi.getValueType() != MVT::i64))
9509 if (!Subtarget.isLittleEndian())
9512 return DAG.
getNode(PPCISD::BUILD_FP128, dl, MVT::f128,
Lo,
Hi);
9520 InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED) {
9521 IsPermuted = InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED;
9534 APFloat APFloatToConvert = ArgAPFloat;
9535 bool LosesInfo =
true;
9540 ArgAPFloat = APFloatToConvert;
9562 APFloat APFloatToConvert = ArgAPFloat;
9563 bool LosesInfo =
true;
9567 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9576 EVT Ty =
Op->getValueType(0);
9579 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9588 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9592 if (Ty == MVT::v2i64) {
9595 if (MemVT == MVT::i32) {
9597 Opcode = PPCISD::ZEXT_LD_SPLAT;
9599 Opcode = PPCISD::SEXT_LD_SPLAT;
9607 bool IsLittleEndian) {
9613 APInt ConstValue(VTSize, 0);
9617 unsigned BitPos = 0;
9625 ConstValue.
insertBits(CN->getAPIntValue().zextOrTrunc(EltWidth),
9626 IsLittleEndian ? BitPos : VTSize - EltWidth - BitPos);
9630 for (
unsigned J = 0; J < 16; ++J) {
9632 if (ExtractValue != 0x00 && ExtractValue != 0xFF)
9634 if (ExtractValue == 0xFF)
9649 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9651 if (Subtarget.hasP10Vector()) {
9652 APInt BitMask(32, 0);
9658 BitMask != 0 && BitMask != 0xffff) {
9660 MachineSDNode *MSDNode =
9672 if (
SDValue VecPat = combineBVLoadsSpecialValue(
Op, DAG))
9676 APInt APSplatBits, APSplatUndef;
9677 unsigned SplatBitSize = 0;
9679 bool BVNIsConstantSplat =
9681 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
9687 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9688 Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
9691 if ((
Op->getValueType(0) == MVT::v2f64) &&
9694 PPCISD::XXSPLTI_SP_TO_DP, dl, MVT::v2f64,
9710 PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9716 DAG.
getNode(PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9725 LowerVecSplatSmallFP(
Op, DAG, BVNIsConstantSplat, SplatBitSize))
9728 bool IsSplat64 =
false;
9729 uint64_t SplatBits = 0;
9730 int32_t SextVal = 0;
9731 if (BVNIsConstantSplat && SplatBitSize <= 64) {
9733 if (SplatBitSize <= 32) {
9735 }
else if (SplatBitSize == 64 && Subtarget.hasP8Altivec()) {
9736 int64_t Splat64Val =
static_cast<int64_t
>(SplatBits);
9737 bool P9Vector = Subtarget.hasP9Vector();
9738 int32_t
Hi = P9Vector ? 127 : 15;
9739 int32_t
Lo = P9Vector ? -128 : -16;
9740 IsSplat64 = Splat64Val >=
Lo && Splat64Val <=
Hi;
9741 SextVal =
static_cast<int32_t
>(SplatBits);
9745 if (!BVNIsConstantSplat || (SplatBitSize > 32 && !IsSplat64)) {
9746 unsigned NewOpcode = PPCISD::LD_SPLAT;
9752 const SDValue *InputLoad = &
Op.getOperand(0);
9757 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9758 unsigned ElementSize =
9759 MemorySize * ((NewOpcode == PPCISD::LD_SPLAT) ? 1 : 2);
9761 assert(((ElementSize == 2 * MemorySize)
9762 ? (NewOpcode == PPCISD::ZEXT_LD_SPLAT ||
9763 NewOpcode == PPCISD::SEXT_LD_SPLAT)
9764 : (NewOpcode == PPCISD::LD_SPLAT)) &&
9765 "Unmatched element size and opcode!\n");
9770 unsigned NumUsesOfInputLD = 128 / ElementSize;
9772 if (BVInOp.isUndef())
9787 if (NumUsesOfInputLD == 1 &&
9788 (
Op->getValueType(0) == MVT::v2i64 && NewOpcode != PPCISD::LD_SPLAT &&
9789 !Subtarget.isLittleEndian() && Subtarget.hasVSX() &&
9790 Subtarget.hasLFIWAX()))
9798 if (NumUsesOfInputLD == 1 && Subtarget.isLittleEndian() &&
9799 Subtarget.isISA3_1() && ElementSize <= 16)
9802 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9804 Subtarget.hasVSX()) {
9811 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other),
Ops,
9812 LD->getMemoryVT(),
LD->getMemOperand());
9824 if (Subtarget.hasVSX() && Subtarget.isPPC64() &&
9826 Subtarget.hasP8Vector()))
9832 unsigned SplatSize = SplatBitSize / 8;
9837 if (SplatBits == 0) {
9839 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9851 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 2)
9853 Op.getValueType(), DAG, dl);
9855 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 4)
9860 if (Subtarget.hasP9Vector() && SplatSize == 1)
9866 if (SextVal >= -16 && SextVal <= 15) {
9869 unsigned UseSize = SplatSize == 8 ? 4 : SplatSize;
9876 DAG.
getBitcast(MVT::v4i32, Res), DAG, dl, MVT::v2i64);
9882 if (Subtarget.hasP9Vector() && SextVal >= -128 && SextVal <= 127) {
9888 switch (SplatSize) {
9892 IID = Intrinsic::ppc_altivec_vupklsb;
9896 IID = Intrinsic::ppc_altivec_vextsb2w;
9900 IID = Intrinsic::ppc_altivec_vextsb2d;
9907 assert(!IsSplat64 &&
"Unhandled 64-bit splat pattern");
9916 if (SextVal >= -32 && SextVal <= 31) {
9921 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9922 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9925 if (VT ==
Op.getValueType())
9934 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9948 static const signed char SplatCsts[] = {
9949 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9950 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9953 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9956 int i = SplatCsts[idx];
9960 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9963 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9965 static const unsigned IIDs[] = {
9966 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9967 Intrinsic::ppc_altivec_vslw
9974 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9976 static const unsigned IIDs[] = {
9977 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9978 Intrinsic::ppc_altivec_vsrw
9985 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9986 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9988 static const unsigned IIDs[] = {
9989 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
9990 Intrinsic::ppc_altivec_vrlw
9997 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
9999 unsigned Amt = Subtarget.isLittleEndian() ? 15 : 1;
10003 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
10005 unsigned Amt = Subtarget.isLittleEndian() ? 14 : 2;
10009 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
10011 unsigned Amt = Subtarget.isLittleEndian() ? 13 : 3;
10024 unsigned OpNum = (PFEntry >> 26) & 0x0F;
10025 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
10026 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
10042 if (LHSID == (1*9+2)*9+3)
return LHS;
10043 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
10055 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
10056 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
10057 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
10058 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
10061 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
10062 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
10063 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
10064 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
10067 for (
unsigned i = 0; i != 16; ++i)
10068 ShufIdxs[i] = (i&3)+0;
10071 for (
unsigned i = 0; i != 16; ++i)
10072 ShufIdxs[i] = (i&3)+4;
10075 for (
unsigned i = 0; i != 16; ++i)
10076 ShufIdxs[i] = (i&3)+8;
10079 for (
unsigned i = 0; i != 16; ++i)
10080 ShufIdxs[i] = (i&3)+12;
10101 const unsigned BytesInVector = 16;
10102 bool IsLE = Subtarget.isLittleEndian();
10106 unsigned ShiftElts = 0, InsertAtByte = 0;
10110 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
10111 0, 15, 14, 13, 12, 11, 10, 9};
10112 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
10113 1, 2, 3, 4, 5, 6, 7, 8};
10115 ArrayRef<int>
Mask =
N->getMask();
10116 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
10128 bool FoundCandidate =
false;
10132 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
10135 for (
unsigned i = 0; i < BytesInVector; ++i) {
10136 unsigned CurrentElement =
Mask[i];
10139 if (V2.
isUndef() && CurrentElement != VINSERTBSrcElem)
10142 bool OtherElementsInOrder =
true;
10145 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
10152 (!V2.
isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
10153 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
10154 OtherElementsInOrder =
false;
10161 if (OtherElementsInOrder) {
10168 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
10169 : BigEndianShifts[CurrentElement & 0xF];
10170 Swap = CurrentElement < BytesInVector;
10172 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
10173 FoundCandidate =
true;
10178 if (!FoundCandidate)
10188 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10190 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8,
V1, Shl,
10193 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8,
V1, V2,
10202 const unsigned NumHalfWords = 8;
10203 const unsigned BytesInVector = NumHalfWords * 2;
10208 bool IsLE = Subtarget.isLittleEndian();
10212 unsigned ShiftElts = 0, InsertAtByte = 0;
10216 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
10217 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
10220 uint32_t OriginalOrderLow = 0x1234567;
10221 uint32_t OriginalOrderHigh = 0x89ABCDEF;
10224 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10225 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10242 bool FoundCandidate =
false;
10245 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10246 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10248 uint32_t MaskOtherElts = ~(0xF <<
MaskShift);
10249 uint32_t TargetOrder = 0x0;
10256 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
10257 TargetOrder = OriginalOrderLow;
10261 if (MaskOneElt == VINSERTHSrcElem &&
10262 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10263 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10264 FoundCandidate =
true;
10270 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
10272 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10274 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
10275 : BigEndianShifts[MaskOneElt & 0x7];
10276 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10277 Swap = MaskOneElt < NumHalfWords;
10278 FoundCandidate =
true;
10284 if (!FoundCandidate)
10296 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10299 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
10304 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
10319 auto ShuffleMask = SVN->
getMask();
10334 ShuffleMask = CommutedSV->
getMask();
10343 APInt APSplatValue, APSplatUndef;
10344 unsigned SplatBitSize;
10347 HasAnyUndefs, 0, !Subtarget.isLittleEndian()) ||
10359 bool IsLE = Subtarget.isLittleEndian();
10360 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
10361 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
10362 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
10364 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
10365 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
10366 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
10374 for (; SplatBitSize < 32; SplatBitSize <<= 1)
10375 SplatVal |= (SplatVal << SplatBitSize);
10378 PPCISD::XXSPLTI32DX,
DL, MVT::v2i64, DAG.
getBitcast(MVT::v2i64,
LHS),
10389 assert(
Op.getValueType() == MVT::v1i128 &&
10390 "Only set v1i128 as custom, other type shouldn't reach here!");
10395 if (SHLAmt % 8 == 0) {
10396 std::array<int, 16>
Mask;
10397 std::iota(
Mask.begin(),
Mask.end(), 0);
10398 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10427 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10432 V1 =
Op.getOperand(0);
10433 V2 =
Op.getOperand(1);
10435 EVT VT =
Op.getValueType();
10436 bool isLittleEndian = Subtarget.isLittleEndian();
10438 unsigned ShiftElts, InsertAtByte;
10444 bool IsPermutedLoad =
false;
10446 if (InputLoad && Subtarget.hasVSX() && V2.
isUndef() &&
10456 if (IsPermutedLoad) {
10457 assert((isLittleEndian || IsFourByte) &&
10458 "Unexpected size for permuted load on big endian target");
10459 SplatIdx += IsFourByte ? 2 : 1;
10460 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10461 "Splat of a value outside of the loaded memory");
10466 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10469 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10471 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10475 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10488 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10491 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10500 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10503 if (Subtarget.hasP9Vector() &&
10513 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv2, Conv2,
10515 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Shl,
10519 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Conv2,
10524 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
10526 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10527 return SplatInsertNode;
10530 if (Subtarget.hasP9Altivec()) {
10532 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10535 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10539 if (Subtarget.hasVSX() &&
10547 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv1, Conv2,
10552 if (Subtarget.hasVSX() &&
10560 SDValue PermDI = DAG.
getNode(PPCISD::XXPERMDI, dl, MVT::v2i64, Conv1, Conv2,
10565 if (Subtarget.hasP9Vector()) {
10585 if (Subtarget.hasVSX()) {
10598 SDValue Swap = DAG.
getNode(PPCISD::SWAP_NO_CHAIN, dl, MVT::v2f64, Conv);
10606 if (V2.isUndef()) {
10619 (Subtarget.hasP8Altivec() && (
10630 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10640 (Subtarget.hasP8Altivec() && (
10648 ArrayRef<int> PermMask = SVOp->
getMask();
10651 unsigned PFIndexes[4];
10652 bool isFourElementShuffle =
true;
10653 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10655 unsigned EltNo = 8;
10656 for (
unsigned j = 0;
j != 4; ++
j) {
10657 if (PermMask[i * 4 + j] < 0)
10660 unsigned ByteSource = PermMask[i * 4 +
j];
10661 if ((ByteSource & 3) != j) {
10662 isFourElementShuffle =
false;
10667 EltNo = ByteSource / 4;
10668 }
else if (EltNo != ByteSource / 4) {
10669 isFourElementShuffle =
false;
10673 PFIndexes[i] = EltNo;
10681 if (isFourElementShuffle) {
10683 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10684 PFIndexes[2] * 9 + PFIndexes[3];
10687 unsigned Cost = (PFEntry >> 30);
10707 if (V2.isUndef()) V2 =
V1;
10709 return LowerVPERM(
Op, DAG, PermMask, VT,
V1, V2);
10715 unsigned Opcode = PPCISD::VPERM;
10718 bool NeedSwap =
false;
10719 bool isLittleEndian = Subtarget.isLittleEndian();
10720 bool isPPC64 = Subtarget.isPPC64();
10722 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10724 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10725 "XXPERM instead\n");
10726 Opcode = PPCISD::XXPERM;
10731 if ((!isLittleEndian && !V2->
hasOneUse() &&
V1->hasOneUse()) ||
10732 (isLittleEndian && !
V1->hasOneUse() && V2->
hasOneUse())) {
10734 NeedSwap = !NeedSwap;
10748 bool V1HasXXSWAPD =
V1->getOperand(0)->getOpcode() == PPCISD::XXSWAPD;
10769 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10771 if (V1HasXXSWAPD) {
10774 else if (SrcElt < 16)
10777 if (V2HasXXSWAPD) {
10780 else if (SrcElt > 15)
10789 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10790 if (isLittleEndian)
10792 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10795 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10798 if (V1HasXXSWAPD) {
10799 dl = SDLoc(
V1->getOperand(0));
10800 V1 =
V1->getOperand(0)->getOperand(1);
10802 if (V2HasXXSWAPD) {
10807 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10808 if (ValType != MVT::v2f64)
10814 ShufflesHandledWithVPERM++;
10818 if (Opcode == PPCISD::XXPERM) {
10819 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10821 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10824 dbgs() <<
"With the following permute control vector:\n";
10828 if (Opcode == PPCISD::XXPERM)
10829 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10833 if (isLittleEndian)
10837 DAG.
getNode(Opcode, dl,
V1.getValueType(),
V1, V2, VPermMask);
10839 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10851 switch (IntrinsicID) {
10855 case Intrinsic::ppc_altivec_vcmpbfp_p:
10859 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10863 case Intrinsic::ppc_altivec_vcmpequb_p:
10867 case Intrinsic::ppc_altivec_vcmpequh_p:
10871 case Intrinsic::ppc_altivec_vcmpequw_p:
10875 case Intrinsic::ppc_altivec_vcmpequd_p:
10876 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10882 case Intrinsic::ppc_altivec_vcmpneb_p:
10883 case Intrinsic::ppc_altivec_vcmpneh_p:
10884 case Intrinsic::ppc_altivec_vcmpnew_p:
10885 case Intrinsic::ppc_altivec_vcmpnezb_p:
10886 case Intrinsic::ppc_altivec_vcmpnezh_p:
10887 case Intrinsic::ppc_altivec_vcmpnezw_p:
10888 if (Subtarget.hasP9Altivec()) {
10889 switch (IntrinsicID) {
10892 case Intrinsic::ppc_altivec_vcmpneb_p:
10895 case Intrinsic::ppc_altivec_vcmpneh_p:
10898 case Intrinsic::ppc_altivec_vcmpnew_p:
10901 case Intrinsic::ppc_altivec_vcmpnezb_p:
10904 case Intrinsic::ppc_altivec_vcmpnezh_p:
10907 case Intrinsic::ppc_altivec_vcmpnezw_p:
10915 case Intrinsic::ppc_altivec_vcmpgefp_p:
10919 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10923 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10927 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10931 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10935 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10936 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10942 case Intrinsic::ppc_altivec_vcmpgtub_p:
10946 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10950 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10954 case Intrinsic::ppc_altivec_vcmpgtud_p:
10955 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10962 case Intrinsic::ppc_altivec_vcmpequq:
10963 case Intrinsic::ppc_altivec_vcmpgtsq:
10964 case Intrinsic::ppc_altivec_vcmpgtuq:
10965 if (!Subtarget.isISA3_1())
10967 switch (IntrinsicID) {
10970 case Intrinsic::ppc_altivec_vcmpequq:
10973 case Intrinsic::ppc_altivec_vcmpgtsq:
10976 case Intrinsic::ppc_altivec_vcmpgtuq:
10983 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10984 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10985 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10986 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10987 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10988 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10989 if (Subtarget.hasVSX()) {
10990 switch (IntrinsicID) {
10991 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10994 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10997 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
11000 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
11003 case Intrinsic::ppc_vsx_xvcmpgesp_p:
11006 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
11016 case Intrinsic::ppc_altivec_vcmpbfp:
11019 case Intrinsic::ppc_altivec_vcmpeqfp:
11022 case Intrinsic::ppc_altivec_vcmpequb:
11025 case Intrinsic::ppc_altivec_vcmpequh:
11028 case Intrinsic::ppc_altivec_vcmpequw:
11031 case Intrinsic::ppc_altivec_vcmpequd:
11032 if (Subtarget.hasP8Altivec())
11037 case Intrinsic::ppc_altivec_vcmpneb:
11038 case Intrinsic::ppc_altivec_vcmpneh:
11039 case Intrinsic::ppc_altivec_vcmpnew:
11040 case Intrinsic::ppc_altivec_vcmpnezb:
11041 case Intrinsic::ppc_altivec_vcmpnezh:
11042 case Intrinsic::ppc_altivec_vcmpnezw:
11043 if (Subtarget.hasP9Altivec())
11044 switch (IntrinsicID) {
11047 case Intrinsic::ppc_altivec_vcmpneb:
11050 case Intrinsic::ppc_altivec_vcmpneh:
11053 case Intrinsic::ppc_altivec_vcmpnew:
11056 case Intrinsic::ppc_altivec_vcmpnezb:
11059 case Intrinsic::ppc_altivec_vcmpnezh:
11062 case Intrinsic::ppc_altivec_vcmpnezw:
11069 case Intrinsic::ppc_altivec_vcmpgefp:
11072 case Intrinsic::ppc_altivec_vcmpgtfp:
11075 case Intrinsic::ppc_altivec_vcmpgtsb:
11078 case Intrinsic::ppc_altivec_vcmpgtsh:
11081 case Intrinsic::ppc_altivec_vcmpgtsw:
11084 case Intrinsic::ppc_altivec_vcmpgtsd:
11085 if (Subtarget.hasP8Altivec())
11090 case Intrinsic::ppc_altivec_vcmpgtub:
11093 case Intrinsic::ppc_altivec_vcmpgtuh:
11096 case Intrinsic::ppc_altivec_vcmpgtuw:
11099 case Intrinsic::ppc_altivec_vcmpgtud:
11100 if (Subtarget.hasP8Altivec())
11105 case Intrinsic::ppc_altivec_vcmpequq_p:
11106 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11107 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11108 if (!Subtarget.isISA3_1())
11110 switch (IntrinsicID) {
11113 case Intrinsic::ppc_altivec_vcmpequq_p:
11116 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11119 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11133 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
11139 auto MapNodeWithSplatVector =
11140 [&](
unsigned Opcode,
11141 std::initializer_list<SDValue> ExtraOps = {}) ->
SDValue {
11146 Ops.append(ExtraOps.begin(), ExtraOps.end());
11147 return DAG.
getNode(Opcode, dl, MVT::v16i8,
Ops);
11150 switch (IntrinsicID) {
11151 case Intrinsic::thread_pointer:
11153 if (Subtarget.isPPC64())
11157 case Intrinsic::ppc_rldimi: {
11158 assert(Subtarget.isPPC64() &&
"rldimi is only available in 64-bit!");
11160 APInt
Mask =
Op.getConstantOperandAPInt(4);
11162 return Op.getOperand(2);
11163 if (
Mask.isAllOnes())
11165 uint64_t SH =
Op.getConstantOperandVal(3);
11166 unsigned MB = 0, ME = 0;
11170 if (ME < 63 - SH) {
11173 }
else if (ME > 63 - SH) {
11179 {Op.getOperand(2), Src,
11180 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
11181 DAG.getTargetConstant(MB, dl, MVT::i32)}),
11185 case Intrinsic::ppc_rlwimi: {
11186 APInt
Mask =
Op.getConstantOperandAPInt(4);
11188 return Op.getOperand(2);
11189 if (
Mask.isAllOnes())
11192 unsigned MB = 0, ME = 0;
11196 PPC::RLWIMI, dl, MVT::i32,
11197 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
11198 DAG.getTargetConstant(MB, dl, MVT::i32),
11199 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11203 case Intrinsic::ppc_bcdshift:
11204 return MapNodeWithSplatVector(PPCISD::BCDSHIFT, {
Op.getOperand(3)});
11205 case Intrinsic::ppc_bcdshiftround:
11206 return MapNodeWithSplatVector(PPCISD::BCDSHIFTROUND, {
Op.getOperand(3)});
11207 case Intrinsic::ppc_bcdtruncate:
11208 return MapNodeWithSplatVector(PPCISD::BCDTRUNC, {
Op.getOperand(3)});
11209 case Intrinsic::ppc_bcdunsignedtruncate:
11210 return MapNodeWithSplatVector(PPCISD::BCDUTRUNC);
11211 case Intrinsic::ppc_bcdunsignedshift:
11212 return MapNodeWithSplatVector(PPCISD::BCDUSHIFT);
11214 case Intrinsic::ppc_rlwnm: {
11215 if (
Op.getConstantOperandVal(3) == 0)
11217 unsigned MB = 0, ME = 0;
11222 {Op.getOperand(1), Op.getOperand(2),
11223 DAG.getTargetConstant(MB, dl, MVT::i32),
11224 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11228 case Intrinsic::ppc_mma_disassemble_acc: {
11229 if (Subtarget.isISAFuture()) {
11230 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11241 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11242 Subtarget.isLittleEndian() ? Value2 :
Value,
11243 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11247 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11248 Subtarget.isLittleEndian() ? Value2 :
Value,
11249 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11253 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11254 Subtarget.isLittleEndian() ?
Value : Value2,
11255 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11259 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11260 Subtarget.isLittleEndian() ?
Value : Value2,
11261 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11268 case Intrinsic::ppc_vsx_disassemble_pair: {
11271 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
11273 WideVec = DAG.
getNode(PPCISD::XXMFACC, dl, MVT::v512i1, WideVec);
11276 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
11278 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8, WideVec,
11279 DAG.
getConstant(Subtarget.isLittleEndian() ? NumVecs - 1 - VecNo
11287 case Intrinsic::ppc_build_dmr: {
11290 for (
int i = 1; i < 9; i += 2) {
11298 DAG.
getNode(PPCISD::PAIR_BUILD, dl, MVT::v256i1, {Hi, Lo}));
11305 case Intrinsic::ppc_mma_dmxxextfdmr512: {
11306 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr512 requires ISA Future");
11308 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11309 "Specify P of 0 or 1 for lower or upper 512 bytes");
11310 unsigned HiLo = Idx->getSExtValue();
11314 Opcode = PPC::DMXXEXTFDMR512;
11315 Subx = PPC::sub_wacc_lo;
11317 Opcode = PPC::DMXXEXTFDMR512_HI;
11318 Subx = PPC::sub_wacc_hi;
11321 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
11325 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11329 case Intrinsic::ppc_mma_dmxxextfdmr256: {
11330 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr256 requires ISA Future");
11332 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11333 "Specify a dmr row pair 0-3");
11334 unsigned IdxVal = Idx->getSExtValue();
11338 Subx = PPC::sub_dmrrowp0;
11341 Subx = PPC::sub_dmrrowp1;
11344 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11347 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11351 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v256i1,
11357 DAG.
getMachineNode(PPC::DMXXEXTFDMR256, dl, MVT::v256i1, {Subreg, P}),
11361 case Intrinsic::ppc_mma_dmxxinstdmr512: {
11362 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr512 requires ISA Future");
11364 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11365 "Specify P of 0 or 1 for lower or upper 512 bytes");
11366 unsigned HiLo = Idx->getSExtValue();
11370 Opcode = PPCISD::INST512;
11371 Subx = PPC::sub_wacc_lo;
11373 Opcode = PPCISD::INST512HI;
11374 Subx = PPC::sub_wacc_hi;
11380 Op.getOperand(1), Wacc, SubReg),
11384 case Intrinsic::ppc_mma_dmxxinstdmr256: {
11385 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr256 requires ISA Future");
11387 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11388 "Specify a dmr row pair 0-3");
11389 unsigned IdxVal = Idx->getSExtValue();
11393 Subx = PPC::sub_dmrrowp0;
11396 Subx = PPC::sub_dmrrowp1;
11399 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11402 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11408 DAG.
getNode(PPCISD::INST256, dl, MVT::v256i1,
Op.getOperand(2),
P);
11410 Op.getOperand(1), DMRRowp, SubReg),
11414 case Intrinsic::ppc_mma_xxmfacc:
11415 case Intrinsic::ppc_mma_xxmtacc: {
11417 if (!Subtarget.isISAFuture())
11428 case Intrinsic::ppc_unpack_longdouble: {
11430 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11431 "Argument of long double unpack must be 0 or 1!");
11434 Idx->getValueType(0)));
11437 case Intrinsic::ppc_compare_exp_lt:
11438 case Intrinsic::ppc_compare_exp_gt:
11439 case Intrinsic::ppc_compare_exp_eq:
11440 case Intrinsic::ppc_compare_exp_uo: {
11442 switch (IntrinsicID) {
11443 case Intrinsic::ppc_compare_exp_lt:
11446 case Intrinsic::ppc_compare_exp_gt:
11449 case Intrinsic::ppc_compare_exp_eq:
11452 case Intrinsic::ppc_compare_exp_uo:
11458 PPC::SELECT_CC_I4, dl, MVT::i32,
11459 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
11460 Op.getOperand(1), Op.getOperand(2)),
11462 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11463 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
11466 case Intrinsic::ppc_test_data_class: {
11467 EVT OpVT =
Op.getOperand(1).getValueType();
11468 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
11469 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
11482 {Op.getOperand(2), Op.getOperand(1)}),
11484 if (Subtarget.isISA3_1()) {
11491 TestDataClass, SubRegIdx),
11494 return DAG.
getNode(PPCISD::SETBC, dl, MVT::i32, CRBit);
11500 {TestDataClass, DAG.getConstant(1, dl, MVT::i32),
11501 DAG.getConstant(0, dl, MVT::i32),
11502 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
11505 case Intrinsic::ppc_fnmsub: {
11506 EVT VT =
Op.getOperand(1).getValueType();
11507 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
11512 return DAG.
getNode(PPCISD::FNMSUB, dl, VT,
Op.getOperand(1),
11513 Op.getOperand(2),
Op.getOperand(3));
11515 case Intrinsic::ppc_convert_f128_to_ppcf128:
11516 case Intrinsic::ppc_convert_ppcf128_to_f128: {
11517 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
11518 ? RTLIB::CONVERT_PPCF128_F128
11519 : RTLIB::CONVERT_F128_PPCF128;
11521 std::pair<SDValue, SDValue>
Result =
11522 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
11526 case Intrinsic::ppc_maxfe:
11527 case Intrinsic::ppc_maxfl:
11528 case Intrinsic::ppc_maxfs:
11529 case Intrinsic::ppc_minfe:
11530 case Intrinsic::ppc_minfl:
11531 case Intrinsic::ppc_minfs: {
11532 EVT VT =
Op.getValueType();
11535 [VT](
const SDUse &Use) { return Use.getValueType() == VT; }) &&
11536 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
11539 if (IntrinsicID == Intrinsic::ppc_minfe ||
11540 IntrinsicID == Intrinsic::ppc_minfl ||
11541 IntrinsicID == Intrinsic::ppc_minfs)
11562 SDValue Tmp = DAG.
getNode(PPCISD::VCMP, dl,
Op.getOperand(2).getValueType(),
11563 Op.getOperand(1),
Op.getOperand(2),
11574 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11582 switch (
Op.getConstantOperandVal(1)) {
11587 Bitx = PPC::sub_eq;
11588 SetOp = PPCISD::SETBC;
11593 Bitx = PPC::sub_eq;
11594 SetOp = PPCISD::SETBCR;
11599 Bitx = PPC::sub_lt;
11600 SetOp = PPCISD::SETBC;
11605 Bitx = PPC::sub_lt;
11606 SetOp = PPCISD::SETBCR;
11611 if (Subtarget.isISA3_1()) {
11616 CR6Reg, SubRegIdx, GlueOp),
11618 return DAG.
getNode(SetOp, dl, MVT::i32, CRBit);
11646 switch (
Op.getConstantOperandVal(ArgStart)) {
11647 case Intrinsic::ppc_cfence: {
11648 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11649 SDValue Val =
Op.getOperand(ArgStart + 1);
11651 if (Ty == MVT::i128) {
11656 unsigned Opcode = Subtarget.isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11659 Opcode,
DL, MVT::Other,
11664 case Intrinsic::ppc_disassemble_dmr: {
11666 "llvm.ppc.disassemble.dmr must carry a chain argument.");
11667 return DAG.
getStore(
Op.getOperand(0),
DL,
Op.getOperand(ArgStart + 2),
11668 Op.getOperand(ArgStart + 1), MachinePointerInfo());
11679 if (!Subtarget.isPPC64())
11682 if (Subtarget.hasP9Vector()) {
11689 int VectorIndex = 0;
11690 if (Subtarget.isLittleEndian())
11700 auto CreateRotateInsert =
11701 [&](
unsigned Opcode, MVT VT,
SDValue Dest,
SDValue Src,
unsigned RotAmt,
11702 unsigned MaskBegin,
11703 std::optional<unsigned> MaskEnd = std::nullopt) ->
SDValue {
11707 if (MaskEnd.has_value())
11719 CreateRotateInsert(PPC::RLWIMI, MVT::i32, Rot, Val32, 24, 0, 7);
11721 return CreateRotateInsert(PPC::RLWIMI, MVT::i32, Swap, Val32, 24, 16, 23);
11734 return CreateRotateInsert(PPC::RLDIMI, MVT::i64, HiSwap, LoSwap, 32, 0);
11742 "Expecting an atomic compare-and-swap here.");
11745 EVT MemVT = AtomicNode->getMemoryVT();
11763 for (
int i = 0, e = AtomicNode->getNumOperands(); i < e; i++)
11764 Ops.push_back(AtomicNode->getOperand(i));
11766 MachineMemOperand *MMO = AtomicNode->getMemOperand();
11767 SDVTList Tys = DAG.
getVTList(MVT::i32, MVT::Other);
11769 (MemVT == MVT::i8) ? PPCISD::ATOMIC_CMP_SWAP_8 : PPCISD::ATOMIC_CMP_SWAP_16;
11776 EVT MemVT =
N->getMemoryVT();
11778 "Expect quadword atomic operations");
11780 unsigned Opc =
N->getOpcode();
11785 SDVTList Tys = DAG.
getVTList(MVT::i64, MVT::i64, MVT::Other);
11788 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11789 for (
int I = 1,
E =
N->getNumOperands();
I <
E; ++
I)
11790 Ops.push_back(
N->getOperand(
I));
11792 Ops, MemVT,
N->getMemOperand());
11799 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11806 SDVTList Tys = DAG.
getVTList(MVT::Other);
11809 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11815 Ops.push_back(ValLo);
11816 Ops.push_back(ValHi);
11817 Ops.push_back(
N->getOperand(2));
11819 N->getMemOperand());
11831 enum DataClassMask {
11833 DC_NEG_INF = 1 << 4,
11834 DC_POS_INF = 1 << 5,
11835 DC_NEG_ZERO = 1 << 2,
11836 DC_POS_ZERO = 1 << 3,
11837 DC_NEG_SUBNORM = 1,
11838 DC_POS_SUBNORM = 1 << 1,
11841 EVT VT =
Op.getValueType();
11843 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11844 : VT == MVT::f64 ? PPC::XSTSTDCDP
11855 return DAG.
getNOT(Dl, Rev, MVT::i1);
11862 TestOp, Dl, MVT::i32,
11864 DC_NEG_ZERO | DC_POS_ZERO |
11865 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11871 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11877 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11882 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11895 bool IsQuiet = Mask &
fcQNan;
11901 if (VT == MVT::f128) {
11905 QuietMask = 0x8000;
11906 }
else if (VT == MVT::f64) {
11907 if (Subtarget.isPPC64()) {
11918 QuietMask = 0x80000;
11919 }
else if (VT == MVT::f32) {
11921 QuietMask = 0x400000;
11937 unsigned NativeMask = 0;
11939 NativeMask |= DC_NAN;
11941 NativeMask |= DC_NEG_INF;
11943 NativeMask |= DC_POS_INF;
11945 NativeMask |= DC_NEG_ZERO;
11947 NativeMask |= DC_POS_ZERO;
11949 NativeMask |= DC_NEG_SUBNORM;
11951 NativeMask |= DC_POS_SUBNORM;
11954 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11956 TestOp, Dl, MVT::i32,
11965 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11967 uint64_t RHSC =
Op.getConstantOperandVal(1);
11970 if (
LHS.getValueType() == MVT::ppcf128) {
11994 bool Future = Subtarget.isISAFuture();
11997 "Mask predication not supported");
12000 unsigned IID = Future ? Intrinsic::ppc_vsx_lxvrl : Intrinsic::ppc_vsx_lxvl;
12001 unsigned EltBits =
Op->getValueType(0).getScalarType().getSizeInBits();
12005 SDVTList Tys = DAG.
getVTList(
Op->getValueType(0), MVT::Other);
12008 VPLD->getMemoryVT(), VPLD->getMemOperand());
12015 "Mask predication not supported");
12020 Op->getOperand(1).getValueType().getScalarType().getSizeInBits();
12021 bool Future = Subtarget.isISAFuture();
12022 unsigned IID = Future ? Intrinsic::ppc_vsx_stxvrl : Intrinsic::ppc_vsx_stxvl;
12025 VPST->getChain(), DAG.
getConstant(IID, dl, MVT::i32),
12028 SDVTList Tys = DAG.
getVTList(MVT::Other);
12031 VPST->getMemoryVT(), VPST->getMemOperand());
12042 "Unexpected partial reduction");
12065 unsigned EltSize =
Op.getValueType().getScalarSizeInBits();
12067 int64_t
IntVal =
Op.getConstantOperandVal(0);
12068 if (IntVal >= -16 && IntVal <= 15)
12074 if (Subtarget.hasLFIWAX() && Subtarget.hasVSX() &&
12079 MachineMemOperand *MMO =
12081 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
12084 PPCISD::LD_SPLAT, dl, DAG.
getVTList(MVT::v4i32, MVT::Other),
Ops,
12088 return Bits.getValue(0);
12104 !Subtarget.isLittleEndian() && ValVT.
isInteger() &&
12109 64 -
Op.getValueType().getScalarSizeInBits(), dl, ShiftAmountTy);
12116 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx,
12117 MachinePointerInfo());
12124 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx, MachinePointerInfo());
12130 "Should only be called for ISD::INSERT_VECTOR_ELT");
12134 EVT VT =
Op.getValueType();
12139 if (VT == MVT::v2f64 &&
C)
12142 if (Subtarget.hasP9Vector()) {
12151 if ((VT == MVT::v4f32) && (V2.
getValueType() == MVT::f32) &&
12157 BitcastLoad,
Op.getOperand(2));
12158 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
12162 if (Subtarget.isISA3_1()) {
12163 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.isPPC64())
12167 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
12168 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
12178 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
12181 unsigned InsertAtElement =
C->getZExtValue();
12182 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
12183 if (Subtarget.isLittleEndian()) {
12184 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
12186 return DAG.
getNode(PPCISD::VECINSERT, dl, VT,
V1, Mtvsrz,
12198 EVT VT =
Op.getValueType();
12199 bool IsV1024i1 = VT == MVT::v1024i1;
12200 bool IsV2048i1 = VT == MVT::v2048i1;
12204 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12206 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12207 "Dense Math support required.");
12208 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12217 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12218 MachineMemOperand *NewMMO =
12226 DAG.
getVTList(MVT::v256i1, MVT::Other),
12227 LoadOps, MVT::v256i1, NewMMO);
12232 if (Subtarget.isLittleEndian()) {
12233 std::reverse(Loads.
begin(), Loads.
end());
12234 std::reverse(LoadChains.
begin(), LoadChains.
end());
12246 SDValue Dmr1Value = DMFInsert1024(MoreLoads, dl, DAG);
12252 const SDValue DmrPOps[] = {DmrPRC,
Value, Dmr0Sub, Dmr1Value, Dmr1Sub};
12255 DAG.
getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v2048i1, DmrPOps), 0);
12264 DAG.
getNode(PPCISD::INST512, dl, MVT::v512i1, Pairs[0], Pairs[1]);
12267 DAG.
getNode(PPCISD::INST512HI, dl, MVT::v512i1, Pairs[2], Pairs[3]);
12272 {RC, Lo, LoSub, Hi, HiSub}),
12282 EVT VT =
Op.getValueType();
12284 if (VT == MVT::v1024i1 || VT == MVT::v2048i1)
12285 return LowerDMFVectorLoad(
Op, DAG);
12287 if (VT != MVT::v256i1 && VT != MVT::v512i1)
12291 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
12292 "Type unsupported without MMA");
12293 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12294 "Type unsupported without paired vector support");
12298 if (VT == MVT::v256i1 && Subtarget.isISAFuture())
12307 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12309 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
12318 if (Subtarget.isLittleEndian()) {
12319 std::reverse(Loads.
begin(), Loads.
end());
12320 std::reverse(LoadChains.
begin(), LoadChains.
end());
12324 DAG.
getNode(VT == MVT::v512i1 ? PPCISD::ACC_BUILD : PPCISD::PAIR_BUILD,
12340 bool IsV1024i1 = VT == MVT::v1024i1;
12341 bool IsV2048i1 = VT == MVT::v2048i1;
12345 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12347 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12348 "Dense Math support required.");
12349 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12351 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12354 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12359 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12363 MachineSDNode *ExtNode =
12367 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes,
Hi);
12373 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12379 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12385 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12390 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12395 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12400 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12404 MachineSDNode *ExtNode =
12405 DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr0Lo);
12409 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr0Hi);
12412 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr1Lo);
12416 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr1Hi);
12421 if (Subtarget.isLittleEndian())
12424 SDVTList Tys = DAG.
getVTList(MVT::Other);
12426 StoreChain, DAG.
getConstant(Intrinsic::ppc_vsx_stxvp, dl, MVT::i32),
12430 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12431 MachineMemOperand *NewMMO =
12440 MVT::v256i1, NewMMO);
12456 EVT StoreVT =
Value.getValueType();
12458 if (StoreVT == MVT::v1024i1 || StoreVT == MVT::v2048i1)
12459 return LowerDMFVectorStore(
Op, DAG);
12461 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
12465 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
12466 "Type unsupported without MMA");
12467 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12468 "Type unsupported without paired vector support");
12472 if (StoreVT == MVT::v256i1 && Subtarget.isISAFuture() &&
12480 unsigned NumVecs = 2;
12481 if (StoreVT == MVT::v512i1) {
12482 if (Subtarget.isISAFuture()) {
12483 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12485 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
12488 Value2 =
SDValue(ExtNode, 1);
12493 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12494 unsigned VecNum = Subtarget.isLittleEndian() ? NumVecs - 1 - Idx : Idx;
12496 if (Subtarget.isISAFuture()) {
12497 VecNum = Subtarget.isLittleEndian() ? 1 - (Idx % 2) : (Idx % 2);
12498 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
12499 Idx > 1 ? Value2 :
Value,
12502 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
Value,
12506 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
12520 if (
Op.getValueType() == MVT::v4i32) {
12537 LHS,
RHS, DAG, dl, MVT::v4i32);
12540 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
12545 }
else if (
Op.getValueType() == MVT::v16i8) {
12547 bool isLittleEndian = Subtarget.isLittleEndian();
12551 LHS,
RHS, DAG, dl, MVT::v8i16);
12556 LHS,
RHS, DAG, dl, MVT::v8i16);
12564 for (
unsigned i = 0; i != 8; ++i) {
12565 if (isLittleEndian) {
12567 Ops[i*2+1] = 2*i+16;
12570 Ops[i*2+1] = 2*i+1+16;
12573 if (isLittleEndian)
12583 bool IsStrict =
Op->isStrictFPOpcode();
12584 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
12585 !Subtarget.hasP9Vector())
12595 "Should only be called for ISD::FP_EXTEND");
12599 if (
Op.getValueType() != MVT::v2f64 ||
12600 Op.getOperand(0).getValueType() != MVT::v2f32)
12612 "Node should have 2 operands with second one being a constant!");
12624 int DWord = Idx >> 1;
12627 if (Subtarget.isLittleEndian())
12630 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64,
12644 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12646 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12647 LD->getMemoryVT(),
LD->getMemOperand());
12652 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewOp,
12657 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12659 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12660 LD->getMemoryVT(),
LD->getMemOperand());
12661 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewLd,
12672 if (STI.useCRBits())
12689 PPCISD::ADDE,
DL, DAG.
getVTList(SumType, MVT::i32), Zero, Zero, Flag);
12690 if (STI.useCRBits())
12698 SDNode *
N =
Op.getNode();
12699 EVT VT =
N->getValueType(0);
12700 EVT CarryType =
N->getValueType(1);
12701 unsigned Opc =
N->getOpcode();
12703 Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12705 N->getOperand(0),
N->getOperand(1));
12717 SDNode *
N =
Op.getNode();
12718 unsigned Opc =
N->getOpcode();
12719 EVT VT =
N->getValueType(0);
12720 EVT CarryType =
N->getValueType(1);
12721 SDValue CarryOp =
N->getOperand(2);
12723 Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12729 Op.getOperand(0),
Op.getOperand(1), CarryOp);
12743 EVT VT =
Op.getNode()->getValueType(0);
12769 EVT VT =
Op.getNode()->getValueType(0);
12801 EVT OpVT =
LHS.getValueType();
12802 EVT VT =
Op.getValueType();
12817 unsigned Opcode = PPCISD::SUBC;
12827 Opcode = PPCISD::ADDC;
12834 if (Subtarget.isPPC64() && OpVT != MVT::i64) {
12841 SDVTList VTs = DAG.
getVTList(OpVT, MVT::i32);
12861 EVT OpVT =
A.getValueType();
12862 EVT ResVT =
Op.getValueType();
12867 if (Subtarget.isPPC64() && OpVT != MVT::i64) {
12877 SDVTList VTs = DAG.
getVTList(OpVT, MVT::i32);
12895 switch (
Op.getOpcode()) {
12916 return LowerSSUBO(
Op, DAG);
12918 return LowerSADDO(
Op, DAG);
12930 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
12951 return LowerSET_ROUNDING(
Op, DAG);
12958 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
12959 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
12971 return LowerFP_ROUND(
Op, DAG);
12985 return LowerINTRINSIC_VOID(
Op, DAG);
12987 return LowerBSWAP(
Op, DAG);
12989 return LowerATOMIC_CMP_SWAP(
Op, DAG);
12991 return LowerATOMIC_LOAD_STORE(
Op, DAG);
12993 return LowerIS_FPCLASS(
Op, DAG);
12996 return LowerADDSUBO(
Op, DAG);
12999 return LowerADDSUBO_CARRY(
Op, DAG);
13001 return LowerUCMP(
Op, DAG);
13003 return LowerABDU(
Op, DAG);
13009 if (
Op->getFlags().hasNoFPExcept())
13013 return LowerVP_LOAD(
Op, DAG);
13014 case ISD::VP_STORE:
13015 return LowerVP_STORE(
Op, DAG);
13017 return LowerPartialReduce(
Op, DAG);
13025 switch (
N->getOpcode()) {
13027 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
13044 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
13047 assert(
N->getValueType(0) == MVT::i1 &&
13048 "Unexpected result type for CTR decrement intrinsic");
13050 N->getValueType(0));
13060 switch (
N->getConstantOperandVal(0)) {
13061 case Intrinsic::ppc_pack_longdouble:
13063 N->getOperand(2),
N->getOperand(1)));
13065 case Intrinsic::ppc_maxfe:
13066 case Intrinsic::ppc_minfe:
13067 case Intrinsic::ppc_fnmsub:
13068 case Intrinsic::ppc_convert_f128_to_ppcf128:
13075 if (!Subtarget.isSVR4ABI() || Subtarget.isPPC64())
13078 EVT VT =
N->getValueType(0);
13080 if (VT == MVT::i64) {
13093 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
13097 Results.push_back(LoweredValue);
13098 if (
N->isStrictFPOpcode())
13103 if (!
N->getValueType(0).isVector())
13136 return Builder.CreateIntrinsicWithoutFolding(Id, {});
13142 unsigned SZ = ValueTy->getPrimitiveSizeInBits();
13144 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
13145 "Only 8/16/32/64-bit atomic loads supported");
13151 IntID = Intrinsic::ppc_lbarx;
13152 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13155 IntID = Intrinsic::ppc_lharx;
13156 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13159 IntID = Intrinsic::ppc_lwarx;
13162 IntID = Intrinsic::ppc_ldarx;
13166 Builder.CreateIntrinsic(IntID, Addr,
nullptr,
"larx");
13168 return Builder.CreateTruncOrBitCast(
Call, ValueTy);
13179 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
13180 "Only 8/16/32/64-bit atomic loads supported");
13186 IntID = Intrinsic::ppc_stbcx;
13187 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13190 IntID = Intrinsic::ppc_sthcx;
13191 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13194 IntID = Intrinsic::ppc_stwcx;
13197 IntID = Intrinsic::ppc_stdcx;
13201 if (SZ == 8 || SZ == 16)
13202 Val = Builder.CreateZExt(Val, Builder.getInt32Ty());
13204 Value *
Call = Builder.CreateIntrinsic(IntID, {Addr, Val},
13206 return Builder.CreateXor(
Call, Builder.getInt32(1));
13229 return Builder.CreateIntrinsicWithoutFolding(Intrinsic::ppc_cfence,
13239 unsigned BinOpcode,
13240 unsigned CmpOpcode,
13241 unsigned CmpPred)
const {
13246 unsigned AtomicSize =
MI.getOperand(3).getImm();
13248 auto LoadMnemonic = PPC::LDARX;
13249 auto StoreMnemonic = PPC::STDCX;
13250 switch (AtomicSize) {
13254 LoadMnemonic = PPC::LBARX;
13255 StoreMnemonic = PPC::STBCX;
13256 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13259 LoadMnemonic = PPC::LHARX;
13260 StoreMnemonic = PPC::STHCX;
13261 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13264 LoadMnemonic = PPC::LWARX;
13265 StoreMnemonic = PPC::STWCX;
13268 LoadMnemonic = PPC::LDARX;
13269 StoreMnemonic = PPC::STDCX;
13277 if (CmpOpcode == PPC::CMPW && (AtomicSize == 1 || AtomicSize == 2))
13288 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13290 F->insert(It, loopMBB);
13292 F->insert(It, loop2MBB);
13293 F->insert(It, exitMBB);
13299 Register TmpReg = (!BinOpcode) ? incr :
13300 RegInfo.createVirtualRegister( AtomicSize == 8 ? &PPC::G8RCRegClass
13301 : &PPC::GPRCRegClass);
13326 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
13331 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13333 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
13334 Register ExtReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13335 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
13365 switch(
MI.getOpcode()) {
13369 return TII->isSignExtended(
MI.getOperand(1).getReg(),
13370 &
MI.getMF()->getRegInfo());
13394 case PPC::EXTSB8_32_64:
13395 case PPC::EXTSB8_rec:
13396 case PPC::EXTSB_rec:
13399 case PPC::EXTSH8_32_64:
13400 case PPC::EXTSH8_rec:
13401 case PPC::EXTSH_rec:
13403 case PPC::EXTSWSLI:
13404 case PPC::EXTSWSLI_32_64:
13405 case PPC::EXTSWSLI_32_64_rec:
13406 case PPC::EXTSWSLI_rec:
13407 case PPC::EXTSW_32:
13408 case PPC::EXTSW_32_64:
13409 case PPC::EXTSW_32_64_rec:
13410 case PPC::EXTSW_rec:
13413 case PPC::SRAWI_rec:
13414 case PPC::SRAW_rec:
13424 unsigned OpIdx,
bool IsByte,
13429 bool IsSignExtended =
13432 if (!IsSignExtended) {
13433 Register ValueReg =
RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13435 TII->get(IsByte ? PPC::EXTSB : PPC::EXTSH), ValueReg)
13437 MI.getOperand(
OpIdx).setReg(ValueReg);
13443 unsigned CmpOpcode,
unsigned CmpPred)
const {
13447 assert(!Subtarget.hasPartwordAtomics() &&
13448 "Assumes that part-word atomics are not available");
13456 const bool is8bit =
MI.getOperand(3).getImm() == 1;
13457 if (CmpOpcode == PPC::CMPW)
13465 bool is64bit = Subtarget.isPPC64();
13466 bool isLittleEndian = Subtarget.isLittleEndian();
13467 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13478 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13480 F->insert(It, loopMBB);
13482 F->insert(It, loop2MBB);
13483 F->insert(It, exitMBB);
13489 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13492 Register PtrReg = RegInfo.createVirtualRegister(RC);
13493 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
13495 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
13496 Register Incr2Reg = RegInfo.createVirtualRegister(GPRC);
13497 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
13498 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
13499 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
13500 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
13501 Register Tmp3Reg = RegInfo.createVirtualRegister(GPRC);
13502 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
13503 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
13504 Register SrwDestReg = RegInfo.createVirtualRegister(GPRC);
13507 (!BinOpcode) ? Incr2Reg : RegInfo.createVirtualRegister(GPRC);
13534 if (ptrA != ZeroReg) {
13535 Ptr1Reg = RegInfo.createVirtualRegister(RC);
13536 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13544 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13545 .
addReg(Ptr1Reg, {}, is64bit ? PPC::sub_32 : 0)
13548 .
addImm(is8bit ? 28 : 27);
13549 if (!isLittleEndian)
13550 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13552 .
addImm(is8bit ? 24 : 16);
13554 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13559 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13569 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13573 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13578 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13582 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
13585 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13592 Register SReg = RegInfo.createVirtualRegister(GPRC);
13593 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13597 unsigned ValueReg = SReg;
13598 unsigned CmpReg = Incr2Reg;
13599 if (CmpOpcode == PPC::CMPW) {
13600 ValueReg = RegInfo.createVirtualRegister(GPRC);
13601 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
13604 Register ValueSReg = RegInfo.createVirtualRegister(GPRC);
13605 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
13607 ValueReg = ValueSReg;
13639 .
addImm(is8bit ? 24 : 16)
13660 Register DstReg =
MI.getOperand(0).getReg();
13662 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
13667 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13668 "Invalid Pointer Size!");
13717 Register BufReg =
MI.getOperand(1).getReg();
13719 if (Subtarget.is64BitELFABI()) {
13732 BaseReg = Subtarget.isPPC64() ? PPC::X1 : PPC::R1;
13734 BaseReg = Subtarget.isPPC64() ? PPC::BP8 : PPC::BP;
13737 TII->get(Subtarget.isPPC64() ? PPC::STD : PPC::STW))
13760 TII->get(Subtarget.isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
13763 if (Subtarget.isPPC64()) {
13781 TII->get(PPC::PHI), DstReg)
13785 MI.eraseFromParent();
13799 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13800 "Invalid Pointer Size!");
13803 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13806 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
13807 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
13821 Register BufReg =
MI.getOperand(0).getReg();
13826 if (PVT == MVT::i64) {
13838 if (PVT == MVT::i64) {
13850 if (PVT == MVT::i64) {
13862 if (PVT == MVT::i64) {
13874 if (PVT == MVT::i64 && Subtarget.isSVR4ABI()) {
13884 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
13887 MI.eraseFromParent();
13903 "Unexpected stack alignment");
13907 unsigned StackProbeSize =
13910 StackProbeSize &= ~(StackAlign - 1);
13911 return StackProbeSize ? StackProbeSize : StackAlign;
13923 const bool isPPC64 = Subtarget.isPPC64();
13955 MF->
insert(MBBIter, TestMBB);
13956 MF->
insert(MBBIter, BlockMBB);
13957 MF->
insert(MBBIter, TailMBB);
13962 Register DstReg =
MI.getOperand(0).getReg();
13963 Register NegSizeReg =
MI.getOperand(1).getReg();
13975 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
13981 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
13982 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
13984 .
addDef(ActualNegSizeReg)
13986 .
add(
MI.getOperand(2))
13987 .
add(
MI.getOperand(3));
13993 .
addReg(ActualNegSizeReg);
13996 int64_t NegProbeSize = -(int64_t)ProbeSize;
14002 .
addImm(NegProbeSize >> 16);
14006 .
addImm(NegProbeSize & 0xFFFF);
14015 .
addReg(ActualNegSizeReg)
14024 .
addReg(ActualNegSizeReg);
14034 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
14061 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
14062 MaxCallFrameSizeReg)
14063 .
add(
MI.getOperand(2))
14064 .
add(
MI.getOperand(3));
14065 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
14067 .
addReg(MaxCallFrameSizeReg);
14073 MBB->addSuccessor(TestMBB);
14076 MI.eraseFromParent();
14078 ++NumDynamicAllocaProbed;
14086static bool IsSelect(
unsigned Opcode,
bool CheckOnlyCC =
false) {
14089 case PPC::SELECT_CC_I4:
14090 case PPC::SELECT_CC_I8:
14091 case PPC::SELECT_CC_F4:
14092 case PPC::SELECT_CC_F8:
14093 case PPC::SELECT_CC_F16:
14094 case PPC::SELECT_CC_VRRC:
14095 case PPC::SELECT_CC_VSFRC:
14096 case PPC::SELECT_CC_VSSRC:
14097 case PPC::SELECT_CC_VSRC:
14098 case PPC::SELECT_CC_SPE4:
14099 case PPC::SELECT_CC_SPE:
14102 case PPC::SELECT_I4:
14103 case PPC::SELECT_I8:
14104 case PPC::SELECT_F4:
14105 case PPC::SELECT_F8:
14106 case PPC::SELECT_F16:
14107 case PPC::SELECT_SPE:
14108 case PPC::SELECT_SPE4:
14109 case PPC::SELECT_VRRC:
14110 case PPC::SELECT_VSFRC:
14111 case PPC::SELECT_VSSRC:
14112 case PPC::SELECT_VSRC:
14113 return !CheckOnlyCC;
14129 assert(
IsSelect(
MI.getOpcode()) &&
"Instruction must be a SELECT variant");
14132 if (Subtarget.hasISEL() &&
14133 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
14134 MI.getOpcode() == PPC::SELECT_CC_I8 ||
14135 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
14137 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
14138 MI.getOpcode() == PPC::SELECT_CC_I8)
14139 Cond.push_back(
MI.getOperand(4));
14142 Cond.push_back(
MI.getOperand(1));
14145 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
14146 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
14147 MI.eraseFromParent();
14160 F->insert(It, copy0MBB);
14161 F->insert(It, sinkMBB);
14169 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
14185 .
addImm(
MI.getOperand(4).getImm())
14186 .
addReg(
MI.getOperand(1).getReg())
14190 .
addReg(
MI.getOperand(1).getReg())
14200 .
addReg(
MI.getOperand(3).getReg())
14202 .
addReg(
MI.getOperand(2).getReg())
14204 MI.eraseFromParent();
14219 loop1MBB =
F->CreateMachineBasicBlock(LLVM_BB);
14220 loop2MBB =
F->CreateMachineBasicBlock(LLVM_BB);
14221 exitMBB =
F->CreateMachineBasicBlock(LLVM_BB);
14222 F->insert(It, loop1MBB);
14223 F->insert(It, loop2MBB);
14224 F->insert(It, exitMBB);
14259 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
14261 unsigned LoadMnemonic = PPC::LDARX;
14262 unsigned StoreMnemonic = PPC::STDCX;
14263 switch (
MI.getOpcode()) {
14266 case PPC::ATOMIC_CMP_SWAP_I8:
14267 LoadMnemonic = PPC::LBARX;
14268 StoreMnemonic = PPC::STBCX;
14269 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14271 case PPC::ATOMIC_CMP_SWAP_I16:
14272 LoadMnemonic = PPC::LHARX;
14273 StoreMnemonic = PPC::STHCX;
14274 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14276 case PPC::ATOMIC_CMP_SWAP_I32:
14277 LoadMnemonic = PPC::LWARX;
14278 StoreMnemonic = PPC::STWCX;
14280 case PPC::ATOMIC_CMP_SWAP_I64:
14281 LoadMnemonic = PPC::LDARX;
14282 StoreMnemonic = PPC::STDCX;
14290 Register oldval =
MI.getOperand(3).getReg();
14291 Register newval =
MI.getOperand(4).getReg();
14305 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
14373 bool is64bit = Subtarget.isPPC64();
14375 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
14380 Register oldval =
MI.getOperand(3).getReg();
14381 Register newval =
MI.getOperand(4).getReg();
14389 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
14394 return RegInfo.createVirtualRegister(RC);
14398 Register Shift1Reg = createVReg(GPRC);
14399 Register ShiftReg = isLittleEndian ? Shift1Reg : createVReg(GPRC);
14400 Register NewVal2Reg = createVReg(GPRC);
14401 Register NewVal3Reg = createVReg(GPRC);
14402 Register OldVal2Reg = createVReg(GPRC);
14403 Register OldVal3Reg = createVReg(GPRC);
14404 Register MaskReg = createVReg(GPRC);
14405 Register Mask2Reg = createVReg(GPRC);
14406 Register Mask3Reg = createVReg(GPRC);
14407 Register Tmp2Reg = createVReg(GPRC);
14408 Register Tmp4Reg = createVReg(GPRC);
14409 Register TmpDestReg = createVReg(GPRC);
14410 Register TmpReg = createVReg(GPRC);
14411 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
14412 Register CrReg = createVReg(&PPC::CRRCRegClass);
14416 if (ptrA != ZeroReg) {
14417 Ptr1Reg = createVReg(RC);
14418 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
14425 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
14426 .
addReg(Ptr1Reg, {}, is64bit ? PPC::sub_32 : 0)
14429 .
addImm(is8bit ? 28 : 27);
14430 if (!isLittleEndian)
14431 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
14433 .
addImm(is8bit ? 24 : 16);
14435 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
14440 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
14447 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
14450 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
14457 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
14461 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
14464 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
14467 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
14477 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
14498 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
14543 switch (
MI.getOpcode()) {
14544 case TargetOpcode::STACKMAP:
14546 case TargetOpcode::PATCHPOINT:
14552 if (Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls())
14556 case PPC::EH_SjLj_SetJmp32:
14557 case PPC::EH_SjLj_SetJmp64:
14560 case PPC::EH_SjLj_LongJmp32:
14561 case PPC::EH_SjLj_LongJmp64:
14564 case PPC::ReadTB: {
14580 F->insert(It, readMBB);
14581 F->insert(It, sinkMBB);
14592 Register ReadAgainReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
14600 Register CmpReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14602 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
14614 case PPC::ATOMIC_LOAD_ADD_NOWP:
14617 case PPC::ATOMIC_LOAD_ADD:
14620 case PPC::ATOMIC_LOAD_ADD_I64:
14623 case PPC::ATOMIC_LOAD_AND_NOWP:
14626 case PPC::ATOMIC_LOAD_AND:
14629 case PPC::ATOMIC_LOAD_AND_I64:
14632 case PPC::ATOMIC_LOAD_OR_NOWP:
14635 case PPC::ATOMIC_LOAD_OR:
14638 case PPC::ATOMIC_LOAD_OR_I64:
14641 case PPC::ATOMIC_LOAD_XOR_NOWP:
14644 case PPC::ATOMIC_LOAD_XOR:
14647 case PPC::ATOMIC_LOAD_XOR_I64:
14650 case PPC::ATOMIC_LOAD_NAND_NOWP:
14653 case PPC::ATOMIC_LOAD_NAND:
14656 case PPC::ATOMIC_LOAD_NAND_I64:
14659 case PPC::ATOMIC_LOAD_SUB_NOWP:
14662 case PPC::ATOMIC_LOAD_SUB:
14665 case PPC::ATOMIC_LOAD_SUB_I64:
14668 case PPC::ATOMIC_LOAD_MIN_NOWP:
14671 case PPC::ATOMIC_LOAD_MIN:
14674 case PPC::ATOMIC_LOAD_MIN_I64:
14677 case PPC::ATOMIC_LOAD_MAX_NOWP:
14680 case PPC::ATOMIC_LOAD_MAX:
14683 case PPC::ATOMIC_LOAD_MAX_I64:
14686 case PPC::ATOMIC_LOAD_UMIN_NOWP:
14689 case PPC::ATOMIC_LOAD_UMIN:
14692 case PPC::ATOMIC_LOAD_UMIN_I64:
14695 case PPC::ATOMIC_LOAD_UMAX_NOWP:
14698 case PPC::ATOMIC_LOAD_UMAX:
14701 case PPC::ATOMIC_LOAD_UMAX_I64:
14704 case PPC::ATOMIC_SWAP_NOWP:
14707 case PPC::ATOMIC_SWAP:
14708 case PPC::ATOMIC_SWAP_I64:
14711 case PPC::ATOMIC_CMP_SWAP_I32:
14712 case PPC::ATOMIC_CMP_SWAP_I64:
14713 case PPC::ATOMIC_CMP_SWAP_I8:
14714 case PPC::ATOMIC_CMP_SWAP_I16: {
14716 bool useHardware =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
14717 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
14718 (Subtarget.hasPartwordAtomics() &&
14719 (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
14720 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16));
14728 case PPC::FADDrtz: {
14738 Register MFFSReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14753 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
14763 case PPC::ANDI_rec_1_EQ_BIT:
14764 case PPC::ANDI_rec_1_GT_BIT:
14765 case PPC::ANDI_rec_1_EQ_BIT8:
14766 case PPC::ANDI_rec_1_GT_BIT8: {
14767 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14768 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
14771 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14772 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
14775 Register Dest = RegInfo.createVirtualRegister(
14776 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
14780 .
addReg(
MI.getOperand(1).getReg())
14783 MI.getOperand(0).getReg())
14784 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
14787 case PPC::TCHECK_RET: {
14790 Register CRReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14793 MI.getOperand(0).getReg())
14797 case PPC::TBEGIN_RET: {
14799 unsigned Imm =
MI.getOperand(1).getImm();
14802 MI.getOperand(0).getReg())
14806 case PPC::SETRNDi: {
14808 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14812 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14814 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14825 unsigned Mode =
MI.getOperand(1).getImm();
14826 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
14830 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
14835 case PPC::SETRND: {
14843 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
14844 if (Subtarget.hasDirectMove()) {
14845 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
14849 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
14852 if (RC == &PPC::F8RCRegClass) {
14854 assert((RegInfo.getRegClass(DestReg) == &PPC::G8RCRegClass) &&
14855 "Unsupported RegClass.");
14857 StoreOp = PPC::STFD;
14861 assert((RegInfo.getRegClass(SrcReg) == &PPC::G8RCRegClass) &&
14862 (RegInfo.getRegClass(DestReg) == &PPC::F8RCRegClass) &&
14863 "Unsupported RegClass.");
14896 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14899 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14911 Register OldFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14913 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
14915 Register ImDefReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14916 Register ExtSrcReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14921 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
14922 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
14927 Register NewFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14928 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
14934 Register NewFPSCRReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14935 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
14946 case PPC::SETFLM: {
14950 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14952 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14954 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14957 Register NewFPSCRReg =
MI.getOperand(1).getReg();
14965 case PPC::PROBED_ALLOCA_32:
14966 case PPC::PROBED_ALLOCA_64:
14969 case PPC::SPLIT_QUADWORD: {
14976 .
addUse(Src, {}, PPC::sub_gp8_x1);
14979 .
addUse(Src, {}, PPC::sub_gp8_x0);
14982 case PPC::LQX_PSEUDO:
14983 case PPC::STQX_PSEUDO: {
14989 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
14995 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
14996 :
TII->get(PPC::STQ))
15006 MI.eraseFromParent();
15019 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
15022 return RefinementSteps;
15029 EVT VT =
Op.getValueType();
15032 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
15056PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
15059 EVT VT =
Op.getValueType();
15060 if (VT != MVT::f64 &&
15061 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
15064 return DAG.
getNode(PPCISD::FSQRT, SDLoc(
Op), VT,
Op);
15068 int Enabled,
int &RefinementSteps,
15069 bool &UseOneConstNR,
15070 bool Reciprocal)
const {
15072 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
15073 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
15074 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
15075 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
15081 UseOneConstNR = !Subtarget.needsTwoConstNR();
15082 return DAG.
getNode(PPCISD::FRSQRTE, SDLoc(Operand), VT, Operand);
15089 int &RefinementSteps)
const {
15091 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
15092 (VT == MVT::f64 && Subtarget.hasFRE()) ||
15093 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
15094 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
15097 return DAG.
getNode(PPCISD::FRE, SDLoc(Operand), VT, Operand);
15113 switch (Subtarget.getCPUDirective()) {
15140 unsigned Bytes,
int Dist,
15154 if (FS != BFS || FS != (
int)Bytes)
return false;
15159 int64_t Offset1 = 0, Offset2 = 0;
15162 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
15172 if (isGA1 && isGA2 && GV1 == GV2)
15173 return Offset1 == (Offset2 + Dist*Bytes);
15180 unsigned Bytes,
int Dist,
15183 EVT VT = LS->getMemoryVT();
15190 switch (
N->getConstantOperandVal(1)) {
15191 default:
return false;
15192 case Intrinsic::ppc_altivec_lvx:
15193 case Intrinsic::ppc_altivec_lvxl:
15194 case Intrinsic::ppc_vsx_lxvw4x:
15195 case Intrinsic::ppc_vsx_lxvw4x_be:
15198 case Intrinsic::ppc_vsx_lxvd2x:
15199 case Intrinsic::ppc_vsx_lxvd2x_be:
15202 case Intrinsic::ppc_altivec_lvebx:
15205 case Intrinsic::ppc_altivec_lvehx:
15208 case Intrinsic::ppc_altivec_lvewx:
15218 switch (
N->getConstantOperandVal(1)) {
15219 default:
return false;
15220 case Intrinsic::ppc_altivec_stvx:
15221 case Intrinsic::ppc_altivec_stvxl:
15222 case Intrinsic::ppc_vsx_stxvw4x:
15225 case Intrinsic::ppc_vsx_stxvd2x:
15228 case Intrinsic::ppc_vsx_stxvw4x_be:
15231 case Intrinsic::ppc_vsx_stxvd2x_be:
15234 case Intrinsic::ppc_altivec_stvebx:
15237 case Intrinsic::ppc_altivec_stvehx:
15240 case Intrinsic::ppc_altivec_stvewx:
15257 SDValue Chain = LD->getChain();
15258 EVT VT = LD->getMemoryVT();
15267 while (!Queue.empty()) {
15268 SDNode *ChainNext = Queue.pop_back_val();
15269 if (!Visited.
insert(ChainNext).second)
15276 if (!Visited.
count(ChainLD->getChain().getNode()))
15277 Queue.push_back(ChainLD->getChain().getNode());
15279 for (
const SDUse &O : ChainNext->
ops())
15280 if (!Visited.
count(O.getNode()))
15281 Queue.push_back(O.getNode());
15283 LoadRoots.
insert(ChainNext);
15294 for (
SDNode *
I : LoadRoots) {
15295 Queue.push_back(
I);
15297 while (!Queue.empty()) {
15298 SDNode *LoadRoot = Queue.pop_back_val();
15299 if (!Visited.
insert(LoadRoot).second)
15311 Queue.push_back(U);
15344 auto Final = Shifted;
15355 DAGCombinerInfo &DCI)
const {
15358 SelectionDAG &DAG = DCI.DAG;
15363 if (!DCI.isAfterLegalizeDAG())
15368 for (
const SDNode *U :
N->users())
15373 auto OpSize =
N->getOperand(0).getValueSizeInBits();
15377 if (OpSize <
Size) {
15395 DAGCombinerInfo &DCI)
const {
15396 SelectionDAG &DAG = DCI.DAG;
15399 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
15410 N->getValueType(0) != MVT::i1)
15413 if (
N->getOperand(0).getValueType() != MVT::i32 &&
15414 N->getOperand(0).getValueType() != MVT::i64)
15424 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
15435 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
15458 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15459 N->getOperand(0).getOpcode() !=
ISD::OR &&
15460 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15470 N->getOperand(1).getOpcode() !=
ISD::AND &&
15471 N->getOperand(1).getOpcode() !=
ISD::OR &&
15472 N->getOperand(1).getOpcode() !=
ISD::XOR &&
15483 SmallPtrSet<SDNode *, 16> Visited;
15485 for (
unsigned i = 0; i < 2; ++i) {
15489 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
15501 while (!BinOps.
empty()) {
15509 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15543 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15547 for (
const SDNode *User : Inputs[i].
getNode()->
users()) {
15548 if (User !=
N && !Visited.
count(User))
15557 if (
User->getOperand(0) == Inputs[i])
15560 if (
User->getOperand(0) == Inputs[i] ||
15561 User->getOperand(1) == Inputs[i])
15567 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15568 for (
const SDNode *User : PromOps[i].
getNode()->
users()) {
15569 if (User !=
N && !Visited.
count(User))
15578 if (
User->getOperand(0) == PromOps[i])
15581 if (
User->getOperand(0) == PromOps[i] ||
15582 User->getOperand(1) == PromOps[i])
15589 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15598 std::list<HandleSDNode> PromOpHandles;
15599 for (
auto &PromOp : PromOps)
15600 PromOpHandles.emplace_back(PromOp);
15607 while (!PromOpHandles.empty()) {
15608 SDValue PromOp = PromOpHandles.back().getValue();
15609 PromOpHandles.pop_back();
15618 PromOpHandles.emplace_front(PromOp);
15632 default:
C = 0;
break;
15645 PromOpHandles.emplace_front(PromOp);
15652 for (
unsigned i = 0; i < 2; ++i)
15662 return N->getOperand(0);
15670 DAGCombinerInfo &DCI)
const {
15671 SelectionDAG &DAG = DCI.DAG;
15688 if (
N->getValueType(0) != MVT::i32 &&
15689 N->getValueType(0) != MVT::i64)
15692 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
15693 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.isPPC64())))
15696 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15697 N->getOperand(0).getOpcode() !=
ISD::OR &&
15698 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15705 SmallPtrSet<SDNode *, 16> Visited;
15709 while (!BinOps.
empty()) {
15717 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15743 DenseMap<SDNode *, EVT> SelectTruncOp[2];
15748 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15753 if (User !=
N && !Visited.
count(User))
15759 if (
User->getOperand(0) == Inputs[i])
15760 SelectTruncOp[0].
insert(std::make_pair(User,
15761 User->getOperand(0).getValueType()));
15763 if (
User->getOperand(0) == Inputs[i])
15764 SelectTruncOp[0].
insert(std::make_pair(User,
15765 User->getOperand(0).getValueType()));
15766 if (
User->getOperand(1) == Inputs[i])
15767 SelectTruncOp[1].
insert(std::make_pair(User,
15768 User->getOperand(1).getValueType()));
15773 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15775 if (User !=
N && !Visited.
count(User))
15781 if (
User->getOperand(0) == PromOps[i])
15782 SelectTruncOp[0].
insert(std::make_pair(User,
15783 User->getOperand(0).getValueType()));
15785 if (
User->getOperand(0) == PromOps[i])
15786 SelectTruncOp[0].
insert(std::make_pair(User,
15787 User->getOperand(0).getValueType()));
15788 if (
User->getOperand(1) == PromOps[i])
15789 SelectTruncOp[1].
insert(std::make_pair(User,
15790 User->getOperand(1).getValueType()));
15795 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
15796 bool ReallyNeedsExt =
false;
15800 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15805 Inputs[i].getOperand(0).getValueSizeInBits();
15806 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
15811 OpBits-PromBits))) ||
15814 (OpBits-(PromBits-1)))) {
15815 ReallyNeedsExt =
true;
15823 std::list<HandleSDNode> PromOpHandles;
15824 for (
auto &PromOp : PromOps)
15825 PromOpHandles.emplace_back(PromOp);
15829 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15836 SDValue InSrc = Inputs[i].getOperand(0);
15854 while (!PromOpHandles.empty()) {
15856 PromOpHandles.pop_back();
15860 default:
C = 0;
break;
15873 PromOpHandles.emplace_front(PromOp);
15883 (SelectTruncOp[1].count(PromOp.
getNode()) &&
15885 PromOpHandles.emplace_front(PromOp);
15893 for (
unsigned i = 0; i < 2; ++i) {
15911 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
15912 if (SI0 != SelectTruncOp[0].
end())
15914 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
15915 if (SI1 != SelectTruncOp[1].
end())
15924 if (!ReallyNeedsExt)
15925 return N->getOperand(0);
15932 N->getValueSizeInBits(0), PromBits),
15933 dl,
N->getValueType(0)));
15936 "Invalid extension type");
15939 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
15949 auto isValidForConvert = [IsPPC64](
SDValue &Operand) {
15958 const APInt &Val =
C->getAPIntValue();
15964 if (IsPPC64 && Val.
ult(1ULL << 16))
15978 if (LoadNode->isVolatile())
15999 return (isValidForConvert(
LHS) && isValidForConvert(
RHS));
16009 "CC mus be ISD::SETNE or ISD::SETEQ");
16011 auto getV16i8Load = [&](
const SDValue &Operand) {
16029 LoadNode->getBasePtr(), NewMMO);
16070 SDValue LHSVec = getV16i8Load(
N->getOperand(0));
16071 SDValue RHSVec = getV16i8Load(
N->getOperand(1));
16074 DAG.
getConstant(Intrinsic::ppc_altivec_vcmpequb_p,
DL, MVT::i32);
16077 IntrID, CRSel, LHSVec, RHSVec);
16080 return DAG.
getSetCC(
DL,
N->getValueType(0), PredResult,
16098 auto IsAndWithOne = [](
SDValue &V) {
16109 auto IsCompareWithZero = [](
SDValue &V) {
16116 return (IsAndWithOne(
LHS) && IsCompareWithZero(
RHS)) ||
16117 (IsAndWithOne(
RHS) && IsCompareWithZero(
LHS));
16134 auto MakeXor1 = [&](
SDValue V) {
16135 EVT VT = V.getValueType();
16142 return MakeXor1(
LHS);
16145 return MakeXor1(
RHS);
16162 DAGCombinerInfo &DCI)
const {
16163 if (Subtarget.isISA3_1())
16166 EVT VT =
N->getValueType(0);
16167 if (VT != MVT::i32 && (VT != MVT::i64 || !Subtarget.isPPC64()))
16183 SelectionDAG &DAG = DCI.DAG;
16185 EVT XVT =
X.getValueType();
16189 MVT OpVT = Subtarget.isPPC64() ? MVT::i64 : MVT::i32;
16202 Addc, Addc, Carry);
16205 if (OpVT == MVT::i64 && VT == MVT::i32)
16212 DAGCombinerInfo &DCI)
const {
16214 "Should be called with a SETCC node");
16236 SelectionDAG &DAG = DCI.DAG;
16237 EVT VT =
N->getValueType(0);
16238 EVT OpVT =
LHS.getValueType();
16256 if (Subtarget.hasAltivec() &&
16261 return DAGCombineTruncBoolExt(
N, DCI);
16268 Op.getValueType() == MVT::f64;
16280combineElementTruncationToVectorTruncation(
SDNode *
N,
16281 DAGCombinerInfo &DCI)
const {
16283 "Should be called with a BUILD_VECTOR node");
16285 SelectionDAG &DAG = DCI.DAG;
16288 SDValue FirstInput =
N->getOperand(0);
16290 "The input operand must be an fp-to-int conversion.");
16295 if (FirstConversion == PPCISD::FCTIDZ ||
16296 FirstConversion == PPCISD::FCTIDUZ ||
16297 FirstConversion == PPCISD::FCTIWZ ||
16298 FirstConversion == PPCISD::FCTIWUZ) {
16299 bool IsSplat =
true;
16300 bool Is32Bit = FirstConversion == PPCISD::FCTIWZ ||
16301 FirstConversion == PPCISD::FCTIWUZ;
16304 EVT TargetVT =
N->getValueType(0);
16305 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
16306 SDValue NextOp =
N->getOperand(i);
16307 if (NextOp.
getOpcode() != PPCISD::MFVSR)
16310 if (NextConversion != FirstConversion)
16318 if (
N->getOperand(i) != FirstInput)
16329 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
16330 SDValue In =
N->getOperand(i).getOperand(0);
16340 Ops.push_back(Trunc);
16343 Ops.push_back(
In.isUndef() ? DAG.
getUNDEF(SrcVT) :
In.getOperand(0));
16347 if (FirstConversion == PPCISD::FCTIDZ ||
16348 FirstConversion == PPCISD::FCTIWZ)
16353 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
16355 return DAG.
getNode(Opcode, dl, TargetVT, BV);
16373 static const APInt BasePattern =
APInt(128, 0x8000000000000000ULL) << 64;
16377 if (FullVal == BasePattern)
16378 return std::make_tuple(Uim,
uint8_t{0});
16381 if (FullVal ==
APInt(128, 1))
16382 return std::make_tuple(Uim,
uint8_t{127});
16384 return std::nullopt;
16404 "Expected a BuildVectorSDNode in combineBVLoadsSpecialValue");
16408 EVT VT =
Op.getValueType();
16409 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
16423 for (
const SDValue &Operand :
Op.getNode()->op_values()) {
16433 for (
unsigned Index = 0;
Index < NumElems; ++
Index) {
16437 uint64_t ElemValue =
C->getZExtValue();
16441 ElemValue &= ((1ULL << ElemBits) - 1);
16445 (IsLittleEndian) ? (Index * ElemBits) : (128 - (
Index + 1) * ElemBits);
16448 APInt ElemAPInt(128, ElemValue);
16449 ElemAPInt <<= BitPos;
16452 FullVal |= ElemAPInt;
16459 const auto &[Uim, ShiftAmount] = *UIMOpt;
16463 if (ShiftAmount == 0) {
16468 <<
"combineBVLoadsSpecialValue: Instruction Emitted ";
16469 LxvkqInstr.
dump());
16473 assert(ShiftAmount == 127 &&
"Unexpected lxvkq shift amount value");
16485 DAG.
getMachineNode(PPC::VSRQ, Dl, VT, ShiftAmountVec, ShiftAmountVec),
16488 <<
"\n combineBVLoadsSpecialValue: Instruction Emitted ";
16504 "Should be called with a BUILD_VECTOR node");
16509 if (!
N->getValueType(0).getVectorElementType().isByteSized())
16512 bool InputsAreConsecutiveLoads =
true;
16513 bool InputsAreReverseConsecutive =
true;
16514 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
16515 SDValue FirstInput =
N->getOperand(0);
16516 bool IsRoundOfExtLoad =
false;
16526 N->getNumOperands() == 1)
16529 if (!IsRoundOfExtLoad)
16534 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
16536 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
16539 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
16545 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
16556 InputsAreConsecutiveLoads =
false;
16558 InputsAreReverseConsecutive =
false;
16561 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
16566 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
16567 "The loads cannot be both consecutive and reverse consecutive.");
16571 if (InputsAreConsecutiveLoads) {
16572 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
16576 ReturnSDVal = WideLoad;
16577 }
else if (InputsAreReverseConsecutive) {
16579 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
16584 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
16592 for (
auto *LD : InputLoads)
16594 return ReturnSDVal;
16605 unsigned NumElems =
Input.getValueType().getVectorNumElements();
16611 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16613 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
16615 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
16616 CorrectElems = CorrectElems >> 8;
16617 Elems = Elems >> 8;
16624 EVT VT =
N->getValueType(0);
16628 Input.getValueType().getVectorElementType(),
16662 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
16688 Elems = Elems << 8;
16697 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16698 if (!isSExtOfVecExtract(
N->getOperand(i))) {
16705 int TgtElemArrayIdx;
16706 int InputSize =
Input.getValueType().getScalarSizeInBits();
16707 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
16708 if (InputSize + OutputSize == 40)
16709 TgtElemArrayIdx = 0;
16710 else if (InputSize + OutputSize == 72)
16711 TgtElemArrayIdx = 1;
16712 else if (InputSize + OutputSize == 48)
16713 TgtElemArrayIdx = 2;
16714 else if (InputSize + OutputSize == 80)
16715 TgtElemArrayIdx = 3;
16716 else if (InputSize + OutputSize == 96)
16717 TgtElemArrayIdx = 4;
16721 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
16723 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
16724 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
16725 if (Elems != CorrectElems) {
16741 if (
N->getValueType(0) != MVT::v1i128)
16744 SDValue Operand =
N->getOperand(0);
16751 EVT MemoryType = LD->getMemoryVT();
16755 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
16756 MemoryType == MVT::i32 || MemoryType == MVT::i64;
16759 if (!ValidLDType ||
16765 LD->getChain(), LD->getBasePtr(),
16769 DAG.
getVTList(MVT::v1i128, MVT::Other),
16770 LoadOps, MemoryType, LD->getMemOperand());
16774 DAGCombinerInfo &DCI)
const {
16776 "Should be called with a BUILD_VECTOR node");
16778 SelectionDAG &DAG = DCI.DAG;
16781 if (!Subtarget.hasVSX())
16788 if (FirstInput.
getOpcode() == PPCISD::MFVSR) {
16789 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
16804 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
16813 if (Subtarget.isISA3_1()) {
16819 if (
N->getValueType(0) != MVT::v2f64)
16830 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
16841 if (!Ext1Op || !Ext2Op)
16850 if (FirstElem == 0 && SecondElem == 1)
16851 SubvecIdx = Subtarget.isLittleEndian() ? 1 : 0;
16852 else if (FirstElem == 2 && SecondElem == 3)
16853 SubvecIdx = Subtarget.isLittleEndian() ? 0 : 1;
16859 PPCISD::SINT_VEC_TO_FP : PPCISD::UINT_VEC_TO_FP;
16860 return DAG.
getNode(NodeType, dl, MVT::v2f64,
16865 DAGCombinerInfo &DCI)
const {
16868 "Need an int -> FP conversion node here");
16873 SelectionDAG &DAG = DCI.DAG;
16879 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
16881 if (!
Op.getOperand(0).getValueType().isSimple())
16883 if (
Op.getOperand(0).getValueType().getSimpleVT() <= MVT(MVT::i1) ||
16884 Op.getOperand(0).getValueType().getSimpleVT() > MVT(MVT::i64))
16887 SDValue FirstOperand(
Op.getOperand(0));
16888 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
16889 (FirstOperand.getValueType() == MVT::i8 ||
16890 FirstOperand.getValueType() == MVT::i16);
16891 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
16893 bool DstDouble =
Op.getValueType() == MVT::f64;
16894 unsigned ConvOp =
Signed ?
16895 (DstDouble ? PPCISD::FCFID : PPCISD::FCFIDS) :
16896 (DstDouble ? PPCISD::FCFIDU : PPCISD::FCFIDUS);
16901 SDValue Ops[] = { LDN->getChain(), LDN->getBasePtr(), WidthConst };
16904 Ops, MVT::i8, LDN->getMemOperand());
16909 SDValue ExtOps[] = { Ld, WidthConst };
16911 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
16913 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
16921 if (
Op.getOperand(0).getValueType() == MVT::i32)
16925 "UINT_TO_FP is supported only with FPCVT");
16929 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16934 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16941 Subtarget.hasFPCVT()) ||
16943 SDValue Src =
Op.getOperand(0).getOperand(0);
16944 if (Src.getValueType() == MVT::f32) {
16946 DCI.AddToWorklist(Src.getNode());
16947 }
else if (Src.getValueType() != MVT::f64) {
16959 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
16962 DCI.AddToWorklist(
FP.getNode());
16986 switch (
N->getOpcode()) {
16991 Chain = LD->getChain();
16992 Base = LD->getBasePtr();
16993 MMO = LD->getMemOperand();
17012 MVT VecTy =
N->getValueType(0).getSimpleVT();
17020 Chain = Load.getValue(1);
17022 PPCISD::XXSWAPD, dl, DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Load);
17026 if (VecTy != MVT::v2f64) {
17053 switch (
N->getOpcode()) {
17058 Chain = ST->getChain();
17059 Base = ST->getBasePtr();
17060 MMO = ST->getMemOperand();
17080 SDValue Src =
N->getOperand(SrcOpnd);
17081 MVT VecTy = Src.getValueType().getSimpleVT();
17084 if (VecTy != MVT::v2f64) {
17090 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
17096 StoreOps, VecTy, MMO);
17103 DAGCombinerInfo &DCI)
const {
17106 unsigned Opcode =
N->getOperand(1).getOpcode();
17108 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
17112 &&
"Not a FP_TO_INT Instruction!");
17115 EVT Op1VT =
N->getOperand(1).getValueType();
17118 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
17122 bool ValidTypeForStoreFltAsInt =
17123 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.isPPC64()) ||
17124 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
17127 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
17130 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
17138 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
17153 bool PrevElemFromFirstVec = Mask[0] < NumElts;
17154 for (
int i = 1, e = Mask.size(); i < e; i++) {
17155 if (PrevElemFromFirstVec && Mask[i] < NumElts)
17157 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
17159 PrevElemFromFirstVec = !PrevElemFromFirstVec;
17170 for (
int i = 0, e =
Op.getNumOperands(); i < e; i++) {
17171 FirstOp =
Op.getOperand(i);
17177 for (
int i = 1, e =
Op.getNumOperands(); i < e; i++)
17178 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
17188 Op =
Op.getOperand(0);
17204 int RHSFirstElt,
int RHSLastElt,
int HalfVec,
unsigned LHSNumValidElts,
17205 unsigned RHSNumValidElts,
const PPCSubtarget &Subtarget) {
17207 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - LHSNumValidElts;
17209 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - RHSNumValidElts;
17210 for (
int I = 0,
E = ShuffV.
size();
I <
E; ++
I) {
17211 int Idx = ShuffV[
I];
17212 if (Idx >= LHSFirstElt && Idx <= LHSLastElt)
17213 ShuffV[
I] += LHSEltFixup;
17214 else if (Idx >= RHSFirstElt && Idx <= RHSLastElt)
17215 ShuffV[
I] += RHSEltFixup;
17226 SDLoc dl(OrigSToV);
17229 "Expecting a SCALAR_TO_VECTOR here");
17242 "Cannot produce a permuted scalar_to_vector for one element vector");
17244 unsigned ResultInElt = NumElts / 2;
17250 return DAG.
getNode(PPCISD::SCALAR_TO_VECTOR_PERMUTED, dl, VT,
17255 int HalfVec,
int LHSLastElementDefined,
17256 int RHSLastElementDefined) {
17257 for (
int Index : ShuffV) {
17261 if ((LHSLastElementDefined >= 0) && (Index < HalfVec) &&
17262 (Index > LHSLastElementDefined))
17265 if ((RHSLastElementDefined >= 0) &&
17266 (Index > HalfVec + RHSLastElementDefined))
17273 int ScalarSize,
uint64_t ShuffleEltWidth,
unsigned &NumValidElts,
17274 int FirstElt,
int &LastElt,
SDValue VecShuffOperand,
SDValue SToVNode,
17290 LastElt = (
uint64_t)ScalarSize > ShuffleEltWidth
17291 ? ScalarSize / ShuffleEltWidth - 1 + FirstElt
17294 if (SToVPermuted.
getValueType() != VecShuffOperandType)
17295 SToVPermuted = DAG.
getBitcast(VecShuffOperandType, SToVPermuted);
17296 return SToVPermuted;
17316 int NumElts =
LHS.getValueType().getVectorNumElements();
17319 bool IsLittleEndian = Subtarget.isLittleEndian();
17326 if (!Subtarget.hasDirectMove())
17346 SmallVector<int, 16> ShuffV(Mask);
17349 if (SToVLHS || SToVRHS) {
17352 int ShuffleNumElts = ShuffV.
size();
17353 int HalfVec = ShuffleNumElts / 2;
17359 unsigned LHSNumValidElts = HalfVec;
17360 unsigned RHSNumValidElts = HalfVec;
17365 int LHSFirstElt = 0;
17366 int RHSFirstElt = ShuffleNumElts;
17367 int LHSLastElt = -1;
17368 int RHSLastElt = -1;
17376 int LHSScalarSize = 0;
17377 int RHSScalarSize = 0;
17380 if (!IsLittleEndian && LHSScalarSize >= 64)
17385 if (!IsLittleEndian && RHSScalarSize >= 64)
17388 if (LHSScalarSize != 0)
17390 LHSScalarSize, ShuffleEltWidth, LHSNumValidElts, LHSFirstElt,
17391 LHSLastElt,
LHS, SToVLHS, DAG, Subtarget);
17392 if (RHSScalarSize != 0)
17394 RHSScalarSize, ShuffleEltWidth, RHSNumValidElts, RHSFirstElt,
17395 RHSLastElt,
RHS, SToVRHS, DAG, Subtarget);
17406 ShuffV, LHSFirstElt, LHSLastElt, RHSFirstElt, RHSLastElt, HalfVec,
17407 LHSNumValidElts, RHSNumValidElts, Subtarget);
17433 if (IsLittleEndian) {
17436 if (Mask[0] < NumElts)
17437 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17441 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
17446 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17450 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
17455 if (Mask[0] < NumElts)
17456 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17460 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
17465 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17469 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
17479 if (IsLittleEndian)
17488 DAGCombinerInfo &DCI)
const {
17490 "Not a reverse memop pattern!");
17492 auto IsElementReverse = [](
const ShuffleVectorSDNode *SVN) ->
bool {
17495 auto I =
Mask.rbegin();
17496 auto E =
Mask.rend();
17498 for (;
I !=
E; ++
I) {
17506 SelectionDAG &DAG = DCI.DAG;
17509 if (!
isTypeLegal(VT) || !Subtarget.isLittleEndian() || !Subtarget.hasVSX())
17515 if (!Subtarget.hasP9Vector())
17518 if(!IsElementReverse(SVN))
17525 for (SDUse &Use : LSBase->
uses())
17526 if (
Use.getResNo() == 0 &&
17533 PPCISD::LOAD_VEC_BE, dl, DAG.
getVTList(VT, MVT::Other), LoadOps,
17548 PPCISD::STORE_VEC_BE, dl, DAG.
getVTList(MVT::Other), StoreOps,
17557 if (IntrinsicID == Intrinsic::ppc_stdcx)
17559 else if (IntrinsicID == Intrinsic::ppc_stwcx)
17561 else if (IntrinsicID == Intrinsic::ppc_sthcx)
17563 else if (IntrinsicID == Intrinsic::ppc_stbcx)
17572 if (
N->getOpcode() == PPCISD::ADDC &&
N->hasAnyUseOfValue(1)) {
17576 if (
LHS->getOpcode() == PPCISD::ADDE &&
17587 if (
N->getOpcode() == PPCISD::SUBE) {
17593 if (
LHS ==
RHS &&
LHS.getOpcode() == PPCISD::ADDC) {
17596 if (AddcLHS.
getOpcode() == PPCISD::ADDE &&
17618 SDValue CmpLHS =
N->getOperand(0);
17619 SDValue CmpRHS =
N->getOperand(1);
17620 SDValue TrueVal =
N->getOperand(2);
17621 SDValue FalseVal =
N->getOperand(3);
17635 if (FalseVal.getOpcode() !=
ISD::SRL || !FalseVal.hasOneUse())
17638 SDValue ShiftVal = FalseVal.getOperand(0);
17639 SDValue ShiftAmt = FalseVal.getOperand(1);
17643 if (!ShiftConst || !ShiftConst->getAPIntValue().isMinSignedValue())
17670 if (CtlzArg != CmpLHS)
17678 DAG.
getNode(PPCISD::SRL,
DL, FalseVal.getValueType(), ShiftVal, ShiftAmt);
17725 auto isZeroOrOne = [=](
SDValue &V) {
17727 V.getConstantOperandVal(0) == Intrinsic::ppc_test_data_class)
17732 if (!isZeroOrOne(NonNullConstant))
17742 EVT VType =
N->getValueType(0);
17746 return NewNonNullConstant;
17765 EVT XorVT =
N->getValueType(0);
17766 if ((XorVT != MVT::i32 && XorVT != MVT::i64))
17774 if (!XorConst || !XorConst->
isOne()) {
17776 if (!XorConst || !XorConst->
isOne())
17783 if (!
LHS.hasOneUse())
17791 SelectNode =
LHS.getOperand(0);
17805 if (MachineOpc != PPC::SELECT_CC_I4 && MachineOpc != PPC::SELECT_CC_I8)
17815 if (!ConstOp1 || !ConstOp2)
17819 if (!((ConstOp1->
isOne() && ConstOp2->
isZero()) ||
17828 MachineOpc = (XorVT == MVT::i32) ? PPC::SELECT_CC_I4 : PPC::SELECT_CC_I8;
17830 bool ConstOp1IsOne = ConstOp1->
isOne();
17833 {SelectNode.getOperand(0),
17834 DAG.getConstant(ConstOp1IsOne ? 0 : 1, DL, XorVT),
17835 DAG.getConstant(ConstOp1IsOne ? 1 : 0, DL, XorVT),
17836 SelectNode.getOperand(3)}),
17844 switch (
N->getOpcode()) {
17847 return combineADD(
N, DCI);
17879 return combineSHL(
N, DCI);
17881 return combineSRA(
N, DCI);
17883 return combineSRL(
N, DCI);
17885 return combineMUL(
N, DCI);
17887 case PPCISD::FNMSUB:
17888 return combineFMALike(
N, DCI);
17891 return N->getOperand(0);
17895 return N->getOperand(0);
17901 return N->getOperand(0);
17905 if (
SDValue SECC = combineSignExtendSetCC(
N, DCI))
17913 return DAGCombineExtBoolTrunc(
N, DCI);
17915 return combineTRUNCATE(
N, DCI);
17917 if (
SDValue CSCC = combineSetCC(
N, DCI))
17923 return DAGCombineTruncBoolExt(
N, DCI);
17926 return combineFPToIntToFP(
N, DCI);
17935 EVT Op1VT =
N->getOperand(1).getValueType();
17936 unsigned Opcode =
N->getOperand(1).getOpcode();
17940 SDValue Val = combineStoreFPToInt(
N, DCI);
17954 N->getOperand(1).getNode()->hasOneUse() &&
17955 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
17956 (Subtarget.hasLDBRX() && Subtarget.isPPC64() && Op1VT == MVT::i64))) {
17964 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
17971 if (Op1VT.
bitsGT(mVT)) {
17976 if (Op1VT == MVT::i64)
17981 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
18001 ST->getBasePtr(), ST->getOffset(), MemVT,
18002 ST->getMemOperand(), ST->getAddressingMode(),
18006 return ST->isUnindexed()
18015 if (Subtarget.needsSwapsForVSXMemOps() &&
18016 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
18017 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
18024 EVT VT = LD->getValueType(0);
18030 if (Subtarget.needsSwapsForVSXMemOps() &&
18031 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
18032 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
18043 auto ReplaceTwoFloatLoad = [&]() {
18044 if (VT != MVT::i64)
18059 if (!LD->hasNUsesOfValue(2, 0))
18062 auto UI = LD->user_begin();
18063 while (UI.getUse().getResNo() != 0) ++UI;
18065 while (UI.getUse().getResNo() != 0) ++UI;
18066 SDNode *RightShift = *UI;
18074 if (RightShift->getOpcode() !=
ISD::SRL ||
18076 RightShift->getConstantOperandVal(1) != 32 ||
18077 !RightShift->hasOneUse())
18080 SDNode *Trunc2 = *RightShift->user_begin();
18090 Bitcast->getValueType(0) != MVT::f32)
18096 if (Subtarget.isLittleEndian())
18102 SDValue BasePtr = LD->getBasePtr();
18103 if (LD->isIndexed()) {
18105 "Non-pre-inc AM on PPC?");
18113 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
18114 LD->getPointerInfo(), LD->getAlign(),
18115 MMOFlags, LD->getAAInfo());
18121 LD->getPointerInfo().getWithOffset(4),
18124 if (LD->isIndexed()) {
18138 if (ReplaceTwoFloatLoad())
18141 EVT MemVT = LD->getMemoryVT();
18144 if (LD->isUnindexed() && VT.
isVector() &&
18147 !Subtarget.hasP8Vector() &&
18148 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
18149 VT == MVT::v4f32))) &&
18150 LD->getAlign() < ABIAlignment) {
18152 SDValue Chain = LD->getChain();
18153 SDValue Ptr = LD->getBasePtr();
18154 bool isLittleEndian = Subtarget.isLittleEndian();
18181 MVT PermCntlTy, PermTy, LDTy;
18182 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
18183 : Intrinsic::ppc_altivec_lvsl;
18184 IntrLD = Intrinsic::ppc_altivec_lvx;
18185 IntrPerm = Intrinsic::ppc_altivec_vperm;
18186 PermCntlTy = MVT::v16i8;
18187 PermTy = MVT::v4i32;
18206 SDValue BaseLoadOps[] = { Chain, LDXIntID, Ptr };
18210 BaseLoadOps, LDTy, BaseMMO);
18219 int IncValue = IncOffset;
18236 SDValue ExtraLoadOps[] = { Chain, LDXIntID, Ptr };
18240 ExtraLoadOps, LDTy, ExtraMMO);
18251 if (isLittleEndian)
18253 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
18256 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
18259 Perm = Subtarget.hasAltivec()
18274 bool isLittleEndian = Subtarget.isLittleEndian();
18275 unsigned IID =
N->getConstantOperandVal(0);
18276 Intrinsic::ID Intr = (isLittleEndian ? Intrinsic::ppc_altivec_lvsr
18277 : Intrinsic::ppc_altivec_lvsl);
18278 if (IID == Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
18285 .zext(
Add.getScalarValueSizeInBits()))) {
18286 SDNode *BasePtr =
Add->getOperand(0).getNode();
18287 for (
SDNode *U : BasePtr->users()) {
18289 U->getConstantOperandVal(0) == IID) {
18300 SDNode *BasePtr =
Add->getOperand(0).getNode();
18301 for (
SDNode *U : BasePtr->users()) {
18304 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
18310 V->getConstantOperandVal(0) == IID) {
18322 (IID == Intrinsic::ppc_altivec_vmaxsw ||
18323 IID == Intrinsic::ppc_altivec_vmaxsh ||
18324 IID == Intrinsic::ppc_altivec_vmaxsb)) {
18327 if ((
V1.getSimpleValueType() == MVT::v4i32 ||
18328 V1.getSimpleValueType() == MVT::v8i16 ||
18329 V1.getSimpleValueType() == MVT::v16i8) &&
18334 V1.getOperand(1) == V2) {
18355 switch (
N->getConstantOperandVal(1)) {
18358 case Intrinsic::ppc_altivec_vsum4sbs:
18359 case Intrinsic::ppc_altivec_vsum4shs:
18360 case Intrinsic::ppc_altivec_vsum4ubs: {
18367 APInt APSplatBits, APSplatUndef;
18368 unsigned SplatBitSize;
18371 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
18372 !Subtarget.isLittleEndian());
18374 if (BVNIsConstantSplat && APSplatBits == 0)
18379 case Intrinsic::ppc_vsx_lxvw4x:
18380 case Intrinsic::ppc_vsx_lxvd2x:
18383 if (Subtarget.needsSwapsForVSXMemOps())
18391 if (Subtarget.needsSwapsForVSXMemOps()) {
18392 switch (
N->getConstantOperandVal(1)) {
18395 case Intrinsic::ppc_vsx_stxvw4x:
18396 case Intrinsic::ppc_vsx_stxvd2x:
18405 bool Is64BitBswapOn64BitTgt =
18406 Subtarget.isPPC64() &&
N->getValueType(0) == MVT::i64;
18408 N->getOperand(0).hasOneUse();
18409 if (IsSingleUseNormalLd &&
18410 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
18411 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
18422 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
18423 MVT::i64 : MVT::i32, MVT::Other),
18424 Ops, LD->getMemoryVT(), LD->getMemOperand());
18428 if (
N->getValueType(0) == MVT::i16)
18445 !IsSingleUseNormalLd)
18450 if (!LD->isSimple())
18452 SDValue BasePtr = LD->getBasePtr();
18454 LD->getPointerInfo(), LD->getAlign());
18459 LD->getMemOperand(), 4, 4);
18463 if (Subtarget.isLittleEndian())
18469 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
18478 if (!
N->getOperand(0).hasOneUse() &&
18479 !
N->getOperand(1).hasOneUse() &&
18480 !
N->getOperand(2).hasOneUse()) {
18483 SDNode *VCMPrecNode =
nullptr;
18485 SDNode *LHSN =
N->getOperand(0).getNode();
18487 if (
User->getOpcode() == PPCISD::VCMP_rec &&
18491 VCMPrecNode =
User;
18503 SDNode *FlagUser =
nullptr;
18505 FlagUser ==
nullptr; ++UI) {
18506 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
18519 return SDValue(VCMPrecNode, 0);
18530 SDValue LHS =
N->getOperand(2), RHS =
N->getOperand(3);
18541 auto RHSAPInt = RHS->getAsAPIntVal();
18542 if (!RHSAPInt.isIntN(64))
18545 unsigned Val = RHSAPInt.getZExtValue();
18546 auto isImpossibleCompare = [&]() {
18549 if (Val != 0 && Val != 1) {
18551 return N->getOperand(0);
18554 N->getOperand(0),
N->getOperand(4));
18559 unsigned StoreWidth = 0;
18562 if (
SDValue Impossible = isImpossibleCompare())
18574 SDValue Ops[] = {LHS.getOperand(0), LHS.getOperand(2), LHS.getOperand(3),
18578 PPCISD::STORE_COND, dl,
18580 MemNode->getMemoryVT(), MemNode->getMemOperand());
18584 if (
N->getOperand(0) == LHS.getValue(1))
18595 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other, InChain,
18597 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
18603 assert(isDot &&
"Can't compare against a vector result!");
18605 if (
SDValue Impossible = isImpossibleCompare())
18608 bool BranchOnWhenPredTrue = (CC ==
ISD::SETEQ) ^ (Val == 0);
18615 EVT VTs[] = { LHS.getOperand(2).getValueType(), MVT::Glue };
18620 switch (LHS.getConstantOperandVal(1)) {
18636 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other,
N->getOperand(0),
18639 N->getOperand(4), CompNode.
getValue(1));
18644 return DAGCombineBuildVector(
N, DCI);
18651 return DAGCombineBitcast(
N, DCI);
18662 EVT VT =
N->getValueType(0);
18663 if (VT == MVT::i64 && !Subtarget.isPPC64())
18665 if ((VT != MVT::i32 && VT != MVT::i64) ||
18673 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
18693 const APInt &DemandedElts,
18695 unsigned Depth)
const {
18697 switch (
Op.getOpcode()) {
18699 case PPCISD::LBRX: {
18702 Known.Zero = 0xFFFF0000;
18705 case PPCISD::ADDE: {
18706 if (
Op.getResNo() == 0) {
18711 Known.Zero = ~1ULL;
18716 switch (
Op.getConstantOperandVal(0)) {
18718 case Intrinsic::ppc_altivec_vcmpbfp_p:
18719 case Intrinsic::ppc_altivec_vcmpeqfp_p:
18720 case Intrinsic::ppc_altivec_vcmpequb_p:
18721 case Intrinsic::ppc_altivec_vcmpequh_p:
18722 case Intrinsic::ppc_altivec_vcmpequw_p:
18723 case Intrinsic::ppc_altivec_vcmpequd_p:
18724 case Intrinsic::ppc_altivec_vcmpequq_p:
18725 case Intrinsic::ppc_altivec_vcmpgefp_p:
18726 case Intrinsic::ppc_altivec_vcmpgtfp_p:
18727 case Intrinsic::ppc_altivec_vcmpgtsb_p:
18728 case Intrinsic::ppc_altivec_vcmpgtsh_p:
18729 case Intrinsic::ppc_altivec_vcmpgtsw_p:
18730 case Intrinsic::ppc_altivec_vcmpgtsd_p:
18731 case Intrinsic::ppc_altivec_vcmpgtsq_p:
18732 case Intrinsic::ppc_altivec_vcmpgtub_p:
18733 case Intrinsic::ppc_altivec_vcmpgtuh_p:
18734 case Intrinsic::ppc_altivec_vcmpgtuw_p:
18735 case Intrinsic::ppc_altivec_vcmpgtud_p:
18736 case Intrinsic::ppc_altivec_vcmpgtuq_p:
18743 switch (
Op.getConstantOperandVal(1)) {
18746 case Intrinsic::ppc_load2r:
18748 Known.Zero = 0xFFFF0000;
18757 switch (Subtarget.getCPUDirective()) {
18779 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
18788 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
18790 LoopSize +=
TII->getInstSizeInBytes(J);
18795 if (LoopSize > 16 && LoopSize <= 32)
18809 if (Constraint.
size() == 1) {
18810 switch (Constraint[0]) {
18828 }
else if (Constraint ==
"wc") {
18830 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
18831 Constraint ==
"wf" || Constraint ==
"ws" ||
18832 Constraint ==
"wi" || Constraint ==
"ww") {
18845 Value *CallOperandVal =
info.CallOperandVal;
18848 if (!CallOperandVal)
18855 else if ((
StringRef(constraint) ==
"wa" ||
18867 switch (*constraint) {
18897std::pair<unsigned, const TargetRegisterClass *>
18901 if (Constraint.
size() == 1) {
18903 switch (Constraint[0]) {
18905 if (VT == MVT::i64 && Subtarget.isPPC64())
18906 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
18907 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
18909 if (VT == MVT::i64 && Subtarget.isPPC64())
18910 return std::make_pair(0U, &PPC::G8RCRegClass);
18911 return std::make_pair(0U, &PPC::GPRCRegClass);
18917 if (Subtarget.hasSPE()) {
18918 if (VT == MVT::f32 || VT == MVT::i32)
18919 return std::make_pair(0U, &PPC::GPRCRegClass);
18920 if (VT == MVT::f64 || VT == MVT::i64)
18921 return std::make_pair(0U, &PPC::SPERCRegClass);
18923 if (VT == MVT::f32 || VT == MVT::i32)
18924 return std::make_pair(0U, &PPC::F4RCRegClass);
18925 if (VT == MVT::f64 || VT == MVT::i64)
18926 return std::make_pair(0U, &PPC::F8RCRegClass);
18930 if (Subtarget.hasAltivec() && VT.
isVector())
18931 return std::make_pair(0U, &PPC::VRRCRegClass);
18932 else if (Subtarget.hasVSX())
18934 return std::make_pair(0U, &PPC::VFRCRegClass);
18937 return std::make_pair(0U, &PPC::CRRCRegClass);
18939 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
18941 return std::make_pair(0U, &PPC::CRBITRCRegClass);
18942 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
18943 Constraint ==
"wf" || Constraint ==
"wi") &&
18944 Subtarget.hasVSX()) {
18948 return std::make_pair(0U, &PPC::VSRCRegClass);
18949 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18950 return std::make_pair(0U, &PPC::VSSRCRegClass);
18951 return std::make_pair(0U, &PPC::VSFRCRegClass);
18952 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
18953 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18954 return std::make_pair(0U, &PPC::VSSRCRegClass);
18956 return std::make_pair(0U, &PPC::VSFRCRegClass);
18957 }
else if (Constraint ==
"lr") {
18958 if (VT == MVT::i64)
18959 return std::make_pair(0U, &PPC::LR8RCRegClass);
18961 return std::make_pair(0U, &PPC::LRRCRegClass);
18966 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
18970 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
18971 int VSNum = atoi(Constraint.
data() + 3);
18972 assert(VSNum >= 0 && VSNum <= 63 &&
18973 "Attempted to access a vsr out of range");
18975 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
18976 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
18981 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
18982 int RegNum = atoi(Constraint.
data() + 2);
18983 if (RegNum > 31 || RegNum < 0)
18985 if (VT == MVT::f32 || VT == MVT::i32)
18986 return Subtarget.hasSPE()
18987 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
18988 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
18989 if (VT == MVT::f64 || VT == MVT::i64)
18990 return Subtarget.hasSPE()
18991 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
18992 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
18996 std::pair<unsigned, const TargetRegisterClass *> R =
19005 if (R.first && VT == MVT::i64 && Subtarget.isPPC64() &&
19006 PPC::GPRCRegClass.contains(R.first))
19007 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
19008 PPC::sub_32, &PPC::G8RCRegClass),
19009 &PPC::G8RCRegClass);
19012 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
19013 R.first = PPC::CR0;
19014 R.second = &PPC::CRRCRegClass;
19018 if (Subtarget.isAIXABI() && !TM.getAIXExtendedAltivecABI()) {
19019 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
19020 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
19021 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
19022 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
19023 "default AIX AltiVec ABI and cannot be used\n";
19033 std::vector<SDValue> &
Ops,
19038 if (Constraint.
size() > 1)
19041 char Letter = Constraint[0];
19056 EVT TCVT = MVT::i64;
19097 if (Result.getNode()) {
19098 Ops.push_back(Result);
19109 if (
I.getNumOperands() <= 1)
19113 auto IntrinsicID =
Ops[1].getNode()->getAsZExtVal();
19114 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
19115 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
19118 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
19134 if (Ty->isVectorTy() && AM.
BaseOffs != 0 && !Subtarget.hasP9Vector())
19146 switch (AM.
Scale) {
19174 unsigned Depth =
Op.getConstantOperandVal(0);
19198 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
19206 unsigned Depth =
Op.getConstantOperandVal(0);
19213 bool isPPC64 = PtrVT == MVT::i64;
19219 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
19221 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
19227 FrameAddr, MachinePointerInfo());
19231#define GET_REGISTER_MATCHER
19232#include "PPCGenAsmMatcher.inc"
19236 bool IsPPC64 = Subtarget.isPPC64();
19248 if ((IsPPC64 && Reg == PPC::R2) || Reg == PPC::R0)
19254 Reg = Reg.id() - PPC::R0 + PPC::X0;
19261 if (Subtarget.is32BitELFABI())
19266 if (Subtarget.isAIXABI())
19280 return Subtarget.isGVIndirectSymbol(
G->getGlobal());
19296 case Intrinsic::ppc_atomicrmw_xchg_i128:
19297 case Intrinsic::ppc_atomicrmw_add_i128:
19298 case Intrinsic::ppc_atomicrmw_sub_i128:
19299 case Intrinsic::ppc_atomicrmw_nand_i128:
19300 case Intrinsic::ppc_atomicrmw_and_i128:
19301 case Intrinsic::ppc_atomicrmw_or_i128:
19302 case Intrinsic::ppc_atomicrmw_xor_i128:
19303 case Intrinsic::ppc_cmpxchg_i128:
19305 Info.memVT = MVT::i128;
19306 Info.ptrVal =
I.getArgOperand(0);
19308 Info.align =
Align(16);
19313 case Intrinsic::ppc_atomic_load_i128:
19315 Info.memVT = MVT::i128;
19316 Info.ptrVal =
I.getArgOperand(0);
19318 Info.align =
Align(16);
19322 case Intrinsic::ppc_atomic_store_i128:
19324 Info.memVT = MVT::i128;
19325 Info.ptrVal =
I.getArgOperand(2);
19327 Info.align =
Align(16);
19331 case Intrinsic::ppc_altivec_lvx:
19332 case Intrinsic::ppc_altivec_lvxl:
19333 case Intrinsic::ppc_altivec_lvebx:
19334 case Intrinsic::ppc_altivec_lvehx:
19335 case Intrinsic::ppc_altivec_lvewx:
19336 case Intrinsic::ppc_vsx_lxvd2x:
19337 case Intrinsic::ppc_vsx_lxvw4x:
19338 case Intrinsic::ppc_vsx_lxvd2x_be:
19339 case Intrinsic::ppc_vsx_lxvw4x_be:
19340 case Intrinsic::ppc_vsx_lxvl:
19341 case Intrinsic::ppc_vsx_lxvll: {
19344 case Intrinsic::ppc_altivec_lvebx:
19347 case Intrinsic::ppc_altivec_lvehx:
19350 case Intrinsic::ppc_altivec_lvewx:
19353 case Intrinsic::ppc_vsx_lxvd2x:
19354 case Intrinsic::ppc_vsx_lxvd2x_be:
19364 Info.ptrVal =
I.getArgOperand(0);
19367 Info.align =
Align(1);
19372 case Intrinsic::ppc_altivec_stvx:
19373 case Intrinsic::ppc_altivec_stvxl:
19374 case Intrinsic::ppc_altivec_stvebx:
19375 case Intrinsic::ppc_altivec_stvehx:
19376 case Intrinsic::ppc_altivec_stvewx:
19377 case Intrinsic::ppc_vsx_stxvd2x:
19378 case Intrinsic::ppc_vsx_stxvw4x:
19379 case Intrinsic::ppc_vsx_stxvd2x_be:
19380 case Intrinsic::ppc_vsx_stxvw4x_be:
19381 case Intrinsic::ppc_vsx_stxvl:
19382 case Intrinsic::ppc_vsx_stxvll: {
19385 case Intrinsic::ppc_altivec_stvebx:
19388 case Intrinsic::ppc_altivec_stvehx:
19391 case Intrinsic::ppc_altivec_stvewx:
19394 case Intrinsic::ppc_vsx_stxvd2x:
19395 case Intrinsic::ppc_vsx_stxvd2x_be:
19405 Info.ptrVal =
I.getArgOperand(1);
19408 Info.align =
Align(1);
19413 case Intrinsic::ppc_stdcx:
19414 case Intrinsic::ppc_stwcx:
19415 case Intrinsic::ppc_sthcx:
19416 case Intrinsic::ppc_stbcx: {
19418 auto Alignment =
Align(8);
19420 case Intrinsic::ppc_stdcx:
19423 case Intrinsic::ppc_stwcx:
19425 Alignment =
Align(4);
19427 case Intrinsic::ppc_sthcx:
19429 Alignment =
Align(2);
19431 case Intrinsic::ppc_stbcx:
19433 Alignment =
Align(1);
19438 Info.ptrVal =
I.getArgOperand(0);
19440 Info.align = Alignment;
19454 const AttributeList &FuncAttributes)
const {
19458 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
19459 if (
Op.isMemset() && Subtarget.hasVSX()) {
19464 if (TailSize > 2 && TailSize <= 4) {
19469 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
19474 if (Subtarget.isPPC64()) {
19485 assert(Ty->isIntegerTy());
19487 unsigned BitSize = Ty->getPrimitiveSizeInBits();
19488 return !(BitSize == 0 || BitSize > 64);
19496 return NumBits1 == 64 && NumBits2 == 32;
19504 return NumBits1 == 64 && NumBits2 == 32;
19511 EVT MemVT = LD->getMemoryVT();
19512 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
19513 (Subtarget.isPPC64() && MemVT == MVT::i32)) &&
19529 "invalid fpext types");
19531 if (DestVT == MVT::f128)
19546 unsigned *
Fast)
const {
19560 !Subtarget.allowsUnalignedFPAccess())
19564 if (Subtarget.hasVSX()) {
19565 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
19566 VT != MVT::v4f32 && VT != MVT::v4i32)
19573 if (VT == MVT::ppcf128)
19588 if (!ConstNode->getAPIntValue().isSignedIntN(64))
19596 int64_t Imm = ConstNode->getSExtValue();
19617 if (Subtarget.hasSPE() || Subtarget.useSoftFloat())
19619 switch (Ty->getScalarType()->getTypeID()) {
19624 return Subtarget.hasP9Vector();
19632 if (!
I->hasOneUse())
19636 assert(
User &&
"A single use instruction with no uses.");
19638 switch (
I->getOpcode()) {
19639 case Instruction::FMul: {
19641 if (
User->getOpcode() != Instruction::FSub &&
19642 User->getOpcode() != Instruction::FAdd)
19649 bool AllowContract =
I->getFastMathFlags().allowContract() &&
19650 User->getFastMathFlags().allowContract();
19656 case Instruction::Load: {
19669 if (
User->getOpcode() != Instruction::Store)
19689 static const MCPhysReg ScratchRegs[] = {
19690 PPC::X12, PPC::LR8, PPC::CTR8, 0
19693 return ScratchRegs;
19697 const Constant *PersonalityFn)
const {
19698 return Subtarget.isPPC64() ? PPC::X3 : PPC::R3;
19702 const Constant *PersonalityFn)
const {
19703 return Subtarget.isPPC64() ? PPC::X4 : PPC::R4;
19708 EVT VT ,
unsigned DefinedValues)
const {
19709 if (VT == MVT::v2i64)
19710 return Subtarget.hasDirectMove();
19712 if (Subtarget.hasVSX())
19739 return PPCISD::FNMSUB;
19740 case PPCISD::FNMSUB:
19746 bool LegalOps,
bool OptForSize,
19748 unsigned Depth)
const {
19752 unsigned Opc =
Op.getOpcode();
19753 EVT VT =
Op.getValueType();
19757 case PPCISD::FNMSUB:
19777 if (Flags.hasNoSignedZeros()) {
19781 N0Cost,
Depth + 1);
19785 N1Cost,
Depth + 1);
19787 if (NegN0 && N0Cost <= N1Cost) {
19788 Cost = std::min(N0Cost, N2Cost);
19790 }
else if (NegN1) {
19791 Cost = std::min(N1Cost, N2Cost);
19811 if (M.getStackProtectorGuard() ==
"tls" || Subtarget.isTargetLinux())
19817 bool ForCodeSize)
const {
19818 if (!VT.
isSimple() || !Subtarget.hasVSX())
19828 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
19833 APSInt IntResult(16,
false);
19838 if (IsExact && IntResult <= 15 && IntResult >= -16)
19840 return Imm.isZero();
19843 return Imm.isPosZero();
19855 unsigned Opcode =
N->getOpcode();
19875 if (Mask->getZExtValue() == OpSizeInBits - 1)
19882 DAGCombinerInfo &DCI)
const {
19883 EVT VT =
N->getValueType(0);
19886 unsigned Opc =
N->getOpcode();
19888 "Unexpected opcode.");
19895 if (EltTy != MVT::i64 && EltTy != MVT::i32)
19899 uint64_t SplatBits = 0;
19900 bool AddSplatCase =
false;
19904 AddSplatCase =
true;
19908 if (!AddSplatCase) {
19912 unsigned SplatBitSize;
19914 APInt APSplatBits, APSplatUndef;
19916 bool BVNIsConstantSplat =
19918 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
19919 if (!BVNIsConstantSplat || SplatBitSize != EltBits)
19930 if (SplatBits == (EltBits - 1)) {
19934 NewOpc = PPCISD::SHL;
19937 NewOpc = PPCISD::SRL;
19940 NewOpc = PPCISD::SRA;
19944 return DCI.DAG.getNode(NewOpc,
DL, VT, N0, SplatOnes);
19952 if (EltTy != MVT::i64 || SplatBits != 1)
19955 return DCI.DAG.getNode(
ISD::ADD, SDLoc(
N), VT, N0, N0);
19958SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19962 if (
N->getValueType(0).isVector())
19963 return combineVectorShift(
N, DCI);
19967 if (!Subtarget.isISA3_0() || !Subtarget.isPPC64() ||
19970 N->getValueType(0) != MVT::i64)
19985 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
19991SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19995 if (
N->getValueType(0).isVector())
19996 return combineVectorShift(
N, DCI);
20001SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20005 if (
N->getValueType(0).isVector())
20006 return combineVectorShift(
N, DCI);
20017 if (!Subtarget.isPPC64())
20023 auto isZextOfCompareWithConstant = [](
SDValue Op) {
20025 Op.getValueType() != MVT::i64)
20029 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
20030 Cmp.getOperand(0).getValueType() != MVT::i64)
20034 int64_t NegConstant = 0 -
Constant->getSExtValue();
20043 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
20044 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
20047 if (LHSHasPattern && !RHSHasPattern)
20049 else if (!LHSHasPattern && !RHSHasPattern)
20053 EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
20056 SDValue Z = Cmp.getOperand(0);
20058 int64_t NegConstant = 0 -
Constant->getSExtValue();
20071 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
20089 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
20119 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
20122 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
20130 if (!GSDN || !ConstNode)
20158 EVT VT =
N->getValueType(0);
20159 if (!Subtarget.hasVSX())
20163 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
20175 unsigned NumOfEles =
RHS.getNumOperands();
20176 for (
unsigned i = 0; i < NumOfEles; ++i) {
20178 if (!CN || CN->getSExtValue() != 1)
20193SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20215 DAGCombinerInfo &DCI)
const {
20217 if (Subtarget.useCRBits()) {
20219 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
20220 return CRTruncValue;
20227 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
20230 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
20240 EltToExtract = EltToExtract ? 0 : 1;
20250 return DCI.DAG.getNode(
20252 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
20257SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20258 SelectionDAG &DAG = DCI.DAG;
20261 if (!ConstOpOrElement)
20269 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne, EVT VT) ->
bool {
20270 switch (this->Subtarget.getCPUDirective()) {
20293 return IsAddOne && IsNeg ? VT.
isVector() :
true;
20297 EVT VT =
N->getValueType(0);
20302 APInt MulAmtAbs = MulAmt.
abs();
20304 if ((MulAmtAbs - 1).isPowerOf2()) {
20308 if (!IsProfitable(IsNeg,
true, VT))
20321 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
20325 if (!IsProfitable(IsNeg,
false, VT))
20346 DAGCombinerInfo &DCI)
const {
20350 SDNodeFlags
Flags =
N->getFlags();
20351 EVT VT =
N->getValueType(0);
20352 SelectionDAG &DAG = DCI.DAG;
20353 unsigned Opc =
N->getOpcode();
20355 bool LegalOps = !DCI.isBeforeLegalizeOps();
20363 if (!
Flags.hasNoSignedZeros())
20379bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
20381 if (!Subtarget.is64BitELFABI())
20391 if (!TM.Options.GuaranteedTailCallOpt &&
DisableSCO)
20396 if (!Callee ||
Callee->isVarArg())
20409bool PPCTargetLowering::
20410isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
20415 if (CI->getBitWidth() > 64)
20417 int64_t ConstVal = CI->getZExtValue();
20419 (
isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
20428PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
20434 if ((Flags & FlagSet) == FlagSet)
20437 if ((Flags & FlagSet) == FlagSet)
20440 if ((Flags & FlagSet) == FlagSet)
20443 if ((Flags & FlagSet) == FlagSet)
20464 if ((FrameIndexAlign % 4) != 0)
20465 FlagSet &=
~PPC::MOF_RPlusSImm16Mult4;
20466 if ((FrameIndexAlign % 16) != 0)
20467 FlagSet &=
~PPC::MOF_RPlusSImm16Mult16;
20471 if ((FrameIndexAlign % 4) == 0)
20473 if ((FrameIndexAlign % 16) == 0)
20486 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
20487 if ((Imm & 0x3) == 0)
20489 if ((Imm & 0xf) == 0)
20495 const APInt &ConstImm = CN->getAPIntValue();
20514 const APInt &ConstImm = CN->getAPIntValue();
20524 }
else if (
RHS.getOpcode() == PPCISD::Lo && !
RHS.getConstantOperandVal(1))
20535 return (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR ||
20544unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
20549 if (!Subtarget.hasP9Vector())
20554 if (Subtarget.hasPrefixInstrs())
20557 if (Subtarget.hasSPE())
20566 unsigned ParentOp = Parent->
getOpcode();
20570 if ((
ID == Intrinsic::ppc_vsx_lxvp) || (
ID == Intrinsic::ppc_vsx_stxvp)) {
20571 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
20583 if (LSB->isIndexed())
20589 assert(MN &&
"Parent should be a MemSDNode!");
20594 "Not expecting scalar integers larger than 16 bytes!");
20597 else if (
Size == 32)
20604 else if (
Size == 256) {
20605 assert(Subtarget.pairedVectorMemops() &&
20606 "256-bit vectors are only available when paired vector memops is "
20614 else if (MemVT == MVT::f128 || MemVT.
isVector())
20645 FlagSet &= ~PPC::MOF_NoExt;
20650 bool IsNonP1034BitConst =
20654 IsNonP1034BitConst)
20667 int16_t ForceXFormImm = 0;
20670 Disp =
N.getOperand(0);
20671 Base =
N.getOperand(1);
20682 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
20683 Disp =
N.getOperand(0);
20684 Base =
N.getOperand(1);
20689 Disp = DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20698 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
20704 if (PartVT == MVT::f64 &&
20705 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
20714SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
20718 EVT RetVT =
Op.getValueType();
20725 EVT ArgVT =
N.getValueType();
20729 Entry.IsZExt = !Entry.IsSExt;
20730 Args.push_back(Entry);
20738 (RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
20751SDValue PPCTargetLowering::lowerLibCallBasedOnType(
20752 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
20754 if (
Op.getValueType() == MVT::f32)
20755 return lowerToLibCall(LibCallFloatName,
Op, DAG);
20757 if (
Op.getValueType() == MVT::f64)
20758 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
20763bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
20764 SDNodeFlags
Flags =
Op.getNode()->getFlags();
20765 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
20769bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
20770 return Op.getNode()->getFlags().hasApproximateFuncs();
20773bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
20777SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
20778 const char *LibCallFloatName,
20779 const char *LibCallDoubleNameFinite,
20780 const char *LibCallFloatNameFinite,
20783 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
20786 if (!isLowringToMASSFiniteSafe(
Op))
20787 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
20790 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
20791 LibCallDoubleNameFinite,
Op, DAG);
20795 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
20796 "__xl_powf_finite",
Op, DAG);
20800 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
20801 "__xl_sinf_finite",
Op, DAG);
20805 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
20806 "__xl_cosf_finite",
Op, DAG);
20810 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
20811 "__xl_logf_finite",
Op, DAG);
20815 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
20816 "__xl_log10f_finite",
Op, DAG);
20820 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
20821 "__xl_expf_finite",
Op, DAG);
20846 unsigned Flags = computeMOFlags(Parent,
N, DAG);
20857 assert(Subtarget.isUsingPCRelativeCalls() &&
20858 "Must be using PC-Relative calls when a valid PC-Relative node is "
20888 Disp =
N.getOperand(1).getOperand(0);
20893 Base =
N.getOperand(0);
20901 EVT CNType = CN->getValueType(0);
20902 uint64_t CNImm = CN->getZExtValue();
20913 if ((CNType == MVT::i32 ||
isInt<32>(CNImm)) &&
20915 int32_t Addr = (int32_t)CNImm;
20920 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
20936 unsigned Opcode =
N.getOpcode();
20944 Base =
N.getOperand(0);
20963 Base = FI ?
N :
N.getOperand(1);
20964 Disp = FI ? DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20975 bool IsVarArg)
const {
20985 return Subtarget.isPPC64() && Subtarget.hasQuadwordAtomics();
21022 return Intrinsic::ppc_atomicrmw_xchg_i128;
21024 return Intrinsic::ppc_atomicrmw_add_i128;
21026 return Intrinsic::ppc_atomicrmw_sub_i128;
21028 return Intrinsic::ppc_atomicrmw_and_i128;
21030 return Intrinsic::ppc_atomicrmw_or_i128;
21032 return Intrinsic::ppc_atomicrmw_xor_i128;
21034 return Intrinsic::ppc_atomicrmw_nand_i128;
21042 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
21046 Value *IncrLo = Builder.CreateTrunc(Incr, Int64Ty,
"incr_lo");
21048 Builder.CreateTrunc(Builder.CreateLShr(Incr, 64), Int64Ty,
"incr_hi");
21049 Value *LoHi = Builder.CreateIntrinsic(
21051 {AlignedAddr, IncrLo, IncrHi});
21052 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
21053 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
21054 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
21055 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
21056 return Builder.CreateOr(
21057 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
21064 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
21070 Value *CmpLo = Builder.CreateTrunc(CmpVal, Int64Ty,
"cmp_lo");
21072 Builder.CreateTrunc(Builder.CreateLShr(CmpVal, 64), Int64Ty,
"cmp_hi");
21073 Value *NewLo = Builder.CreateTrunc(NewVal, Int64Ty,
"new_lo");
21075 Builder.CreateTrunc(Builder.CreateLShr(NewVal, 64), Int64Ty,
"new_hi");
21078 Builder.CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
21080 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
21081 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
21082 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
21083 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
21084 return Builder.CreateOr(
21085 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
21089 return Subtarget.useCRBits();
21094bool PPCTargetLowering::isShuffleMaskLegal(
ArrayRef<int> Mask,
EVT VT)
const {
21105 DAGCombinerInfo &DCI)
const {
21110 EVT ResVT =
N->getValueType(0);
21112 EVT SrcVT = Src.getValueType();
21117 if (ResVT != MVT::i16 && ResVT != MVT::i8)
21120 GenerateVBPERM(DAG, dl, Src, SrcVT, TruncResVT, IsLittleEndian);
21133 bool IsV16i8 = (ResVT == MVT::v16i1 && SrcVT == MVT::v16i8);
21134 bool IsV8i16 = (ResVT == MVT::v8i1 && SrcVT == MVT::v8i16);
21135 bool IsV8i8 = (ResVT == MVT::v8i1 && SrcVT == MVT::v8i8);
21137 if (!IsV16i8 && !IsV8i16 && !IsV8i8)
21145 SmallVector<int, 16> BitIndices(16, 128);
21149 BitIndices[Idx] = EltSize * (NumElts - Idx) - 1;
21150 if (IsV8i8 && IsLE)
21151 BitIndices[Idx] += 64;
21154 std::reverse(BitIndices.begin(), BitIndices.end());
21156 for (
auto Idx : BitIndices)
21161 DAG.
getConstant(Intrinsic::ppc_altivec_vbpermq, dl, MVT::i32),
21169 bool BVNIsConstantSplat,
21170 unsigned SplatBitSize)
const {
21172 if (!BVNIsConstantSplat || !Subtarget.hasVSX() || !Subtarget.hasP8Vector() ||
21173 Subtarget.hasP10Vector())
21176 EVT VT =
Op->getValueType(0);
21177 if (!((SplatBitSize == 64 && VT == MVT::v2f64) ||
21178 (SplatBitSize == 32 && VT == MVT::v4f32)))
21185 APFloat APFloatVal = CN->getValueAPF();
21187 APSInt IntResult(16,
false);
21190 if (!(IsExact && IntResult <= 15 && IntResult >= -16 && !APFloatVal.
isZero()))
21193 int64_t
IntVal = IntResult.getSExtValue();
21198 if (SplatBitSize == 64)
21201 DAG.
getConstant(Intrinsic::ppc_vsx_xvcvsxwdp, dl, MVT::i32), IntSplat);
21203 return DAG.
getNode(PPCISD::XVCVSXWSP, dl, MVT::v4f32, IntSplat);
static MCRegister MatchRegisterName(StringRef Name)
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall, std::optional< CallLowering::PtrAuthInfo > &PAI, MachineRegisterInfo &MRI)
static SDValue GeneratePerfectShuffle(unsigned ID, SDValue V1, SDValue V2, unsigned PFEntry, SDValue LHS, SDValue RHS, SelectionDAG &DAG, const SDLoc &DL)
GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit the specified operations t...
static bool isSignExtended(SDValue N, SelectionDAG &DAG)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
const HexagonInstrInfo * TII
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, ISD::ArgFlagsTy Flags, SelectionDAG &DAG, const SDLoc &dl)
CreateCopyOfByValArgument - Make a copy of an aggregate at address specified by "Src" to address "Dst...
Module.h This file contains the declarations for the Module class.
This defines the Use class.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
static int getEstimateRefinementSteps(EVT VT, const LoongArchSubtarget &Subtarget)
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).
Machine Check Debug Module
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static bool isConstantOrUndef(const SDValue Op)
MachineInstr unsigned OpIdx
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 CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
static const TargetRegisterClass * getRegClassForSVT(MVT::SimpleValueType SVT, bool IsPPC64, bool HasP8Vector, bool HasVSX)
static bool isGPRShadowAligned(MCPhysReg Reg, Align RequiredAlign)
static SDValue DAGCombineAddc(SDNode *N, llvm::PPCTargetLowering::DAGCombinerInfo &DCI)
static bool needStackSlotPassParameters(const PPCSubtarget &Subtarget, const SmallVectorImpl< ISD::OutputArg > &Outs)
std::tuple< uint32_t, uint8_t > LXVKQPattern
static bool isAlternatingShuffMask(const ArrayRef< int > &Mask, int NumElts)
static bool isShuffleMaskInRange(const SmallVectorImpl< int > &ShuffV, int HalfVec, int LHSLastElementDefined, int RHSLastElementDefined)
static SDValue addShuffleForVecExtend(SDNode *N, SelectionDAG &DAG, SDValue Input, uint64_t Elems, uint64_t CorrectElems)
static cl::opt< bool > DisablePPCUnaligned("disable-ppc-unaligned", cl::desc("disable unaligned load/store generation on PPC"), cl::Hidden)
static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool findConsecutiveLoad(LoadSDNode *LD, SelectionDAG &DAG)
static SDValue generateEquivalentSub(SDNode *N, int Size, bool Complement, bool Swap, SDLoc &DL, SelectionDAG &DAG)
This function is called when we have proved that a SETCC node can be replaced by subtraction (and oth...
static unsigned mapArgRegToOffsetAIX(unsigned Reg, const PPCFrameLowering *FL)
static void CalculateTailCallArgDest(SelectionDAG &DAG, MachineFunction &MF, bool IsPPC64, SDValue Arg, int SPDiff, unsigned ArgOffset, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
CalculateTailCallArgDest - Remember Argument for later processing.
static MachineBasicBlock * emitAtomicCmpSwapSoftware(MachineInstr &MI, MachineBasicBlock *BB, const TargetInstrInfo *TII, const PPCSubtarget &Subtarget)
Emit software-emulated atomic compare-and-swap for I8/I16 without hardware partword atomic support.
static SDValue DAGCombineSube(SDNode *N, llvm::PPCTargetLowering::DAGCombinerInfo &DCI)
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 IsSelect(unsigned Opcode, bool CheckOnlyCC=false)
Check if the opcode is a SELECT or SELECT_CC variant.
static bool provablyDisjointOr(SelectionDAG &DAG, const SDValue &N)
Used when computing address flags for selecting loads and stores.
static bool callsShareTOCBase(const Function *Caller, const GlobalValue *CalleeGV, const TargetMachine &TM)
static void prepareOutOfLineGlueCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, SDValue CallSeqStart, const CallBase *CB, const SDLoc &dl, bool hasNest, const PPCSubtarget &Subtarget)
static SDValue generateSToVPermutedForVecShuffle(int ScalarSize, uint64_t ShuffleEltWidth, unsigned &NumValidElts, int FirstElt, int &LastElt, SDValue VecShuffOperand, SDValue SToVNode, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
constexpr uint64_t AIXSmallTlsPolicySizeLimit
static bool isPCRelNode(SDValue N)
static void LowerMemOpCallTo(SelectionDAG &DAG, MachineFunction &MF, SDValue Chain, SDValue Arg, SDValue PtrOff, int SPDiff, unsigned ArgOffset, bool isPPC64, bool isTailCall, bool isVector, SmallVectorImpl< SDValue > &MemOpChains, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments, const SDLoc &dl)
LowerMemOpCallTo - Store the argument to the stack or remember it in case of tail calls.
static cl::opt< unsigned > PPCGatherAllAliasesMaxDepth("ppc-gather-alias-max-depth", cl::init(18), cl::Hidden, cl::desc("max depth when checking alias info in GatherAllAliases()"))
static bool IsSelectCC(unsigned Opcode)
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 SDValue ConvertCarryFlagToCarryValue(EVT SumType, SDValue Flag, EVT CarryType, SelectionDAG &DAG, const PPCSubtarget &STI)
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 void setUsesTOCBasePtr(MachineFunction &MF)
static SDValue combineXorSelectCC(SDNode *N, SelectionDAG &DAG)
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 bool canConvertToVcmpequb(SDValue &LHS, SDValue &RHS, bool IsPPC64)
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 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 cl::opt< unsigned > PPCMinimumBitTestCmps("ppc-min-bit-test-cmps", cl::init(3), cl::Hidden, cl::desc("Set minimum of largest number of comparisons to use bit test for " "switch on PPC."))
static CallInst * callIntrinsic(IRBuilderBase &Builder, Intrinsic::ID Id)
static void getMaxByValAlign(Type *Ty, Align &MaxAlign, Align MaxMaxAlign)
getMaxByValAlign - Helper for getByValTypeAlignment to determine the desired ByVal argument alignment...
static bool isConsecutiveLS(SDNode *N, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static bool isVMerge(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned LHSStart, unsigned RHSStart)
isVMerge - Common function, used to match vmrg* shuffles.
static void getLabelAccessInfo(bool IsPIC, const PPCSubtarget &Subtarget, unsigned &HiOpFlags, unsigned &LoOpFlags, const GlobalValue *GV=nullptr)
Return true if we should reference labels using a PICBase, set the HiOpFlags and LoOpFlags to the tar...
cl::opt< bool > DisableAutoPairedVecSt("disable-auto-paired-vec-st", cl::desc("disable automatically generated 32byte paired vector stores"), cl::init(true), cl::Hidden)
static void buildCallOperands(SmallVectorImpl< SDValue > &Ops, PPCTargetLowering::CallFlags CFlags, const SDLoc &dl, SelectionDAG &DAG, SmallVector< std::pair< unsigned, SDValue >, 8 > &RegsToPass, SDValue Glue, SDValue Chain, SDValue &Callee, int SPDiff, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableInnermostLoopAlign32("disable-ppc-innermost-loop-align32", cl::desc("don't always align innermost loop to 32 bytes on ppc"), cl::Hidden)
static bool usePartialVectorLoads(SDNode *N, const PPCSubtarget &ST)
Returns true if we should use a direct load into vector instruction (such as lxsd or lfd),...
static SDValue getDataClassTest(SDValue Op, FPClassTest Mask, const SDLoc &Dl, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void fixupShuffleMaskForPermutedSToV(SmallVectorImpl< int > &ShuffV, int LHSFirstElt, int LHSLastElt, int RHSFirstElt, int RHSLastElt, int HalfVec, unsigned LHSNumValidElts, unsigned RHSNumValidElts, const PPCSubtarget &Subtarget)
static SDValue AdjustLength(SDValue Val, unsigned Bits, bool Left, SelectionDAG &DAG)
static cl::opt< bool > DisableSCO("disable-ppc-sco", cl::desc("disable sibling call optimization on ppc"), cl::Hidden)
static std::optional< LXVKQPattern > getPatternInfo(const APInt &FullVal)
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 SDValue ConvertSETCCToXori(SDNode *N, SelectionDAG &DAG)
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 void prepareIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, const SDLoc &dl)
static SDValue combineSELECT_CCBitFloor(SDNode *N, SelectionDAG &DAG)
Optimize the bitfloor(X) pattern for PowerPC.
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)
bool isValidMtVsrBmi(APInt &BitMask, BuildVectorSDNode &BVN, bool IsLittleEndian)
static MachineBasicBlock * emitSelect(MachineInstr &MI, MachineBasicBlock *BB, const TargetInstrInfo *TII, const PPCSubtarget &Subtarget)
Emit SELECT instruction, using ISEL if available, otherwise use branch-based control flow.
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 SDValue combineADDToSUB(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static const SDValue * getNormalLoadInput(const SDValue &Op, bool &IsPermuted)
static bool canConvertSETCCToXori(SDNode *N)
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 ConvertCarryValueToCarryFlag(EVT SumType, SDValue Value, SelectionDAG &DAG, const PPCSubtarget &STI)
static SDValue convertIntToFP(SDValue Op, SDValue Src, SelectionDAG &DAG, const PPCSubtarget &Subtarget, SDValue Chain=SDValue())
static void PrepareTailCall(SelectionDAG &DAG, SDValue &InGlue, SDValue &Chain, const SDLoc &dl, int SPDiff, unsigned NumBytes, SDValue LROp, SDValue FPOp, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
static SDValue EmitTailCallStoreFPAndRetAddr(SelectionDAG &DAG, SDValue Chain, SDValue OldRetAddr, SDValue OldFP, int SPDiff, const SDLoc &dl)
EmitTailCallStoreFPAndRetAddr - Move the frame pointer and return address to the appropriate stack sl...
static SDValue BuildVSLDOI(SDValue LHS, SDValue RHS, unsigned Amt, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
BuildVSLDOI - Return a VECTOR_SHUFFLE that is a vsldoi of the specified amount.
static void createAtomicLoopBlocks(MachineFunction *F, MachineBasicBlock *BB, MachineBasicBlock *&loop1MBB, MachineBasicBlock *&loop2MBB, MachineBasicBlock *&exitMBB, MachineInstr &MI, MachineFunction::iterator It)
Helper function to create basic blocks for atomic compare-and-swap.
static SDValue combineBVZEXTLOAD(SDNode *N, SelectionDAG &DAG)
static SDValue combineZextSetccWithZero(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...
static MachineBasicBlock * emitAtomicCmpSwapHardware(MachineInstr &MI, MachineBasicBlock *BB, const TargetInstrInfo *TII, const PPCSubtarget &Subtarget)
Emit hardware-supported atomic compare-and-swap for I32/I64 and I8/I16 with partword atomic support.
SDValue convertTwoLoadsAndCmpToVCMPEQUB(SelectionDAG &DAG, SDNode *N, const SDLoc &DL)
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 void signExtendOperandIfUnknown(MachineInstr &MI, MachineBasicBlock *BB, unsigned OpIdx, bool IsByte, const PPCInstrInfo *TII)
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)
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
pre isel intrinsic Pre ISel Intrinsic Lowering
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
SI optimize exec mask operations pre RA
static const MCExpr * MaskShift(const MCExpr *Val, uint32_t Mask, uint32_t Shift, MCContext &Ctx)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG, const SparcSubtarget *Subtarget)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
This file describes how to lower LLVM code to machine code.
static constexpr int TPOffset
static const fltSemantics & IEEEsingle()
static constexpr roundingMode rmTowardZero
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & PPCDoubleDouble()
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
APInt bitcastToAPInt() const
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) 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.
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 isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
bool isNegative() const
Determine sign of this APInt.
void clearAllBits()
Set every bit to 0.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
LLVM_ABI void insertBits(const APInt &SubBits, unsigned bitPosition)
Insert the bits from a smaller APInt starting at bitPosition.
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.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
LLVM_ABI APInt extractBits(unsigned numBits, unsigned bitPosition) const
Return an APInt with the extracted bits [bitPosition,bitPosition+numBits).
An arbitrary precision integer that knows its signedness.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
An instruction that atomically checks whether a specified value is in a memory location,...
Value * getNewValOperand()
an instruction that atomically reads a memory location, combines it with another value,...
BinOp
This enumeration lists the possible modifications atomicrmw can make.
@ USubCond
Subtract only if no unsigned overflow.
@ USubSat
*p = usub.sat(old, v) usub.sat matches the behavior of llvm.usub.sat.
@ UIncWrap
Increment one up to a maximum value.
@ UDecWrap
Decrement one until a minimum value or zero.
BinOp getOperation() const
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
LLVM Basic Block Representation.
int64_t getOffset() const
const BlockAddress * getBlockAddress() const
static constexpr BranchProbability getOne()
static constexpr BranchProbability getZero()
A "pseudo-class" with methods for operating on BUILD_VECTORs.
LLVM_ABI 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.
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP)
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
int64_t getLocMemOffset() const
unsigned getValNo() const
static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool isStrictFP() const
Determine if the call requires strict floating point semantics.
CallingConv::ID getCallingConv() const
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
LLVM_ABI 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
LLVM_ABI 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].
const Constant * getConstVal() const
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
int64_t getSExtValue() const
This is an important base class in LLVM.
uint64_t getNumOperands() const
A parsed version of the target data layout string in and methods for querying it.
bool isLittleEndian() const
Layout endianness...
LLVM_ABI unsigned getLargestLegalIntTypeSizeInBits() const
Returns the size of largest legal integer type size, or 0 if none are set.
LLVM_ABI 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.
LLVM_ABI Align getABITypeAlign(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
LLVM_ABI TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
AttributeList getAttributes() const
Return the attribute list for this Function.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Type * getReturnType() const
Returns the type of the ret val.
const Argument * const_arg_iterator
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
LLVM_ABI 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
LLVM_ABI 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.
LLVM_ABI 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.
LLVM_ABI 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.
Tracks which library functions to use for a particular subtarget.
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, SMLoc Loc=SMLoc())
@ INVALID_SIMPLE_VALUE_TYPE
uint64_t getScalarSizeInBits() const
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
LLVM_ABI 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.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
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 '...
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
LLVM_ABI 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.
BasicBlockListType::iterator iterator
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)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
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 & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
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.
AtomicOrdering getFailureOrdering() const
For cmpxchg atomic operations, return the atomic ordering requirements when store does not occur.
SyncScope::ID getSyncScopeID() const
Returns the synchronization scope ID for this memory operation.
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.
AtomicOrdering getSuccessOrdering() const
Return the atomic ordering requirements for this memory operation.
const MachinePointerInfo & getPointerInfo() const
Flags getFlags() const
Return the raw flags of the source value,.
LLVM_ABI Align getAlign() const
Return the minimum known alignment in bytes of the actual memory reference.
AAMDNodes getAAInfo() const
Return the AA tags for the memory reference.
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,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLVM_ABI Register getLiveInVirtReg(MCRegister PReg) const
getLiveInVirtReg - If PReg is a live-in physical register, return the corresponding live-in virtual r...
bool use_empty(Register RegNo) const
use_empty - Return true if there are no instructions using the specified register.
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 the unique 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.
unsigned getLinkageSize() const
getLinkageSize - Return the size of the PowerPC ABI linkage area.
uint64_t getTOCSaveOffset() const
getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
void setVarArgsNumFPR(unsigned Num)
void setReturnAddrSaveIndex(int idx)
bool isAIXFuncUseTLSIEForLD() const
int getReturnAddrSaveIndex() const
unsigned getVarArgsNumFPR() const
void setAIXFuncUseTLSIEForLD()
int getFramePointerSaveIndex() const
void setVarArgsNumGPR(unsigned Num)
void appendParameterType(ParamType Type)
int getVarArgsFrameIndex() const
void setLRStoreRequired()
bool isAIXFuncTLSModelOptInitDone() const
void setTailCallSPDelta(int size)
void setAIXFuncTLSModelOptInitDone()
bool isLRStoreRequired() const
void setMinReservedArea(unsigned size)
unsigned getVarArgsNumGPR() const
unsigned getMinReservedArea() const
void setVarArgsStackOffset(int Offset)
void setVarArgsFrameIndex(int Index)
void addLiveInAttr(Register VReg, ISD::ArgFlagsTy Flags)
This function associates attributes for each live-in virtual register.
int getVarArgsStackOffset() const
void setFramePointerSaveIndex(int Idx)
static bool hasPCRelFlag(unsigned TF)
bool is32BitELFABI() const
unsigned descriptorTOCAnchorOffset() const
MVT getScalarIntVT() const
MCRegister getGlueCodeDescriptorRegister() const
const PPCFrameLowering * getFrameLowering() const override
bool isUsingPCRelativeCalls() const
bool usesFunctionDescriptors() const
True if the ABI is descriptor based.
MCRegister getEnvironmentPointerRegister() const
bool isLittleEndian() const
MCRegister getTOCPointerRegister() const
MCRegister getStackPointerRegister() const
bool is64BitELFABI() const
const PPCTargetMachine & getTargetMachine() const
const PPCRegisterInfo * getRegisterInfo() const override
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
TargetLowering::AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
bool hasInlineStackProbe(const MachineFunction &MF) const override
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
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...
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...
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...
bool hasMultipleConditionRegisters(EVT VT) const override
Does the target have multiple (allocatable) condition registers that can be used to store the results...
Align getByValTypeAlignment(Type *Ty, const DataLayout &DL) const override
getByValTypeAlignment - Return the desired alignment for ByVal aggregate function arguments in the ca...
bool SelectAddressRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG, MaybeAlign EncodingAlignment=std::nullopt) const
SelectAddressRegReg - Given the specified addressed, check to see if it can be more efficiently repre...
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.
Value * emitStoreConditional(IRBuilderBase &Builder, Value *Val, Value *Addr, AtomicOrdering Ord) const override
Perform a store-conditional operation to Addr.
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.
TargetLowering::AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(const AtomicCmpXchgInst *AI) const override
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
Value * emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder, AtomicCmpXchgInst *CI, Value *AlignedAddr, Value *CmpVal, Value *NewVal, Value *Mask, AtomicOrdering Ord) const override
Perform a masked cmpxchg using a target-specific intrinsic.
ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
bool enableAggressiveFMAFusion(EVT VT) const override
Return true if target always benefits from combining into FMA for a given value type.
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
bool decomposeMulByConstant(LLVMContext &Context, EVT VT, SDValue C) const override
Return true if it is profitable to transform an integer multiplication-by-constant into simpler opera...
void getTgtMemIntrinsic(SmallVectorImpl< IntrinsicInfo > &Infos, const CallBase &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...
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...
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo, const LibcallLoweringInfo *LibcallLowering) const override
createFastISel - This method returns a target-specific FastISel object, or null if the target does no...
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.
Value * emitLoadLinked(IRBuilderBase &Builder, Type *ValueTy, Value *Addr, AtomicOrdering Ord) const override
Perform a load-linked operation on Addr, returning a "Value *" with the corresponding pointee type.