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()) {
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;
4038 MachinePointerInfo(SV), MVT::i8);
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;
4288 RC = &PPC::VRRCRegClass;
4295 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4296 assert(i + 1 < e &&
"No second half of double precision argument");
4301 if (!Subtarget.isLittleEndian())
4303 ArgValue = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64, ArgValueLo,
4308 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4309 if (ValVT == MVT::i1)
4324 ArgOffset += ArgSize - ObjSize;
4342 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4347 unsigned MinReservedArea = CCByValInfo.getStackSize();
4348 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4364 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4365 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4367 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4370 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4373 unsigned NumFPArgRegs = std::size(FPArgRegs);
4382 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4383 NumFPArgRegs * MVT(MVT::f64).getSizeInBits()/8;
4386 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4399 VReg = MF.
addLiveIn(GPArgReg, &PPC::GPRCRegClass);
4414 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4418 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4431 if (!MemOps.
empty())
4442 const SDLoc &dl)
const {
4446 else if (
Flags.isZExt())
4453SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4459 bool isELFv2ABI = Subtarget.isELFv2ABI();
4460 bool isLittleEndian = Subtarget.isLittleEndian();
4463 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4466 "fastcc not supported on varargs functions");
4472 unsigned PtrByteSize = 8;
4473 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4476 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4477 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4480 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4481 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4484 const unsigned Num_GPR_Regs = std::size(GPR);
4486 const unsigned Num_VR_Regs = std::size(VR);
4494 bool HasParameterArea = !isELFv2ABI || isVarArg;
4495 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4496 unsigned NumBytes = LinkageSize;
4497 unsigned AvailableFPRs = Num_FPR_Regs;
4498 unsigned AvailableVRs = Num_VR_Regs;
4499 for (
const ISD::InputArg &In : Ins) {
4500 if (
In.Flags.isNest())
4504 LinkageSize, ParamAreaSize, NumBytes,
4505 AvailableFPRs, AvailableVRs))
4506 HasParameterArea =
true;
4513 unsigned ArgOffset = LinkageSize;
4514 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4517 unsigned CurArgIdx = 0;
4518 for (
unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) {
4520 bool needsLoad =
false;
4521 EVT ObjectVT = Ins[ArgNo].VT;
4522 EVT OrigVT = Ins[ArgNo].ArgVT;
4524 unsigned ArgSize = ObjSize;
4525 ISD::ArgFlagsTy
Flags = Ins[ArgNo].Flags;
4526 if (Ins[ArgNo].isOrigArg()) {
4527 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4528 CurArgIdx = Ins[ArgNo].getOrigArgIndex();
4533 unsigned CurArgOffset;
4535 auto ComputeArgOffset = [&]() {
4539 ArgOffset =
alignTo(ArgOffset, Alignment);
4540 CurArgOffset = ArgOffset;
4547 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4548 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4553 if (
Flags.isByVal()) {
4554 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4560 ObjSize =
Flags.getByValSize();
4561 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4583 if (HasParameterArea ||
4584 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4591 if (ObjSize < PtrByteSize) {
4595 if (!isLittleEndian) {
4601 if (GPR_idx != Num_GPR_Regs) {
4608 MachinePointerInfo(&*FuncArg), ObjType);
4613 ArgOffset += PtrByteSize;
4622 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4623 if (GPR_idx == Num_GPR_Regs)
4634 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4638 MachinePointerInfo(&*FuncArg, j), ObjType);
4642 ArgOffset += ArgSize;
4651 if (
Flags.isNest()) {
4656 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4657 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4665 if (GPR_idx != Num_GPR_Regs) {
4670 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4673 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4679 ArgSize = PtrByteSize;
4690 if (FPR_idx != Num_FPR_Regs) {
4693 if (ObjectVT == MVT::f32)
4695 Subtarget.hasP8Vector()
4696 ? &PPC::VSSRCRegClass
4697 : &PPC::F4RCRegClass);
4700 ? &PPC::VSFRCRegClass
4701 : &PPC::F8RCRegClass);
4716 if (ObjectVT == MVT::f32) {
4717 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4735 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4736 ArgOffset += ArgSize;
4737 if (
Flags.isInConsecutiveRegsLast())
4738 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4752 if (VR_idx != Num_VR_Regs) {
4769 if (ObjSize < ArgSize && !isLittleEndian)
4770 CurArgOffset += ArgSize - ObjSize;
4773 ArgVal = DAG.
getLoad(ObjectVT, dl, Chain, FIN, MachinePointerInfo());
4780 unsigned MinReservedArea;
4781 if (HasParameterArea)
4782 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4784 MinReservedArea = LinkageSize;
4801 int Depth = ArgOffset;
4810 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4811 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4823 if (!MemOps.
empty())
4832 unsigned ParamSize) {
4834 if (!isTailCall)
return 0;
4838 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4840 if (SPDiff < FI->getTailCallSPDelta())
4856 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4915 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
4918 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4930 const unsigned PtrByteSize = 8;
4934 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4935 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4938 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4939 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4942 const unsigned NumGPRs = std::size(GPR);
4943 const unsigned NumFPRs = 13;
4944 const unsigned NumVRs = std::size(VR);
4945 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4947 unsigned NumBytes = LinkageSize;
4948 unsigned AvailableFPRs = NumFPRs;
4949 unsigned AvailableVRs = NumVRs;
4952 if (Param.Flags.isNest())
continue;
4955 LinkageSize, ParamAreaSize, NumBytes,
4956 AvailableFPRs, AvailableVRs))
4967 auto CalleeArgEnd = CB.
arg_end();
4970 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
4971 const Value* CalleeArg = *CalleeArgIter;
4972 const Value* CallerArg = &(*CallerArgIter);
4973 if (CalleeArg == CallerArg)
4999 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
5009bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
5014 bool isCalleeExternalSymbol)
const {
5017 if (
DisableSCO && !TailCallOpt)
return false;
5020 if (isVarArg)
return false;
5027 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5063 if (!Subtarget.isUsingPCRelativeCalls() &&
5068 if (!Subtarget.isUsingPCRelativeCalls() &&
5096bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5109 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5130 if (!
C)
return nullptr;
5132 int Addr =
C->getZExtValue();
5133 if ((Addr & 3) != 0 ||
5139 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5146struct TailCallArgumentInfo {
5151 TailCallArgumentInfo() =
default;
5161 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5162 SDValue Arg = TailCallArgs[i].Arg;
5163 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5164 int FI = TailCallArgs[i].FrameIdx;
5167 Chain, dl, Arg, FIN,
5176 int SPDiff,
const SDLoc &dl) {
5182 int SlotSize = Subtarget.isPPC64() ? 8 : 4;
5183 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5185 NewRetAddrLoc,
true);
5188 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5198 int SPDiff,
unsigned ArgOffset,
5200 int Offset = ArgOffset + SPDiff;
5203 EVT VT = IsPPC64 ? MVT::i64 : MVT::i32;
5205 TailCallArgumentInfo Info;
5207 Info.FrameIdxOp = FIN;
5215SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5220 LROpOut = getReturnAddrFrameIndex(DAG);
5221 LROpOut = DAG.
getLoad(Subtarget.getScalarIntVT(), dl, Chain, LROpOut,
5222 MachinePointerInfo());
5238 Align Alignment = Flags.getNonZeroByValAlign();
5240 Chain, dl, Dst, Src, SizeNode, Alignment, Alignment,
false,
false,
5248 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5272 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5282 if (!MemOpChains2.
empty())
5306SDValue PPCTargetLowering::LowerCallResult(
5314 CCRetInfo.AnalyzeCallResult(
5320 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5321 CCValAssign &VA = RVLocs[i];
5326 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5336 if (!Subtarget.isLittleEndian())
5338 Val = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64,
Lo,
Hi);
5404 bool IsStrictFPCall =
false) {
5406 return PPCISD::TC_RETURN;
5408 unsigned RetOpc = 0;
5419 if (Subtarget.usePointerGlueHelper())
5420 RetOpc = PPCISD::BL_LOAD_TOC;
5426 RetOpc = PPCISD::CALL_NOTOC;
5441 RetOpc = PPCISD::CALL;
5442 if (IsStrictFPCall) {
5446 case PPCISD::BCTRL_LOAD_TOC:
5447 RetOpc = PPCISD::BCTRL_LOAD_TOC_RM;
5450 RetOpc = PPCISD::BCTRL_RM;
5452 case PPCISD::BL_LOAD_TOC:
5453 RetOpc = PPCISD::BL_LOAD_TOC_RM;
5455 case PPCISD::CALL_NOTOC:
5456 RetOpc = PPCISD::CALL_NOTOC_RM;
5459 RetOpc = PPCISD::CALL_RM;
5461 case PPCISD::CALL_NOP:
5462 RetOpc = PPCISD::CALL_NOP_RM;
5476 auto isLocalCallee = [&]() {
5492 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5508 return getAIXFuncEntryPointSymbolSDNode(GV);
5515 const char *SymName = S->getSymbol();
5522 return getAIXFuncEntryPointSymbolSDNode(
F);
5528 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5536 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5543 assert(Callee.getNode() &&
"What no callee?");
5549 "Expected a CALLSEQ_STARTSDNode.");
5566 SDValue MTCTROps[] = {Chain, Callee, Glue};
5567 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5568 Chain = DAG.
getNode(PPCISD::MTCTR, dl, ReturnTypes,
5608 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5627 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5628 Alignment, MMOFlags);
5635 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5642 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5654 "Nest parameter is not supported on AIX.");
5669 const SDLoc &dl,
bool hasNest,
5679 Chain = MoveToPhysicalReg.
getValue(0);
5680 Glue = MoveToPhysicalReg.
getValue(1);
5687 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5690 const bool IsPPC64 = Subtarget.isPPC64();
5695 Ops.push_back(Chain);
5699 Ops.push_back(Callee);
5700 else if (Subtarget.usePointerGlueHelper()) {
5701 Ops.push_back(Callee);
5724 Ops.push_back(AddTOC);
5735 Ops.push_back(DAG.
getRegister(IsPPC64 ? PPC::CTR8 : PPC::CTR, RegVT));
5744 for (
const auto &[
Reg,
N] : RegsToPass)
5762 assert(Mask &&
"Missing call preserved mask for calling convention");
5767 Ops.push_back(Glue);
5770SDValue PPCTargetLowering::FinishCall(
5777 if ((Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls()) ||
5778 Subtarget.isAIXABI())
5785 if (!CFlags.IsIndirect)
5787 else if (Subtarget.usesFunctionDescriptors()) {
5788 if (Subtarget.usePointerGlueHelper()) {
5790 CFlags.HasNest, Subtarget);
5796 dl, CFlags.HasNest, Subtarget);
5808 if (CFlags.IsTailCall) {
5816 (CFlags.IsIndirect && Subtarget.isUsingPCRelativeCalls())) &&
5817 "Expecting a global address, external symbol, absolute value, "
5818 "register or an indirect tail call when PC Relative calls are "
5821 assert(CallOpc == PPCISD::TC_RETURN &&
5822 "Unexpected call opcode for a tail call.");
5829 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5830 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes,
Ops);
5842 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5845 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5865 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5866 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5870bool PPCTargetLowering::isEligibleForTCO(
5875 bool isCalleeExternalSymbol)
const {
5879 if (Subtarget.
isSVR4ABI() && Subtarget.isPPC64())
5880 return IsEligibleForTailCallOptimization_64SVR4(
5881 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5882 isCalleeExternalSymbol);
5884 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5912 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5927 "Callee should be an llvm::Function object.");
5930 <<
"\nTCO callee: ");
5937 "site marked musttail");
5944 Callee = LowerGlobalAddress(Callee, DAG);
5947 CallConv, isTailCall, isVarArg, isPatchPoint,
5950 Subtarget.is64BitELFABI() &&
5954 if (Subtarget.isAIXABI())
5955 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5958 assert(Subtarget.isSVR4ABI());
5959 if (Subtarget.isPPC64())
5960 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5962 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5966SDValue PPCTargetLowering::LowerCall_32SVR4(
5977 const bool IsVarArg = CFlags.IsVarArg;
5978 const bool IsTailCall = CFlags.IsTailCall;
5984 const Align PtrAlign(4);
5995 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
6003 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.
getContext());
6006 CCInfo.AllocateStack(Subtarget.getFrameLowering()->getLinkageSize(),
6013 unsigned NumArgs = Outs.
size();
6015 for (
unsigned i = 0; i != NumArgs; ++i) {
6016 MVT ArgVT = Outs[i].VT;
6017 ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
6022 Outs[i].OrigTy, CCInfo);
6025 ArgFlags, Outs[i].OrigTy, CCInfo);
6030 errs() <<
"Call operand #" << i <<
" has unhandled type "
6043 CCState CCByValInfo(CallConv, IsVarArg, MF, ByValArgLocs, *DAG.
getContext());
6046 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
6053 unsigned NumBytes = CCByValInfo.getStackSize();
6067 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6078 bool seenFloatArg =
false;
6083 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
6085 ++i, ++RealArgIdx) {
6086 CCValAssign &VA = ArgLocs[i];
6087 SDValue Arg = OutVals[RealArgIdx];
6088 ISD::ArgFlagsTy
Flags = Outs[RealArgIdx].Flags;
6090 if (
Flags.isByVal()) {
6095 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
6096 CCValAssign &ByValVA = ByValArgLocs[
j++];
6118 Chain = CallSeqStart = NewCallSeqStart;
6137 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6138 bool IsLE = Subtarget.isLittleEndian();
6139 SDValue SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6142 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6144 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6159 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()));
6168 if (!MemOpChains.
empty())
6174 for (
const auto &[
Reg,
N] : RegsToPass) {
6182 SDVTList VTs = DAG.
getVTList(MVT::Other, MVT::Glue);
6185 Chain = DAG.
getNode(seenFloatArg ? PPCISD::CR6SET : PPCISD::CR6UNSET, dl,
6195 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6196 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6201SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6213 return NewCallSeqStart;
6216SDValue PPCTargetLowering::LowerCall_64SVR4(
6223 bool isELFv2ABI = Subtarget.isELFv2ABI();
6224 bool isLittleEndian = Subtarget.isLittleEndian();
6226 bool IsSibCall =
false;
6230 unsigned PtrByteSize = 8;
6243 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
6245 assert(!(IsFastCall && CFlags.IsVarArg) &&
6246 "fastcc not supported on varargs functions");
6252 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
6253 unsigned NumBytes = LinkageSize;
6254 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6257 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6258 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6261 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6262 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6265 const unsigned NumGPRs = std::size(GPR);
6267 const unsigned NumVRs = std::size(VR);
6273 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6274 if (!HasParameterArea) {
6275 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6276 unsigned AvailableFPRs = NumFPRs;
6277 unsigned AvailableVRs = NumVRs;
6278 unsigned NumBytesTmp = NumBytes;
6279 for (
unsigned i = 0; i !=
NumOps; ++i) {
6280 if (Outs[i].
Flags.isNest())
continue;
6282 PtrByteSize, LinkageSize, ParamAreaSize,
6283 NumBytesTmp, AvailableFPRs, AvailableVRs))
6284 HasParameterArea =
true;
6290 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6295 HasParameterArea =
false;
6298 for (
unsigned i = 0; i !=
NumOps; ++i) {
6299 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6300 EVT ArgVT = Outs[i].VT;
6301 EVT OrigVT = Outs[i].ArgVT;
6307 if (
Flags.isByVal()) {
6308 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6309 if (NumGPRsUsed > NumGPRs)
6310 HasParameterArea =
true;
6317 if (++NumGPRsUsed <= NumGPRs)
6327 if (++NumVRsUsed <= NumVRs)
6331 if (++NumVRsUsed <= NumVRs)
6336 if (++NumFPRsUsed <= NumFPRs)
6340 HasParameterArea =
true;
6347 NumBytes =
alignTo(NumBytes, Alignement);
6350 if (
Flags.isInConsecutiveRegsLast())
6351 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6354 unsigned NumBytesActuallyUsed = NumBytes;
6364 if (HasParameterArea)
6365 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6367 NumBytes = LinkageSize;
6382 if (CFlags.IsTailCall)
6394 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6405 unsigned ArgOffset = LinkageSize;
6411 for (
unsigned i = 0; i !=
NumOps; ++i) {
6413 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6414 EVT ArgVT = Outs[i].VT;
6415 EVT OrigVT = Outs[i].ArgVT;
6424 auto ComputePtrOff = [&]() {
6428 ArgOffset =
alignTo(ArgOffset, Alignment);
6439 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6440 GPR_idx = std::min(GPR_idx, NumGPRs);
6447 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6453 if (
Flags.isByVal()) {
6471 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6472 if (GPR_idx != NumGPRs) {
6474 MachinePointerInfo(), VT);
6478 ArgOffset += PtrByteSize;
6483 if (GPR_idx == NumGPRs &&
Size < 8) {
6485 if (!isLittleEndian) {
6490 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6493 ArgOffset += PtrByteSize;
6502 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6503 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6508 if (
Size < 8 && GPR_idx != NumGPRs) {
6518 if (!isLittleEndian) {
6522 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6528 DAG.
getLoad(PtrVT, dl, Chain, PtrOff, MachinePointerInfo());
6533 ArgOffset += PtrByteSize;
6539 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6542 if (GPR_idx != NumGPRs) {
6543 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6546 MachinePointerInfo(), ObjType);
6550 ArgOffset += PtrByteSize;
6552 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6564 if (
Flags.isNest()) {
6566 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6573 if (GPR_idx != NumGPRs) {
6574 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6579 assert(HasParameterArea &&
6580 "Parameter area must exist to pass an argument in memory.");
6582 true, CFlags.IsTailCall,
false, MemOpChains,
6583 TailCallArguments, dl);
6585 ArgOffset += PtrByteSize;
6588 ArgOffset += PtrByteSize;
6601 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6602 bool NeededLoad =
false;
6605 if (FPR_idx != NumFPRs)
6606 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6609 if (!NeedGPROrStack)
6611 else if (GPR_idx != NumGPRs && !IsFastCall) {
6625 }
else if (!
Flags.isInConsecutiveRegs()) {
6631 }
else if (ArgOffset % PtrByteSize != 0) {
6635 if (!isLittleEndian)
6640 }
else if (
Flags.isInConsecutiveRegsLast()) {
6643 if (!isLittleEndian)
6653 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6661 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6666 assert(HasParameterArea &&
6667 "Parameter area must exist to pass an argument in memory.");
6669 true, CFlags.IsTailCall,
false, MemOpChains,
6670 TailCallArguments, dl);
6677 if (!IsFastCall || NeededLoad) {
6679 Flags.isInConsecutiveRegs()) ? 4 : 8;
6680 if (
Flags.isInConsecutiveRegsLast())
6681 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6701 if (CFlags.IsVarArg) {
6702 assert(HasParameterArea &&
6703 "Parameter area must exist if we have a varargs call.");
6707 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
6709 if (VR_idx != NumVRs) {
6711 DAG.
getLoad(MVT::v4f32, dl,
Store, PtrOff, MachinePointerInfo());
6716 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6717 if (GPR_idx == NumGPRs)
6722 DAG.
getLoad(PtrVT, dl,
Store, Ix, MachinePointerInfo());
6730 if (VR_idx != NumVRs) {
6731 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6736 assert(HasParameterArea &&
6737 "Parameter area must exist to pass an argument in memory.");
6739 true, CFlags.IsTailCall,
true, MemOpChains,
6740 TailCallArguments, dl);
6751 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6752 "mismatch in size of parameter area");
6753 (void)NumBytesActuallyUsed;
6755 if (!MemOpChains.
empty())
6761 if (CFlags.IsIndirect) {
6765 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6770 unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
6780 if (isELFv2ABI && !CFlags.IsPatchPoint)
6781 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6787 for (
const auto &[
Reg,
N] : RegsToPass) {
6792 if (CFlags.IsTailCall && !IsSibCall)
6796 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6797 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6804 "Required alignment greater than stack alignment.");
6824 return RequiredAlign <= 8;
6829 return RequiredAlign <= 4;
6837 State.getMachineFunction().getSubtarget());
6838 const bool IsPPC64 = Subtarget.isPPC64();
6839 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6840 const Align PtrAlign(PtrSize);
6841 const Align StackAlign(16);
6844 if (ValVT == MVT::f128)
6848 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6849 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6851 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6852 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6855 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6856 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6857 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6862 MCRegister EnvReg = State.AllocateReg(IsPPC64 ? PPC::X11 : PPC::R11);
6871 if (ByValAlign > StackAlign)
6873 "16 are not supported.");
6876 const Align ObjAlign = ByValAlign > PtrAlign ? ByValAlign : PtrAlign;
6880 if (ByValSize == 0) {
6882 State.getStackSize(), RegVT, LocInfo));
6887 unsigned NextReg = State.getFirstUnallocated(GPRs);
6888 while (NextReg != GPRs.
size() &&
6893 State.AllocateStack(PtrSize, PtrAlign);
6894 assert(
Reg &&
"Alocating register unexpectedly failed.");
6896 NextReg = State.getFirstUnallocated(GPRs);
6899 const unsigned StackSize =
alignTo(ByValSize, ObjAlign);
6900 unsigned Offset = State.AllocateStack(StackSize, ObjAlign);
6920 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6924 const unsigned Offset = State.AllocateStack(PtrSize, PtrAlign);
6943 State.AllocateStack(IsPPC64 ? 8 : StoreSize,
Align(4));
6949 for (
unsigned I = 0;
I < StoreSize;
I += PtrSize) {
6951 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
6952 if (State.isVarArg()) {
6984 const unsigned VecSize = 16;
6985 const Align VecAlign(VecSize);
6987 if (!State.isVarArg()) {
6990 if (
MCRegister VReg = State.AllocateReg(VR)) {
6997 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7002 unsigned NextRegIndex = State.getFirstUnallocated(GPRs);
7005 while (NextRegIndex != GPRs.
size() &&
7009 State.AllocateStack(PtrSize, PtrAlign);
7010 assert(
Reg &&
"Allocating register unexpectedly failed.");
7012 NextRegIndex = State.getFirstUnallocated(GPRs);
7020 if (
MCRegister VReg = State.AllocateReg(VR)) {
7023 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
7024 State.AllocateReg(GPRs);
7025 State.AllocateStack(VecSize, VecAlign);
7029 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7035 if (NextRegIndex == GPRs.
size()) {
7036 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7044 if (GPRs[NextRegIndex] == PPC::R9) {
7045 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7049 const MCRegister FirstReg = State.AllocateReg(PPC::R9);
7050 const MCRegister SecondReg = State.AllocateReg(PPC::R10);
7051 assert(FirstReg && SecondReg &&
7052 "Allocating R9 or R10 unexpectedly failed.");
7063 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7066 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
7068 assert(
Reg &&
"Failed to allocated register for vararg vector argument");
7083 assert((IsPPC64 || SVT != MVT::i64) &&
7084 "i64 should have been split for 32-bit codegen.");
7092 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7094 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
7096 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
7104 return &PPC::VRRCRegClass;
7117 else if (Flags.isZExt())
7129 "Reg must be a valid argument register!");
7130 return LASize + 4 * (
Reg - PPC::R3);
7135 "Reg must be a valid argument register!");
7136 return LASize + 8 * (
Reg - PPC::X3);
7182SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7189 "Unexpected calling convention!");
7197 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7199 const bool IsPPC64 = Subtarget.isPPC64();
7200 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7206 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
7207 CCState CCInfo(CallConv, isVarArg, MF, ArgLocs, *DAG.
getContext());
7211 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7212 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7213 uint64_t SaveStackPos = CCInfo.getStackSize();
7215 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7219 for (
size_t I = 0, End = ArgLocs.
size();
I != End; ) {
7220 CCValAssign &VA = ArgLocs[
I++];
7225 EVT ArgVT = Ins[VA.
getValNo()].ArgVT;
7226 bool ArgSignExt = Ins[VA.
getValNo()].Flags.isSExt();
7238 LocVT.
SimpleTy, IsPPC64, Subtarget.hasP8Vector(), Subtarget.hasVSX());
7240 MVT SaveVT = RegClass == &PPC::G8RCRegClass ? MVT::i64 : LocVT;
7246 MachinePointerInfo(),
Align(PtrByteSize));
7252 unsigned StoreSize =
7254 SaveStackPos =
alignTo(SaveStackPos + StoreSize, PtrByteSize);
7257 auto HandleMemLoc = [&]() {
7260 assert((ValSize <= LocSize) &&
7261 "Object size is larger than size of MemLoc");
7264 if (LocSize > ValSize)
7265 CurArgOffset += LocSize - ValSize;
7267 const bool IsImmutable =
7273 DAG.
getLoad(ValVT, dl, Chain, FIN, MachinePointerInfo());
7307 assert(isVarArg &&
"Only use custom memloc for vararg.");
7310 const unsigned OriginalValNo = VA.
getValNo();
7311 (void)OriginalValNo;
7313 auto HandleCustomVecRegLoc = [&]() {
7314 assert(
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7315 "Missing custom RegLoc.");
7318 "Unexpected Val type for custom RegLoc.");
7320 "ValNo mismatch between custom MemLoc and RegLoc.");
7324 Subtarget.hasVSX()));
7331 HandleCustomVecRegLoc();
7332 HandleCustomVecRegLoc();
7336 if (
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7338 "Only 2 custom RegLocs expected for 64-bit codegen.");
7339 HandleCustomVecRegLoc();
7340 HandleCustomVecRegLoc();
7384 const unsigned Size =
7396 if (
Flags.isByVal()) {
7400 const PPCFrameLowering *FL = Subtarget.getFrameLowering();
7402 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7411 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7413 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7426 CopyFrom.
getValue(1), dl, CopyFrom,
7436 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7439 "RegLocs should be for ByVal argument.");
7441 const CCValAssign RL = ArgLocs[
I++];
7446 if (
Offset != StackSize) {
7448 "Expected MemLoc for remaining bytes.");
7449 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7463 Subtarget.hasVSX()));
7480 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7482 unsigned CallerReservedArea = std::max<unsigned>(
7483 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7489 CallerReservedArea =
7494 int VAListIndex = 0;
7498 if (CCInfo.getStackSize() < (LinkageSize + MinParameterSaveArea)) {
7499 unsigned FixedStackSize =
7500 LinkageSize + MinParameterSaveArea - CCInfo.getStackSize();
7516 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7517 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7519 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7520 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7521 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7527 GPRIndex = (CCInfo.getStackSize() - LinkageSize) / PtrByteSize,
7529 GPRIndex < NumGPArgRegs; ++GPRIndex,
Offset += PtrByteSize) {
7532 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7533 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7536 MachinePointerInfo MPI =
7546 if (!MemOps.
empty())
7552SDValue PPCTargetLowering::LowerCall_AIX(
7565 "Unexpected calling convention!");
7567 if (CFlags.IsPatchPoint)
7570 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7574 CCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7581 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7582 const bool IsPPC64 = Subtarget.isPPC64();
7584 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7585 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7586 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7594 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7595 const unsigned NumBytes = std::max<unsigned>(
7596 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7612 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E;) {
7613 const unsigned ValNo = ArgLocs[
I].getValNo();
7615 ISD::ArgFlagsTy
Flags = Outs[ValNo].Flags;
7617 if (
Flags.isByVal()) {
7618 const unsigned ByValSize =
Flags.getByValSize();
7626 auto GetLoad = [&](EVT VT,
unsigned LoadOffset) {
7632 MachinePointerInfo(), VT);
7635 unsigned LoadOffset = 0;
7638 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7641 LoadOffset += PtrByteSize;
7642 const CCValAssign &ByValVA = ArgLocs[
I++];
7644 "Unexpected location for pass-by-value argument.");
7648 if (LoadOffset == ByValSize)
7652 assert(ArgLocs[
I].getValNo() == ValNo &&
7653 "Expected additional location for by-value argument.");
7655 if (ArgLocs[
I].isMemLoc()) {
7656 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7657 const CCValAssign &ByValVA = ArgLocs[
I++];
7658 ISD::ArgFlagsTy MemcpyFlags =
Flags;
7661 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7667 CallSeqStart, MemcpyFlags, DAG, dl);
7676 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7677 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7678 "Unexpected register residue for by-value argument.");
7680 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7684 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7694 "Unexpected load emitted during handling of pass-by-value "
7702 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7707 const CCValAssign &ByValVA = ArgLocs[
I++];
7712 CCValAssign &VA = ArgLocs[
I++];
7737 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7743 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
7745 const unsigned OriginalValNo = VA.
getValNo();
7747 unsigned LoadOffset = 0;
7748 auto HandleCustomVecRegLoc = [&]() {
7749 assert(
I !=
E &&
"Unexpected end of CCvalAssigns.");
7750 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7751 "Expected custom RegLoc.");
7752 CCValAssign RegVA = ArgLocs[
I++];
7754 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7760 LoadOffset += PtrByteSize;
7766 HandleCustomVecRegLoc();
7767 HandleCustomVecRegLoc();
7769 if (
I !=
E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7770 ArgLocs[
I].getValNo() == OriginalValNo) {
7772 "Only 2 custom RegLocs expected for 64-bit codegen.");
7773 HandleCustomVecRegLoc();
7774 HandleCustomVecRegLoc();
7785 DAG.
getStore(Chain, dl, Arg, PtrOff,
7787 Subtarget.getFrameLowering()->getStackAlign()));
7794 "Unexpected register handling for calling convention.");
7800 "Custom register handling only expected for VarArg.");
7805 if (Arg.getValueType().getStoreSize() == LocVT.
getStoreSize())
7809 else if (Arg.getValueType().getFixedSizeInBits() <
7817 assert(Arg.getValueType() == MVT::f64 && CFlags.IsVarArg && !IsPPC64 &&
7818 "Unexpected custom register for argument!");
7819 CCValAssign &GPR1 = VA;
7828 CCValAssign &PeekArg = ArgLocs[
I];
7831 CCValAssign &GPR2 = ArgLocs[
I++];
7839 if (!MemOpChains.
empty())
7844 if (CFlags.IsIndirect && !Subtarget.usePointerGlueHelper()) {
7845 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7846 const MCRegister TOCBaseReg = Subtarget.getTOCPointerRegister();
7847 const MCRegister StackPtrReg = Subtarget.getStackPointerRegister();
7848 const MVT PtrVT = Subtarget.getScalarIntVT();
7849 const unsigned TOCSaveOffset =
7850 Subtarget.getFrameLowering()->getTOCSaveOffset();
7865 for (
auto Reg : RegsToPass) {
7870 const int SPDiff = 0;
7871 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7872 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7880 const Type *RetTy)
const {
7882 CCState CCInfo(CallConv, isVarArg, MF, RVLocs,
Context);
7883 return CCInfo.CheckReturn(
7898 CCInfo.AnalyzeReturn(Outs,
7907 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7908 CCValAssign &VA = RVLocs[i];
7911 SDValue Arg = OutVals[RealResIdx];
7926 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7927 bool isLittleEndian = Subtarget.isLittleEndian();
7930 DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7934 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7949 RetOps.push_back(Glue);
7951 return DAG.
getNode(PPCISD::RET_GLUE, dl, MVT::Other, RetOps);
7955PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7960 EVT IntVT =
Op.getValueType();
7964 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7968 return DAG.
getNode(PPCISD::DYNAREAOFFSET, dl, VTs,
Ops);
7980 bool isPPC64 = Subtarget.isPPC64();
7981 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7990 DAG.
getLoad(PtrVT, dl, Chain, StackPtr, MachinePointerInfo());
7996 return DAG.
getStore(Chain, dl, LoadLinkSP, StackPtr, MachinePointerInfo());
8001 bool isPPC64 = Subtarget.isPPC64();
8006 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
8012 int LROffset = Subtarget.getFrameLowering()->getReturnSaveOffset();
8022PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
8024 bool isPPC64 = Subtarget.isPPC64();
8029 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
8035 int FPOffset = Subtarget.getFrameLowering()->getFramePointerSaveOffset();
8058 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
8060 SDVTList VTs = DAG.
getVTList(PtrVT, MVT::Other);
8062 return DAG.
getNode(PPCISD::PROBED_ALLOCA, dl, VTs,
Ops);
8063 return DAG.
getNode(PPCISD::DYNALLOC, dl, VTs,
Ops);
8070 bool isPPC64 = Subtarget.isPPC64();
8080 return DAG.
getNode(PPCISD::EH_SJLJ_SETJMP,
DL,
8082 Op.getOperand(0),
Op.getOperand(1));
8088 return DAG.
getNode(PPCISD::EH_SJLJ_LONGJMP,
DL, MVT::Other,
8089 Op.getOperand(0),
Op.getOperand(1));
8093 if (
Op.getValueType().isVector())
8094 return LowerVectorLoad(
Op, DAG);
8096 assert(
Op.getValueType() == MVT::i1 &&
8097 "Custom lowering only for i1 loads");
8106 MachineMemOperand *MMO =
LD->getMemOperand();
8110 BasePtr, MVT::i8, MMO);
8118 if (
Op.getOperand(1).getValueType().isVector())
8119 return LowerVectorStore(
Op, DAG);
8121 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
8122 "Custom lowering only for i1 stores");
8132 MachineMemOperand *MMO =
ST->getMemOperand();
8141 assert(
Op.getValueType() == MVT::i1 &&
8142 "Custom lowering only for i1 results");
8170 EVT TrgVT =
Op.getValueType();
8194 if (SrcSize == 256) {
8205 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8211 SmallVector<int, 16> ShuffV;
8212 if (Subtarget.isLittleEndian())
8213 for (
unsigned i = 0; i < TrgNumElts; ++i)
8216 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8220 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8233 EVT ResVT =
Op.getValueType();
8234 EVT CmpVT =
Op.getOperand(0).getValueType();
8236 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8242 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8255 SDNodeFlags
Flags =
Op.getNode()->getFlags();
8259 if (Subtarget.hasP9Vector() &&
LHS == TV &&
RHS == FV) {
8276 if (!
Flags.hasNoInfs() || !
Flags.hasNoNaNs() || ResVT == MVT::f128)
8289 if (
LHS.getValueType() == MVT::f32)
8291 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8294 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8302 if (
LHS.getValueType() == MVT::f32)
8304 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8311 if (
LHS.getValueType() == MVT::f32)
8313 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8325 if (
Cmp.getValueType() == MVT::f32)
8327 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8330 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8335 if (
Cmp.getValueType() == MVT::f32)
8337 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8341 if (
Cmp.getValueType() == MVT::f32)
8343 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8347 if (
Cmp.getValueType() == MVT::f32)
8349 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8353 if (
Cmp.getValueType() == MVT::f32)
8355 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8364 case PPCISD::FCTIDZ:
8365 return PPCISD::STRICT_FCTIDZ;
8366 case PPCISD::FCTIWZ:
8367 return PPCISD::STRICT_FCTIWZ;
8368 case PPCISD::FCTIDUZ:
8369 return PPCISD::STRICT_FCTIDUZ;
8370 case PPCISD::FCTIWUZ:
8371 return PPCISD::STRICT_FCTIWUZ;
8373 return PPCISD::STRICT_FCFID;
8374 case PPCISD::FCFIDU:
8375 return PPCISD::STRICT_FCFIDU;
8376 case PPCISD::FCFIDS:
8377 return PPCISD::STRICT_FCFIDS;
8378 case PPCISD::FCFIDUS:
8379 return PPCISD::STRICT_FCFIDUS;
8386 bool IsStrict =
Op->isStrictFPOpcode();
8395 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8397 MVT DestTy =
Op.getSimpleValueType();
8398 assert(Src.getValueType().isFloatingPoint() &&
8399 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8400 DestTy == MVT::i64) &&
8401 "Invalid FP_TO_INT types");
8402 if (Src.getValueType() == MVT::f32) {
8406 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8411 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8417 Opc = IsSigned ? PPCISD::FCTIWZ
8418 : (Subtarget.hasFPCVT() ? PPCISD::FCTIWUZ : PPCISD::FCTIDZ);
8421 assert((IsSigned || Subtarget.hasFPCVT()) &&
8422 "i64 FP_TO_UINT is supported only with FPCVT");
8423 Opc = IsSigned ? PPCISD::FCTIDZ : PPCISD::FCTIDUZ;
8425 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8437void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8439 const SDLoc &dl)
const {
8443 bool IsStrict =
Op->isStrictFPOpcode();
8446 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8447 (IsSigned || Subtarget.hasFPCVT());
8450 MachinePointerInfo MPI =
8459 MachineMemOperand *MMO =
8465 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8469 if (
Op.getValueType() == MVT::i32 && !i32Stack &&
8470 !Subtarget.isLittleEndian()) {
8487 const SDLoc &dl)
const {
8490 if (
Op->isStrictFPOpcode())
8497 const SDLoc &dl)
const {
8498 bool IsStrict =
Op->isStrictFPOpcode();
8501 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8502 EVT SrcVT = Src.getValueType();
8503 EVT DstVT =
Op.getValueType();
8506 if (SrcVT == MVT::f128)
8507 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8511 if (SrcVT == MVT::ppcf128) {
8512 if (DstVT == MVT::i32) {
8517 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8528 {Op.getOperand(0), Lo, Hi}, Flags);
8531 {Res.getValue(1), Res}, Flags);
8537 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8561 {Chain, Src, FltOfs}, Flags);
8565 {Chain, Val}, Flags);
8568 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8586 if (Subtarget.hasDirectMove() && Subtarget.isPPC64())
8587 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8590 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8592 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8593 RLI.Alignment, RLI.MMOFlags(),
8594 MMOMetadata(RLI.AAInfo, RLI.Ranges));
8605bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8610 if (
Op->isStrictFPOpcode())
8615 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8619 Op.getOperand(0).getValueType())) {
8621 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8626 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8627 LD->isNonTemporal())
8629 if (
LD->getMemoryVT() != MemVT)
8639 RLI.Ptr =
LD->getBasePtr();
8640 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8642 "Non-pre-inc AM on PPC?");
8647 RLI.Chain =
LD->getChain();
8648 RLI.MPI =
LD->getPointerInfo();
8649 RLI.IsDereferenceable =
LD->isDereferenceable();
8650 RLI.IsInvariant =
LD->isInvariant();
8651 RLI.Alignment =
LD->getAlign();
8652 RLI.AAInfo =
LD->getAAInfo();
8653 RLI.Ranges =
LD->getRanges();
8655 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8662bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8663 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8670 if (!Subtarget.hasP9Vector() &&
8674 for (SDUse &Use : Origin->
uses()) {
8677 if (
Use.getResNo() != 0)
8704 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8705 unsigned ConvOpc = IsSingle ? (IsSigned ? PPCISD::FCFIDS : PPCISD::FCFIDUS)
8706 : (IsSigned ? PPCISD::FCFID : PPCISD::FCFIDU);
8707 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8708 if (
Op->isStrictFPOpcode()) {
8710 Chain =
Op.getOperand(0);
8712 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8714 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8722 const SDLoc &dl)
const {
8723 assert((
Op.getValueType() == MVT::f32 ||
8724 Op.getValueType() == MVT::f64) &&
8725 "Invalid floating point type as target of conversion");
8726 assert(Subtarget.hasFPCVT() &&
8727 "Int to FP conversions with direct moves require FPCVT");
8728 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8729 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8732 unsigned MovOpc = (WordInt && !
Signed) ? PPCISD::MTVSRZ : PPCISD::MTVSRA;
8751 for (
unsigned i = 1; i < NumConcat; ++i)
8758 const SDLoc &dl)
const {
8759 bool IsStrict =
Op->isStrictFPOpcode();
8760 unsigned Opc =
Op.getOpcode();
8761 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8764 "Unexpected conversion type");
8765 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8766 "Supports conversions to v2f64/v4f32 only.");
8770 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8773 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8778 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8780 SmallVector<int, 16> ShuffV;
8781 for (
unsigned i = 0; i < WideNumElts; ++i)
8784 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8785 int SaveElts = FourEltRes ? 4 : 2;
8786 if (Subtarget.isLittleEndian())
8787 for (
int i = 0; i < SaveElts; i++)
8788 ShuffV[i * Stride] = i;
8790 for (
int i = 1; i <= SaveElts; i++)
8791 ShuffV[i * Stride - 1] = i - 1;
8799 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8800 EVT ExtVT = Src.getValueType();
8801 if (Subtarget.hasP9Altivec())
8812 {Op.getOperand(0), Extend}, Flags);
8814 return DAG.
getNode(
Opc, dl,
Op.getValueType(), Extend);
8822 bool IsStrict =
Op->isStrictFPOpcode();
8823 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8828 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8830 EVT InVT = Src.getValueType();
8831 EVT OutVT =
Op.getValueType();
8834 return LowerINT_TO_FPVector(
Op, DAG, dl);
8837 if (
Op.getValueType() == MVT::f128)
8838 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8841 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8844 if (Src.getValueType() == MVT::i1) {
8856 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8857 Subtarget.isPPC64() && Subtarget.hasFPCVT())
8858 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8860 assert((IsSigned || Subtarget.hasFPCVT()) &&
8861 "UINT_TO_FP is supported only with FPCVT");
8863 if (Src.getValueType() == MVT::i64) {
8878 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT() &&
8879 !
Op->getFlags().hasApproximateFuncs()) {
8919 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8923 DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI, RLI.Alignment,
8924 RLI.MMOFlags(), MMOMetadata(RLI.AAInfo));
8927 }
else if (Subtarget.hasLFIWAX() &&
8928 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8931 MMOMetadata(RLI.AAInfo, RLI.Ranges));
8935 Ops, MVT::i32, MMO);
8938 }
else if (Subtarget.hasFPCVT() &&
8939 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8942 MMOMetadata(RLI.AAInfo, RLI.Ranges));
8946 Ops, MVT::i32, MMO);
8949 }
else if (((Subtarget.hasLFIWAX() &&
8951 (Subtarget.hasFPCVT() &&
8966 "Expected an i32 store");
8972 RLI.Alignment =
Align(4);
8976 MMOMetadata(RLI.AAInfo, RLI.Ranges));
8979 PPCISD::LFIWZX : PPCISD::LFIWAX,
8980 dl, DAG.
getVTList(MVT::f64, MVT::Other),
8981 Ops, MVT::i32, MMO);
8982 Chain =
Bits.getValue(1);
8990 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8994 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)},
9003 assert(Src.getValueType() == MVT::i32 &&
9004 "Unhandled INT_TO_FP type in custom expander!");
9014 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
9017 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
9027 "Expected an i32 store");
9033 RLI.Alignment =
Align(4);
9038 MMOMetadata(RLI.AAInfo, RLI.Ranges));
9043 Chain = Ld.getValue(1);
9044 if (ReusingLoad && RLI.ResChain) {
9048 assert(Subtarget.isPPC64() &&
9049 "i32->FP without LFIWAX supported only on PPC64");
9058 Chain, dl, Ext64, FIdx,
9064 MVT::f64, dl, Chain, FIdx,
9066 Chain = Ld.getValue(1);
9073 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
9077 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)}, Flags);
9095 assert(
Mode < 4 &&
"Unsupported rounding mode!");
9096 unsigned InternalRnd =
Mode ^ (~(
Mode >> 1) & 1);
9097 if (Subtarget.isISA3_0())
9100 PPC::MFFSCRNI, Dl, {MVT::f64, MVT::Other},
9101 {DAG.getConstant(InternalRnd, Dl, MVT::i32, true), Chain}),
9104 (InternalRnd & 2) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9105 {DAG.
getConstant(30, Dl, MVT::i32,
true), Chain});
9107 (InternalRnd & 1) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9125 if (!Subtarget.isISA3_0()) {
9126 MFFS = DAG.
getNode(PPCISD::MFFS, Dl, {MVT::f64, MVT::Other}, Chain);
9130 if (Subtarget.isPPC64()) {
9131 if (Subtarget.isISA3_0()) {
9136 PPC::RLDIMI, Dl, MVT::i64,
9141 NewFPSCR =
SDValue(InsertRN, 0);
9148 SDValue Addr = Subtarget.isLittleEndian()
9152 if (Subtarget.isISA3_0()) {
9153 Chain = DAG.
getStore(Chain, Dl, DstFlag, Addr, MachinePointerInfo());
9155 Chain = DAG.
getStore(Chain, Dl, MFFS, StackSlot, MachinePointerInfo());
9157 DAG.
getLoad(MVT::i32, Dl, Chain, Addr, MachinePointerInfo());
9160 PPC::RLWIMI, Dl, MVT::i32,
9161 {Tmp, DstFlag, DAG.getTargetConstant(0, Dl, MVT::i32),
9162 DAG.getTargetConstant(30, Dl, MVT::i32),
9163 DAG.getTargetConstant(31, Dl, MVT::i32)}),
9165 Chain = DAG.
getStore(Chain, Dl, Tmp, Addr, MachinePointerInfo());
9168 DAG.
getLoad(MVT::f64, Dl, Chain, StackSlot, MachinePointerInfo());
9171 if (Subtarget.isISA3_0())
9177 PPC::MTFSF, Dl, MVT::Other,
9205 EVT VT =
Op.getValueType();
9210 SDValue MFFS = DAG.
getNode(PPCISD::MFFS, dl, {MVT::f64, MVT::Other}, Chain);
9221 Chain = DAG.
getStore(Chain, dl, MFFS, StackSlot, MachinePointerInfo());
9225 "Stack slot adjustment is valid only on big endian subtargets!");
9228 CWD = DAG.
getLoad(MVT::i32, dl, Chain, Addr, MachinePointerInfo());
9255 EVT VT =
Op.getValueType();
9259 VT ==
Op.getOperand(1).getValueType() &&
9279 SDValue OutOps[] = { OutLo, OutHi };
9284 EVT VT =
Op.getValueType();
9288 VT ==
Op.getOperand(1).getValueType() &&
9308 SDValue OutOps[] = { OutLo, OutHi };
9314 EVT VT =
Op.getValueType();
9317 VT ==
Op.getOperand(1).getValueType() &&
9337 SDValue OutOps[] = { OutLo, OutHi };
9344 EVT VT =
Op.getValueType();
9351 EVT AmtVT =
Z.getValueType();
9361 X = DAG.
getNode(PPCISD::SHL, dl, VT,
X, IsFSHL ? Z : SubZ);
9362 Y = DAG.
getNode(PPCISD::SRL, dl, VT,
Y, IsFSHL ? SubZ : Z);
9374 static const MVT VTys[] = {
9375 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9378 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9381 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9386 EVT CanonicalVT = VTys[SplatSize-1];
9399 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9400 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9409 EVT DestVT = MVT::Other) {
9410 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9419 EVT DestVT = MVT::Other) {
9422 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9434 for (
unsigned i = 0; i != 16; ++i)
9455 EVT VecVT = V->getValueType(0);
9456 bool RightType = VecVT == MVT::v2f64 ||
9457 (HasP8Vector && VecVT == MVT::v4f32) ||
9458 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9462 bool IsSplat =
true;
9463 bool IsLoad =
false;
9469 if (V->isConstant())
9471 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9472 if (V->getOperand(i).isUndef())
9476 if (V->getOperand(i).getOpcode() ==
ISD::LOAD ||
9478 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9480 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9482 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD))
9486 if (V->getOperand(i) != Op0 ||
9487 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9490 return !(IsSplat && IsLoad);
9500 (
Op.getValueType() != MVT::f128))
9505 if ((
Lo.getValueType() != MVT::i64) || (
Hi.getValueType() != MVT::i64))
9508 if (!Subtarget.isLittleEndian())
9511 return DAG.
getNode(PPCISD::BUILD_FP128, dl, MVT::f128,
Lo,
Hi);
9519 InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED) {
9520 IsPermuted = InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED;
9533 APFloat APFloatToConvert = ArgAPFloat;
9534 bool LosesInfo =
true;
9539 ArgAPFloat = APFloatToConvert;
9561 APFloat APFloatToConvert = ArgAPFloat;
9562 bool LosesInfo =
true;
9566 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9575 EVT Ty =
Op->getValueType(0);
9578 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9587 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9591 if (Ty == MVT::v2i64) {
9594 if (MemVT == MVT::i32) {
9596 Opcode = PPCISD::ZEXT_LD_SPLAT;
9598 Opcode = PPCISD::SEXT_LD_SPLAT;
9606 bool IsLittleEndian) {
9612 APInt ConstValue(VTSize, 0);
9616 unsigned BitPos = 0;
9624 ConstValue.
insertBits(CN->getAPIntValue().zextOrTrunc(EltWidth),
9625 IsLittleEndian ? BitPos : VTSize - EltWidth - BitPos);
9629 for (
unsigned J = 0; J < 16; ++J) {
9631 if (ExtractValue != 0x00 && ExtractValue != 0xFF)
9633 if (ExtractValue == 0xFF)
9648 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9650 if (Subtarget.hasP10Vector()) {
9651 APInt BitMask(32, 0);
9657 BitMask != 0 && BitMask != 0xffff) {
9659 MachineSDNode *MSDNode =
9671 if (
SDValue VecPat = combineBVLoadsSpecialValue(
Op, DAG))
9675 APInt APSplatBits, APSplatUndef;
9676 unsigned SplatBitSize = 0;
9678 bool BVNIsConstantSplat =
9680 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
9686 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9687 Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
9690 if ((
Op->getValueType(0) == MVT::v2f64) &&
9693 PPCISD::XXSPLTI_SP_TO_DP, dl, MVT::v2f64,
9709 PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9715 DAG.
getNode(PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9724 LowerVecSplatSmallFP(
Op, DAG, BVNIsConstantSplat, SplatBitSize))
9727 bool IsSplat64 =
false;
9729 int32_t SextVal = 0;
9730 if (BVNIsConstantSplat && SplatBitSize <= 64) {
9732 if (SplatBitSize <= 32) {
9734 }
else if (SplatBitSize == 64 && Subtarget.hasP8Altivec()) {
9735 int64_t Splat64Val =
static_cast<int64_t
>(SplatBits);
9736 bool P9Vector = Subtarget.hasP9Vector();
9737 int32_t
Hi = P9Vector ? 127 : 15;
9738 int32_t
Lo = P9Vector ? -128 : -16;
9739 IsSplat64 = Splat64Val >=
Lo && Splat64Val <=
Hi;
9740 SextVal =
static_cast<int32_t
>(SplatBits);
9744 if (!BVNIsConstantSplat || (SplatBitSize > 32 && !IsSplat64)) {
9745 unsigned NewOpcode = PPCISD::LD_SPLAT;
9751 const SDValue *InputLoad = &
Op.getOperand(0);
9756 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9757 unsigned ElementSize =
9758 MemorySize * ((NewOpcode == PPCISD::LD_SPLAT) ? 1 : 2);
9760 assert(((ElementSize == 2 * MemorySize)
9761 ? (NewOpcode == PPCISD::ZEXT_LD_SPLAT ||
9762 NewOpcode == PPCISD::SEXT_LD_SPLAT)
9763 : (NewOpcode == PPCISD::LD_SPLAT)) &&
9764 "Unmatched element size and opcode!\n");
9769 unsigned NumUsesOfInputLD = 128 / ElementSize;
9771 if (BVInOp.isUndef())
9786 if (NumUsesOfInputLD == 1 &&
9787 (
Op->getValueType(0) == MVT::v2i64 && NewOpcode != PPCISD::LD_SPLAT &&
9788 !Subtarget.isLittleEndian() && Subtarget.hasVSX() &&
9789 Subtarget.hasLFIWAX()))
9797 if (NumUsesOfInputLD == 1 && Subtarget.isLittleEndian() &&
9798 Subtarget.isISA3_1() && ElementSize <= 16)
9801 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9803 Subtarget.hasVSX()) {
9810 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other),
Ops,
9811 LD->getMemoryVT(),
LD->getMemOperand());
9823 if (Subtarget.hasVSX() && Subtarget.isPPC64() &&
9825 Subtarget.hasP8Vector()))
9831 unsigned SplatSize = SplatBitSize / 8;
9836 if (SplatBits == 0) {
9838 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9850 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 2)
9852 Op.getValueType(), DAG, dl);
9854 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 4)
9859 if (Subtarget.hasP9Vector() && SplatSize == 1)
9865 if (SextVal >= -16 && SextVal <= 15) {
9868 unsigned UseSize = SplatSize == 8 ? 4 : SplatSize;
9875 DAG.
getBitcast(MVT::v4i32, Res), DAG, dl, MVT::v2i64);
9881 if (Subtarget.hasP9Vector() && SextVal >= -128 && SextVal <= 127) {
9887 switch (SplatSize) {
9891 IID = Intrinsic::ppc_altivec_vupklsb;
9895 IID = Intrinsic::ppc_altivec_vextsb2w;
9899 IID = Intrinsic::ppc_altivec_vextsb2d;
9906 assert(!IsSplat64 &&
"Unhandled 64-bit splat pattern");
9915 if (SextVal >= -32 && SextVal <= 31) {
9920 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9921 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9924 if (VT ==
Op.getValueType())
9933 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9947 static const signed char SplatCsts[] = {
9948 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9949 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9952 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9955 int i = SplatCsts[idx];
9959 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9962 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9964 static const unsigned IIDs[] = {
9965 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9966 Intrinsic::ppc_altivec_vslw
9973 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9975 static const unsigned IIDs[] = {
9976 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9977 Intrinsic::ppc_altivec_vsrw
9984 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9985 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9987 static const unsigned IIDs[] = {
9988 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
9989 Intrinsic::ppc_altivec_vrlw
9996 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
9998 unsigned Amt = Subtarget.isLittleEndian() ? 15 : 1;
10002 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
10004 unsigned Amt = Subtarget.isLittleEndian() ? 14 : 2;
10008 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
10010 unsigned Amt = Subtarget.isLittleEndian() ? 13 : 3;
10023 unsigned OpNum = (PFEntry >> 26) & 0x0F;
10024 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
10025 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
10041 if (LHSID == (1*9+2)*9+3)
return LHS;
10042 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
10054 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
10055 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
10056 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
10057 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
10060 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
10061 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
10062 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
10063 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
10066 for (
unsigned i = 0; i != 16; ++i)
10067 ShufIdxs[i] = (i&3)+0;
10070 for (
unsigned i = 0; i != 16; ++i)
10071 ShufIdxs[i] = (i&3)+4;
10074 for (
unsigned i = 0; i != 16; ++i)
10075 ShufIdxs[i] = (i&3)+8;
10078 for (
unsigned i = 0; i != 16; ++i)
10079 ShufIdxs[i] = (i&3)+12;
10100 const unsigned BytesInVector = 16;
10101 bool IsLE = Subtarget.isLittleEndian();
10105 unsigned ShiftElts = 0, InsertAtByte = 0;
10109 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
10110 0, 15, 14, 13, 12, 11, 10, 9};
10111 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
10112 1, 2, 3, 4, 5, 6, 7, 8};
10114 ArrayRef<int>
Mask =
N->getMask();
10115 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
10127 bool FoundCandidate =
false;
10131 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
10134 for (
unsigned i = 0; i < BytesInVector; ++i) {
10135 unsigned CurrentElement =
Mask[i];
10138 if (V2.
isUndef() && CurrentElement != VINSERTBSrcElem)
10141 bool OtherElementsInOrder =
true;
10144 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
10151 (!V2.
isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
10152 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
10153 OtherElementsInOrder =
false;
10160 if (OtherElementsInOrder) {
10167 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
10168 : BigEndianShifts[CurrentElement & 0xF];
10169 Swap = CurrentElement < BytesInVector;
10171 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
10172 FoundCandidate =
true;
10177 if (!FoundCandidate)
10187 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10189 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8,
V1, Shl,
10192 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8,
V1, V2,
10201 const unsigned NumHalfWords = 8;
10202 const unsigned BytesInVector = NumHalfWords * 2;
10207 bool IsLE = Subtarget.isLittleEndian();
10211 unsigned ShiftElts = 0, InsertAtByte = 0;
10215 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
10216 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
10219 uint32_t OriginalOrderLow = 0x1234567;
10220 uint32_t OriginalOrderHigh = 0x89ABCDEF;
10223 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10224 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10241 bool FoundCandidate =
false;
10244 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10245 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10247 uint32_t MaskOtherElts = ~(0xF <<
MaskShift);
10248 uint32_t TargetOrder = 0x0;
10255 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
10256 TargetOrder = OriginalOrderLow;
10260 if (MaskOneElt == VINSERTHSrcElem &&
10261 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10262 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10263 FoundCandidate =
true;
10269 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
10271 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10273 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
10274 : BigEndianShifts[MaskOneElt & 0x7];
10275 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10276 Swap = MaskOneElt < NumHalfWords;
10277 FoundCandidate =
true;
10283 if (!FoundCandidate)
10295 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10298 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
10303 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
10318 auto ShuffleMask = SVN->
getMask();
10333 ShuffleMask = CommutedSV->
getMask();
10342 APInt APSplatValue, APSplatUndef;
10343 unsigned SplatBitSize;
10346 HasAnyUndefs, 0, !Subtarget.isLittleEndian()) ||
10358 bool IsLE = Subtarget.isLittleEndian();
10359 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
10360 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
10361 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
10363 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
10364 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
10365 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
10373 for (; SplatBitSize < 32; SplatBitSize <<= 1)
10374 SplatVal |= (SplatVal << SplatBitSize);
10377 PPCISD::XXSPLTI32DX,
DL, MVT::v2i64, DAG.
getBitcast(MVT::v2i64,
LHS),
10388 assert(
Op.getValueType() == MVT::v1i128 &&
10389 "Only set v1i128 as custom, other type shouldn't reach here!");
10394 if (SHLAmt % 8 == 0) {
10395 std::array<int, 16>
Mask;
10396 std::iota(
Mask.begin(),
Mask.end(), 0);
10397 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10426 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10431 V1 =
Op.getOperand(0);
10432 V2 =
Op.getOperand(1);
10434 EVT VT =
Op.getValueType();
10435 bool isLittleEndian = Subtarget.isLittleEndian();
10437 unsigned ShiftElts, InsertAtByte;
10443 bool IsPermutedLoad =
false;
10445 if (InputLoad && Subtarget.hasVSX() && V2.
isUndef() &&
10455 if (IsPermutedLoad) {
10456 assert((isLittleEndian || IsFourByte) &&
10457 "Unexpected size for permuted load on big endian target");
10458 SplatIdx += IsFourByte ? 2 : 1;
10459 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10460 "Splat of a value outside of the loaded memory");
10465 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10468 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10470 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10474 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10487 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10490 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10499 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10502 if (Subtarget.hasP9Vector() &&
10512 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv2, Conv2,
10514 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Shl,
10518 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Conv2,
10523 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
10525 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10526 return SplatInsertNode;
10529 if (Subtarget.hasP9Altivec()) {
10531 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10534 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10538 if (Subtarget.hasVSX() &&
10546 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv1, Conv2,
10551 if (Subtarget.hasVSX() &&
10559 SDValue PermDI = DAG.
getNode(PPCISD::XXPERMDI, dl, MVT::v2i64, Conv1, Conv2,
10564 if (Subtarget.hasP9Vector()) {
10584 if (Subtarget.hasVSX()) {
10597 SDValue Swap = DAG.
getNode(PPCISD::SWAP_NO_CHAIN, dl, MVT::v2f64, Conv);
10605 if (V2.isUndef()) {
10618 (Subtarget.hasP8Altivec() && (
10629 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10639 (Subtarget.hasP8Altivec() && (
10647 ArrayRef<int> PermMask = SVOp->
getMask();
10650 unsigned PFIndexes[4];
10651 bool isFourElementShuffle =
true;
10652 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10654 unsigned EltNo = 8;
10655 for (
unsigned j = 0;
j != 4; ++
j) {
10656 if (PermMask[i * 4 + j] < 0)
10659 unsigned ByteSource = PermMask[i * 4 +
j];
10660 if ((ByteSource & 3) != j) {
10661 isFourElementShuffle =
false;
10666 EltNo = ByteSource / 4;
10667 }
else if (EltNo != ByteSource / 4) {
10668 isFourElementShuffle =
false;
10672 PFIndexes[i] = EltNo;
10680 if (isFourElementShuffle) {
10682 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10683 PFIndexes[2] * 9 + PFIndexes[3];
10686 unsigned Cost = (PFEntry >> 30);
10706 if (V2.isUndef()) V2 =
V1;
10708 return LowerVPERM(
Op, DAG, PermMask, VT,
V1, V2);
10714 unsigned Opcode = PPCISD::VPERM;
10717 bool NeedSwap =
false;
10718 bool isLittleEndian = Subtarget.isLittleEndian();
10719 bool isPPC64 = Subtarget.isPPC64();
10721 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10723 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10724 "XXPERM instead\n");
10725 Opcode = PPCISD::XXPERM;
10730 if ((!isLittleEndian && !V2->
hasOneUse() &&
V1->hasOneUse()) ||
10731 (isLittleEndian && !
V1->hasOneUse() && V2->
hasOneUse())) {
10733 NeedSwap = !NeedSwap;
10747 bool V1HasXXSWAPD =
V1->getOperand(0)->getOpcode() == PPCISD::XXSWAPD;
10768 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10770 if (V1HasXXSWAPD) {
10773 else if (SrcElt < 16)
10776 if (V2HasXXSWAPD) {
10779 else if (SrcElt > 15)
10788 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10789 if (isLittleEndian)
10791 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10794 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10797 if (V1HasXXSWAPD) {
10798 dl = SDLoc(
V1->getOperand(0));
10799 V1 =
V1->getOperand(0)->getOperand(1);
10801 if (V2HasXXSWAPD) {
10806 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10807 if (ValType != MVT::v2f64)
10813 ShufflesHandledWithVPERM++;
10817 if (Opcode == PPCISD::XXPERM) {
10818 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10820 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10823 dbgs() <<
"With the following permute control vector:\n";
10827 if (Opcode == PPCISD::XXPERM)
10828 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10832 if (isLittleEndian)
10836 DAG.
getNode(Opcode, dl,
V1.getValueType(),
V1, V2, VPermMask);
10838 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10850 switch (IntrinsicID) {
10854 case Intrinsic::ppc_altivec_vcmpbfp_p:
10858 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10862 case Intrinsic::ppc_altivec_vcmpequb_p:
10866 case Intrinsic::ppc_altivec_vcmpequh_p:
10870 case Intrinsic::ppc_altivec_vcmpequw_p:
10874 case Intrinsic::ppc_altivec_vcmpequd_p:
10875 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10881 case Intrinsic::ppc_altivec_vcmpneb_p:
10882 case Intrinsic::ppc_altivec_vcmpneh_p:
10883 case Intrinsic::ppc_altivec_vcmpnew_p:
10884 case Intrinsic::ppc_altivec_vcmpnezb_p:
10885 case Intrinsic::ppc_altivec_vcmpnezh_p:
10886 case Intrinsic::ppc_altivec_vcmpnezw_p:
10887 if (Subtarget.hasP9Altivec()) {
10888 switch (IntrinsicID) {
10891 case Intrinsic::ppc_altivec_vcmpneb_p:
10894 case Intrinsic::ppc_altivec_vcmpneh_p:
10897 case Intrinsic::ppc_altivec_vcmpnew_p:
10900 case Intrinsic::ppc_altivec_vcmpnezb_p:
10903 case Intrinsic::ppc_altivec_vcmpnezh_p:
10906 case Intrinsic::ppc_altivec_vcmpnezw_p:
10914 case Intrinsic::ppc_altivec_vcmpgefp_p:
10918 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10922 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10926 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10930 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10934 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10935 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10941 case Intrinsic::ppc_altivec_vcmpgtub_p:
10945 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10949 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10953 case Intrinsic::ppc_altivec_vcmpgtud_p:
10954 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10961 case Intrinsic::ppc_altivec_vcmpequq:
10962 case Intrinsic::ppc_altivec_vcmpgtsq:
10963 case Intrinsic::ppc_altivec_vcmpgtuq:
10964 if (!Subtarget.isISA3_1())
10966 switch (IntrinsicID) {
10969 case Intrinsic::ppc_altivec_vcmpequq:
10972 case Intrinsic::ppc_altivec_vcmpgtsq:
10975 case Intrinsic::ppc_altivec_vcmpgtuq:
10982 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10983 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10984 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10985 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10986 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10987 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10988 if (Subtarget.hasVSX()) {
10989 switch (IntrinsicID) {
10990 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10993 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10996 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10999 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
11002 case Intrinsic::ppc_vsx_xvcmpgesp_p:
11005 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
11015 case Intrinsic::ppc_altivec_vcmpbfp:
11018 case Intrinsic::ppc_altivec_vcmpeqfp:
11021 case Intrinsic::ppc_altivec_vcmpequb:
11024 case Intrinsic::ppc_altivec_vcmpequh:
11027 case Intrinsic::ppc_altivec_vcmpequw:
11030 case Intrinsic::ppc_altivec_vcmpequd:
11031 if (Subtarget.hasP8Altivec())
11036 case Intrinsic::ppc_altivec_vcmpneb:
11037 case Intrinsic::ppc_altivec_vcmpneh:
11038 case Intrinsic::ppc_altivec_vcmpnew:
11039 case Intrinsic::ppc_altivec_vcmpnezb:
11040 case Intrinsic::ppc_altivec_vcmpnezh:
11041 case Intrinsic::ppc_altivec_vcmpnezw:
11042 if (Subtarget.hasP9Altivec())
11043 switch (IntrinsicID) {
11046 case Intrinsic::ppc_altivec_vcmpneb:
11049 case Intrinsic::ppc_altivec_vcmpneh:
11052 case Intrinsic::ppc_altivec_vcmpnew:
11055 case Intrinsic::ppc_altivec_vcmpnezb:
11058 case Intrinsic::ppc_altivec_vcmpnezh:
11061 case Intrinsic::ppc_altivec_vcmpnezw:
11068 case Intrinsic::ppc_altivec_vcmpgefp:
11071 case Intrinsic::ppc_altivec_vcmpgtfp:
11074 case Intrinsic::ppc_altivec_vcmpgtsb:
11077 case Intrinsic::ppc_altivec_vcmpgtsh:
11080 case Intrinsic::ppc_altivec_vcmpgtsw:
11083 case Intrinsic::ppc_altivec_vcmpgtsd:
11084 if (Subtarget.hasP8Altivec())
11089 case Intrinsic::ppc_altivec_vcmpgtub:
11092 case Intrinsic::ppc_altivec_vcmpgtuh:
11095 case Intrinsic::ppc_altivec_vcmpgtuw:
11098 case Intrinsic::ppc_altivec_vcmpgtud:
11099 if (Subtarget.hasP8Altivec())
11104 case Intrinsic::ppc_altivec_vcmpequq_p:
11105 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11106 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11107 if (!Subtarget.isISA3_1())
11109 switch (IntrinsicID) {
11112 case Intrinsic::ppc_altivec_vcmpequq_p:
11115 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11118 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11132 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
11138 auto MapNodeWithSplatVector =
11139 [&](
unsigned Opcode,
11140 std::initializer_list<SDValue> ExtraOps = {}) ->
SDValue {
11145 Ops.append(ExtraOps.begin(), ExtraOps.end());
11146 return DAG.
getNode(Opcode, dl, MVT::v16i8,
Ops);
11149 switch (IntrinsicID) {
11150 case Intrinsic::thread_pointer:
11152 if (Subtarget.isPPC64())
11156 case Intrinsic::ppc_rldimi: {
11157 assert(Subtarget.isPPC64() &&
"rldimi is only available in 64-bit!");
11159 APInt
Mask =
Op.getConstantOperandAPInt(4);
11161 return Op.getOperand(2);
11162 if (
Mask.isAllOnes())
11165 unsigned MB = 0, ME = 0;
11169 if (ME < 63 - SH) {
11172 }
else if (ME > 63 - SH) {
11178 {Op.getOperand(2), Src,
11179 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
11180 DAG.getTargetConstant(MB, dl, MVT::i32)}),
11184 case Intrinsic::ppc_rlwimi: {
11185 APInt
Mask =
Op.getConstantOperandAPInt(4);
11187 return Op.getOperand(2);
11188 if (
Mask.isAllOnes())
11191 unsigned MB = 0, ME = 0;
11195 PPC::RLWIMI, dl, MVT::i32,
11196 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
11197 DAG.getTargetConstant(MB, dl, MVT::i32),
11198 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11202 case Intrinsic::ppc_bcdshift:
11203 return MapNodeWithSplatVector(PPCISD::BCDSHIFT, {
Op.getOperand(3)});
11204 case Intrinsic::ppc_bcdshiftround:
11205 return MapNodeWithSplatVector(PPCISD::BCDSHIFTROUND, {
Op.getOperand(3)});
11206 case Intrinsic::ppc_bcdtruncate:
11207 return MapNodeWithSplatVector(PPCISD::BCDTRUNC, {
Op.getOperand(3)});
11208 case Intrinsic::ppc_bcdunsignedtruncate:
11209 return MapNodeWithSplatVector(PPCISD::BCDUTRUNC);
11210 case Intrinsic::ppc_bcdunsignedshift:
11211 return MapNodeWithSplatVector(PPCISD::BCDUSHIFT);
11213 case Intrinsic::ppc_rlwnm: {
11214 if (
Op.getConstantOperandVal(3) == 0)
11216 unsigned MB = 0, ME = 0;
11221 {Op.getOperand(1), Op.getOperand(2),
11222 DAG.getTargetConstant(MB, dl, MVT::i32),
11223 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11227 case Intrinsic::ppc_mma_disassemble_acc: {
11228 if (Subtarget.isISAFuture()) {
11229 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11240 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11241 Subtarget.isLittleEndian() ? Value2 :
Value,
11242 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11246 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11247 Subtarget.isLittleEndian() ? Value2 :
Value,
11248 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11252 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11253 Subtarget.isLittleEndian() ?
Value : Value2,
11254 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11258 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11259 Subtarget.isLittleEndian() ?
Value : Value2,
11260 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11267 case Intrinsic::ppc_vsx_disassemble_pair: {
11270 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
11272 WideVec = DAG.
getNode(PPCISD::XXMFACC, dl, MVT::v512i1, WideVec);
11275 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
11277 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8, WideVec,
11278 DAG.
getConstant(Subtarget.isLittleEndian() ? NumVecs - 1 - VecNo
11286 case Intrinsic::ppc_build_dmr: {
11289 for (
int i = 1; i < 9; i += 2) {
11297 DAG.
getNode(PPCISD::PAIR_BUILD, dl, MVT::v256i1, {Hi, Lo}));
11304 case Intrinsic::ppc_mma_dmxxextfdmr512: {
11305 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr512 requires ISA Future");
11307 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11308 "Specify P of 0 or 1 for lower or upper 512 bytes");
11309 unsigned HiLo = Idx->getSExtValue();
11313 Opcode = PPC::DMXXEXTFDMR512;
11314 Subx = PPC::sub_wacc_lo;
11316 Opcode = PPC::DMXXEXTFDMR512_HI;
11317 Subx = PPC::sub_wacc_hi;
11320 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
11324 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11328 case Intrinsic::ppc_mma_dmxxextfdmr256: {
11329 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr256 requires ISA Future");
11331 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11332 "Specify a dmr row pair 0-3");
11333 unsigned IdxVal = Idx->getSExtValue();
11337 Subx = PPC::sub_dmrrowp0;
11340 Subx = PPC::sub_dmrrowp1;
11343 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11346 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11350 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v256i1,
11356 DAG.
getMachineNode(PPC::DMXXEXTFDMR256, dl, MVT::v256i1, {Subreg, P}),
11360 case Intrinsic::ppc_mma_dmxxinstdmr512: {
11361 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr512 requires ISA Future");
11363 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11364 "Specify P of 0 or 1 for lower or upper 512 bytes");
11365 unsigned HiLo = Idx->getSExtValue();
11369 Opcode = PPCISD::INST512;
11370 Subx = PPC::sub_wacc_lo;
11372 Opcode = PPCISD::INST512HI;
11373 Subx = PPC::sub_wacc_hi;
11379 Op.getOperand(1), Wacc, SubReg),
11383 case Intrinsic::ppc_mma_dmxxinstdmr256: {
11384 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr256 requires ISA Future");
11386 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11387 "Specify a dmr row pair 0-3");
11388 unsigned IdxVal = Idx->getSExtValue();
11392 Subx = PPC::sub_dmrrowp0;
11395 Subx = PPC::sub_dmrrowp1;
11398 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11401 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11407 DAG.
getNode(PPCISD::INST256, dl, MVT::v256i1,
Op.getOperand(2),
P);
11409 Op.getOperand(1), DMRRowp, SubReg),
11413 case Intrinsic::ppc_mma_xxmfacc:
11414 case Intrinsic::ppc_mma_xxmtacc: {
11416 if (!Subtarget.isISAFuture())
11427 case Intrinsic::ppc_unpack_longdouble: {
11429 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11430 "Argument of long double unpack must be 0 or 1!");
11433 Idx->getValueType(0)));
11436 case Intrinsic::ppc_compare_exp_lt:
11437 case Intrinsic::ppc_compare_exp_gt:
11438 case Intrinsic::ppc_compare_exp_eq:
11439 case Intrinsic::ppc_compare_exp_uo: {
11441 switch (IntrinsicID) {
11442 case Intrinsic::ppc_compare_exp_lt:
11445 case Intrinsic::ppc_compare_exp_gt:
11448 case Intrinsic::ppc_compare_exp_eq:
11451 case Intrinsic::ppc_compare_exp_uo:
11457 PPC::SELECT_CC_I4, dl, MVT::i32,
11458 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
11459 Op.getOperand(1), Op.getOperand(2)),
11461 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11462 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
11465 case Intrinsic::ppc_test_data_class: {
11466 EVT OpVT =
Op.getOperand(1).getValueType();
11467 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
11468 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
11481 {Op.getOperand(2), Op.getOperand(1)}),
11483 if (Subtarget.isISA3_1()) {
11490 TestDataClass, SubRegIdx),
11493 return DAG.
getNode(PPCISD::SETBC, dl, MVT::i32, CRBit);
11499 {TestDataClass, DAG.getConstant(1, dl, MVT::i32),
11500 DAG.getConstant(0, dl, MVT::i32),
11501 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
11504 case Intrinsic::ppc_fnmsub: {
11505 EVT VT =
Op.getOperand(1).getValueType();
11506 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
11511 return DAG.
getNode(PPCISD::FNMSUB, dl, VT,
Op.getOperand(1),
11512 Op.getOperand(2),
Op.getOperand(3));
11514 case Intrinsic::ppc_convert_f128_to_ppcf128:
11515 case Intrinsic::ppc_convert_ppcf128_to_f128: {
11516 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
11517 ? RTLIB::CONVERT_PPCF128_F128
11518 : RTLIB::CONVERT_F128_PPCF128;
11520 std::pair<SDValue, SDValue>
Result =
11521 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
11525 case Intrinsic::ppc_maxfe:
11526 case Intrinsic::ppc_maxfl:
11527 case Intrinsic::ppc_maxfs:
11528 case Intrinsic::ppc_minfe:
11529 case Intrinsic::ppc_minfl:
11530 case Intrinsic::ppc_minfs: {
11531 EVT VT =
Op.getValueType();
11534 [VT](
const SDUse &Use) { return Use.getValueType() == VT; }) &&
11535 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
11538 if (IntrinsicID == Intrinsic::ppc_minfe ||
11539 IntrinsicID == Intrinsic::ppc_minfl ||
11540 IntrinsicID == Intrinsic::ppc_minfs)
11561 SDValue Tmp = DAG.
getNode(PPCISD::VCMP, dl,
Op.getOperand(2).getValueType(),
11562 Op.getOperand(1),
Op.getOperand(2),
11573 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11581 switch (
Op.getConstantOperandVal(1)) {
11586 Bitx = PPC::sub_eq;
11587 SetOp = PPCISD::SETBC;
11592 Bitx = PPC::sub_eq;
11593 SetOp = PPCISD::SETBCR;
11598 Bitx = PPC::sub_lt;
11599 SetOp = PPCISD::SETBC;
11604 Bitx = PPC::sub_lt;
11605 SetOp = PPCISD::SETBCR;
11610 if (Subtarget.isISA3_1()) {
11615 CR6Reg, SubRegIdx, GlueOp),
11617 return DAG.
getNode(SetOp, dl, MVT::i32, CRBit);
11645 switch (
Op.getConstantOperandVal(ArgStart)) {
11646 case Intrinsic::ppc_cfence: {
11647 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11648 SDValue Val =
Op.getOperand(ArgStart + 1);
11650 if (Ty == MVT::i128) {
11655 unsigned Opcode = Subtarget.isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11658 Opcode,
DL, MVT::Other,
11663 case Intrinsic::ppc_disassemble_dmr: {
11665 "llvm.ppc.disassemble.dmr must carry a chain argument.");
11666 return DAG.
getStore(
Op.getOperand(0),
DL,
Op.getOperand(ArgStart + 2),
11667 Op.getOperand(ArgStart + 1), MachinePointerInfo());
11678 if (!Subtarget.isPPC64())
11681 if (Subtarget.hasP9Vector()) {
11688 int VectorIndex = 0;
11689 if (Subtarget.isLittleEndian())
11699 auto CreateRotateInsert =
11700 [&](
unsigned Opcode, MVT VT,
SDValue Dest,
SDValue Src,
unsigned RotAmt,
11701 unsigned MaskBegin,
11702 std::optional<unsigned> MaskEnd = std::nullopt) ->
SDValue {
11706 if (MaskEnd.has_value())
11718 CreateRotateInsert(PPC::RLWIMI, MVT::i32, Rot, Val32, 24, 0, 7);
11720 return CreateRotateInsert(PPC::RLWIMI, MVT::i32, Swap, Val32, 24, 16, 23);
11733 return CreateRotateInsert(PPC::RLDIMI, MVT::i64, HiSwap, LoSwap, 32, 0);
11741 "Expecting an atomic compare-and-swap here.");
11744 EVT MemVT = AtomicNode->getMemoryVT();
11762 for (
int i = 0, e = AtomicNode->getNumOperands(); i < e; i++)
11763 Ops.push_back(AtomicNode->getOperand(i));
11765 MachineMemOperand *MMO = AtomicNode->getMemOperand();
11766 SDVTList Tys = DAG.
getVTList(MVT::i32, MVT::Other);
11768 (MemVT == MVT::i8) ? PPCISD::ATOMIC_CMP_SWAP_8 : PPCISD::ATOMIC_CMP_SWAP_16;
11775 EVT MemVT =
N->getMemoryVT();
11777 "Expect quadword atomic operations");
11779 unsigned Opc =
N->getOpcode();
11784 SDVTList Tys = DAG.
getVTList(MVT::i64, MVT::i64, MVT::Other);
11787 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11788 for (
int I = 1,
E =
N->getNumOperands();
I <
E; ++
I)
11789 Ops.push_back(
N->getOperand(
I));
11791 Ops, MemVT,
N->getMemOperand());
11798 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11805 SDVTList Tys = DAG.
getVTList(MVT::Other);
11808 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11814 Ops.push_back(ValLo);
11815 Ops.push_back(ValHi);
11816 Ops.push_back(
N->getOperand(2));
11818 N->getMemOperand());
11830 enum DataClassMask {
11832 DC_NEG_INF = 1 << 4,
11833 DC_POS_INF = 1 << 5,
11834 DC_NEG_ZERO = 1 << 2,
11835 DC_POS_ZERO = 1 << 3,
11836 DC_NEG_SUBNORM = 1,
11837 DC_POS_SUBNORM = 1 << 1,
11840 EVT VT =
Op.getValueType();
11842 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11843 : VT == MVT::f64 ? PPC::XSTSTDCDP
11854 return DAG.
getNOT(Dl, Rev, MVT::i1);
11861 TestOp, Dl, MVT::i32,
11863 DC_NEG_ZERO | DC_POS_ZERO |
11864 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11870 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11876 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11881 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11894 bool IsQuiet = Mask &
fcQNan;
11900 if (VT == MVT::f128) {
11904 QuietMask = 0x8000;
11905 }
else if (VT == MVT::f64) {
11906 if (Subtarget.isPPC64()) {
11917 QuietMask = 0x80000;
11918 }
else if (VT == MVT::f32) {
11920 QuietMask = 0x400000;
11936 unsigned NativeMask = 0;
11938 NativeMask |= DC_NAN;
11940 NativeMask |= DC_NEG_INF;
11942 NativeMask |= DC_POS_INF;
11944 NativeMask |= DC_NEG_ZERO;
11946 NativeMask |= DC_POS_ZERO;
11948 NativeMask |= DC_NEG_SUBNORM;
11950 NativeMask |= DC_POS_SUBNORM;
11953 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11955 TestOp, Dl, MVT::i32,
11964 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11966 uint64_t RHSC =
Op.getConstantOperandVal(1);
11969 if (
LHS.getValueType() == MVT::ppcf128) {
11993 bool Future = Subtarget.isISAFuture();
11996 "Mask predication not supported");
11999 unsigned IID = Future ? Intrinsic::ppc_vsx_lxvrl : Intrinsic::ppc_vsx_lxvl;
12000 unsigned EltBits =
Op->getValueType(0).getScalarType().getSizeInBits();
12004 SDVTList Tys = DAG.
getVTList(
Op->getValueType(0), MVT::Other);
12007 VPLD->getMemoryVT(), VPLD->getMemOperand());
12014 "Mask predication not supported");
12019 Op->getOperand(1).getValueType().getScalarType().getSizeInBits();
12020 bool Future = Subtarget.isISAFuture();
12021 unsigned IID = Future ? Intrinsic::ppc_vsx_stxvrl : Intrinsic::ppc_vsx_stxvl;
12024 VPST->getChain(), DAG.
getConstant(IID, dl, MVT::i32),
12027 SDVTList Tys = DAG.
getVTList(MVT::Other);
12030 VPST->getMemoryVT(), VPST->getMemOperand());
12041 "Unexpected partial reduction");
12064 unsigned EltSize =
Op.getValueType().getScalarSizeInBits();
12066 int64_t
IntVal =
Op.getConstantOperandVal(0);
12067 if (IntVal >= -16 && IntVal <= 15)
12073 if (Subtarget.hasLFIWAX() && Subtarget.hasVSX() &&
12080 MMOMetadata(RLI.AAInfo, RLI.Ranges));
12083 PPCISD::LD_SPLAT, dl, DAG.
getVTList(MVT::v4i32, MVT::Other),
Ops,
12087 return Bits.getValue(0);
12103 !Subtarget.isLittleEndian() && ValVT.
isInteger() &&
12108 64 -
Op.getValueType().getScalarSizeInBits(), dl, ShiftAmountTy);
12116 MachinePointerInfo());
12123 return DAG.
getLoad(
Op.getValueType(), dl,
Store, FIdx, MachinePointerInfo());
12129 "Should only be called for ISD::INSERT_VECTOR_ELT");
12133 EVT VT =
Op.getValueType();
12138 if (VT == MVT::v2f64 &&
C)
12141 if (Subtarget.hasP9Vector()) {
12150 if ((VT == MVT::v4f32) && (V2.
getValueType() == MVT::f32) &&
12156 BitcastLoad,
Op.getOperand(2));
12157 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
12161 if (Subtarget.isISA3_1()) {
12162 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.isPPC64())
12166 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
12167 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
12177 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
12180 unsigned InsertAtElement =
C->getZExtValue();
12181 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
12182 if (Subtarget.isLittleEndian()) {
12183 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
12185 return DAG.
getNode(PPCISD::VECINSERT, dl, VT,
V1, Mtvsrz,
12197 EVT VT =
Op.getValueType();
12198 bool IsV1024i1 = VT == MVT::v1024i1;
12199 bool IsV2048i1 = VT == MVT::v2048i1;
12203 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12205 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12206 "Dense Math support required.");
12207 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12216 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12217 MachineMemOperand *NewMMO =
12225 DAG.
getVTList(MVT::v256i1, MVT::Other),
12226 LoadOps, MVT::v256i1, NewMMO);
12231 if (Subtarget.isLittleEndian()) {
12232 std::reverse(Loads.
begin(), Loads.
end());
12233 std::reverse(LoadChains.
begin(), LoadChains.
end());
12245 SDValue Dmr1Value = DMFInsert1024(MoreLoads, dl, DAG);
12251 const SDValue DmrPOps[] = {DmrPRC,
Value, Dmr0Sub, Dmr1Value, Dmr1Sub};
12254 DAG.
getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v2048i1, DmrPOps), 0);
12263 DAG.
getNode(PPCISD::INST512, dl, MVT::v512i1, Pairs[0], Pairs[1]);
12266 DAG.
getNode(PPCISD::INST512HI, dl, MVT::v512i1, Pairs[2], Pairs[3]);
12271 {RC, Lo, LoSub, Hi, HiSub}),
12281 EVT VT =
Op.getValueType();
12283 if (VT == MVT::v1024i1 || VT == MVT::v2048i1)
12284 return LowerDMFVectorLoad(
Op, DAG);
12286 if (VT != MVT::v256i1 && VT != MVT::v512i1)
12290 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
12291 "Type unsupported without MMA");
12292 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12293 "Type unsupported without paired vector support");
12297 if (VT == MVT::v256i1 && Subtarget.isISAFuture())
12306 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12308 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
12317 if (Subtarget.isLittleEndian()) {
12318 std::reverse(Loads.
begin(), Loads.
end());
12319 std::reverse(LoadChains.
begin(), LoadChains.
end());
12323 DAG.
getNode(VT == MVT::v512i1 ? PPCISD::ACC_BUILD : PPCISD::PAIR_BUILD,
12339 bool IsV1024i1 = VT == MVT::v1024i1;
12340 bool IsV2048i1 = VT == MVT::v2048i1;
12344 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12346 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12347 "Dense Math support required.");
12348 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12350 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12353 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12358 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12362 MachineSDNode *ExtNode =
12366 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes,
Hi);
12372 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12378 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12384 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12389 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12394 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12399 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12403 MachineSDNode *ExtNode =
12404 DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr0Lo);
12408 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr0Hi);
12411 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr1Lo);
12415 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr1Hi);
12420 if (Subtarget.isLittleEndian())
12423 SDVTList Tys = DAG.
getVTList(MVT::Other);
12425 StoreChain, DAG.
getConstant(Intrinsic::ppc_vsx_stxvp, dl, MVT::i32),
12429 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12430 MachineMemOperand *NewMMO =
12439 MVT::v256i1, NewMMO);
12455 EVT StoreVT =
Value.getValueType();
12457 if (StoreVT == MVT::v1024i1 || StoreVT == MVT::v2048i1)
12458 return LowerDMFVectorStore(
Op, DAG);
12460 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
12464 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
12465 "Type unsupported without MMA");
12466 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12467 "Type unsupported without paired vector support");
12471 if (StoreVT == MVT::v256i1 && Subtarget.isISAFuture() &&
12479 unsigned NumVecs = 2;
12480 if (StoreVT == MVT::v512i1) {
12481 if (Subtarget.isISAFuture()) {
12482 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12484 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
12487 Value2 =
SDValue(ExtNode, 1);
12492 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12493 unsigned VecNum = Subtarget.isLittleEndian() ? NumVecs - 1 - Idx : Idx;
12495 if (Subtarget.isISAFuture()) {
12496 VecNum = Subtarget.isLittleEndian() ? 1 - (Idx % 2) : (Idx % 2);
12497 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
12498 Idx > 1 ? Value2 :
Value,
12501 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
Value,
12505 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
12519 if (
Op.getValueType() == MVT::v4i32) {
12536 LHS,
RHS, DAG, dl, MVT::v4i32);
12539 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
12544 }
else if (
Op.getValueType() == MVT::v16i8) {
12546 bool isLittleEndian = Subtarget.isLittleEndian();
12550 LHS,
RHS, DAG, dl, MVT::v8i16);
12555 LHS,
RHS, DAG, dl, MVT::v8i16);
12563 for (
unsigned i = 0; i != 8; ++i) {
12564 if (isLittleEndian) {
12566 Ops[i*2+1] = 2*i+16;
12569 Ops[i*2+1] = 2*i+1+16;
12572 if (isLittleEndian)
12582 bool IsStrict =
Op->isStrictFPOpcode();
12583 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
12584 !Subtarget.hasP9Vector())
12594 "Should only be called for ISD::FP_EXTEND");
12598 if (
Op.getValueType() != MVT::v2f64 ||
12599 Op.getOperand(0).getValueType() != MVT::v2f32)
12611 "Node should have 2 operands with second one being a constant!");
12623 int DWord = Idx >> 1;
12626 if (Subtarget.isLittleEndian())
12629 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64,
12643 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12645 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12646 LD->getMemoryVT(),
LD->getMemOperand());
12651 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewOp,
12656 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12658 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12659 LD->getMemoryVT(),
LD->getMemOperand());
12660 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewLd,
12671 if (STI.useCRBits())
12688 PPCISD::ADDE,
DL, DAG.
getVTList(SumType, MVT::i32), Zero, Zero, Flag);
12689 if (STI.useCRBits())
12697 SDNode *
N =
Op.getNode();
12698 EVT VT =
N->getValueType(0);
12699 EVT CarryType =
N->getValueType(1);
12700 unsigned Opc =
N->getOpcode();
12702 Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12704 N->getOperand(0),
N->getOperand(1));
12716 SDNode *
N =
Op.getNode();
12717 unsigned Opc =
N->getOpcode();
12718 EVT VT =
N->getValueType(0);
12719 EVT CarryType =
N->getValueType(1);
12720 SDValue CarryOp =
N->getOperand(2);
12722 Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12728 Op.getOperand(0),
Op.getOperand(1), CarryOp);
12742 EVT VT =
Op.getNode()->getValueType(0);
12768 EVT VT =
Op.getNode()->getValueType(0);
12800 EVT OpVT =
LHS.getValueType();
12801 EVT VT =
Op.getValueType();
12816 unsigned Opcode = PPCISD::SUBC;
12826 Opcode = PPCISD::ADDC;
12833 if (Subtarget.isPPC64() && OpVT != MVT::i64) {
12840 SDVTList VTs = DAG.
getVTList(OpVT, MVT::i32);
12860 EVT OpVT =
A.getValueType();
12861 EVT ResVT =
Op.getValueType();
12866 if (Subtarget.isPPC64() && OpVT != MVT::i64) {
12876 SDVTList VTs = DAG.
getVTList(OpVT, MVT::i32);
12894 switch (
Op.getOpcode()) {
12915 return LowerSSUBO(
Op, DAG);
12917 return LowerSADDO(
Op, DAG);
12929 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
12950 return LowerSET_ROUNDING(
Op, DAG);
12957 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
12958 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
12970 return LowerFP_ROUND(
Op, DAG);
12984 return LowerINTRINSIC_VOID(
Op, DAG);
12986 return LowerBSWAP(
Op, DAG);
12988 return LowerATOMIC_CMP_SWAP(
Op, DAG);
12990 return LowerATOMIC_LOAD_STORE(
Op, DAG);
12992 return LowerIS_FPCLASS(
Op, DAG);
12995 return LowerADDSUBO(
Op, DAG);
12998 return LowerADDSUBO_CARRY(
Op, DAG);
13000 return LowerUCMP(
Op, DAG);
13002 return LowerABDU(
Op, DAG);
13008 if (
Op->getFlags().hasNoFPExcept())
13012 return LowerVP_LOAD(
Op, DAG);
13013 case ISD::VP_STORE:
13014 return LowerVP_STORE(
Op, DAG);
13016 return LowerPartialReduce(
Op, DAG);
13024 switch (
N->getOpcode()) {
13026 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
13043 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
13046 assert(
N->getValueType(0) == MVT::i1 &&
13047 "Unexpected result type for CTR decrement intrinsic");
13049 N->getValueType(0));
13059 switch (
N->getConstantOperandVal(0)) {
13060 case Intrinsic::ppc_pack_longdouble:
13062 N->getOperand(2),
N->getOperand(1)));
13064 case Intrinsic::ppc_maxfe:
13065 case Intrinsic::ppc_minfe:
13066 case Intrinsic::ppc_fnmsub:
13067 case Intrinsic::ppc_convert_f128_to_ppcf128:
13074 if (!Subtarget.isSVR4ABI() || Subtarget.isPPC64())
13077 EVT VT =
N->getValueType(0);
13079 if (VT == MVT::i64) {
13092 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
13096 Results.push_back(LoweredValue);
13097 if (
N->isStrictFPOpcode())
13102 if (!
N->getValueType(0).isVector())
13135 return Builder.CreateIntrinsicWithoutFolding(Id, {});
13141 unsigned SZ = ValueTy->getPrimitiveSizeInBits();
13143 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
13144 "Only 8/16/32/64-bit atomic loads supported");
13150 IntID = Intrinsic::ppc_lbarx;
13151 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13154 IntID = Intrinsic::ppc_lharx;
13155 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13158 IntID = Intrinsic::ppc_lwarx;
13161 IntID = Intrinsic::ppc_ldarx;
13165 Builder.CreateIntrinsic(IntID, Addr,
nullptr,
"larx");
13167 return Builder.CreateTruncOrBitCast(
Call, ValueTy);
13178 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
13179 "Only 8/16/32/64-bit atomic loads supported");
13185 IntID = Intrinsic::ppc_stbcx;
13186 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13189 IntID = Intrinsic::ppc_sthcx;
13190 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13193 IntID = Intrinsic::ppc_stwcx;
13196 IntID = Intrinsic::ppc_stdcx;
13200 if (SZ == 8 || SZ == 16)
13201 Val = Builder.CreateZExt(Val, Builder.getInt32Ty());
13203 Value *
Call = Builder.CreateIntrinsic(IntID, {Addr, Val},
13205 return Builder.CreateXor(
Call, Builder.getInt32(1));
13228 return Builder.CreateIntrinsicWithoutFolding(Intrinsic::ppc_cfence,
13238 unsigned BinOpcode,
13239 unsigned CmpOpcode,
13240 unsigned CmpPred)
const {
13245 unsigned AtomicSize =
MI.getOperand(3).getImm();
13247 auto LoadMnemonic = PPC::LDARX;
13248 auto StoreMnemonic = PPC::STDCX;
13249 switch (AtomicSize) {
13253 LoadMnemonic = PPC::LBARX;
13254 StoreMnemonic = PPC::STBCX;
13255 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13258 LoadMnemonic = PPC::LHARX;
13259 StoreMnemonic = PPC::STHCX;
13260 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13263 LoadMnemonic = PPC::LWARX;
13264 StoreMnemonic = PPC::STWCX;
13267 LoadMnemonic = PPC::LDARX;
13268 StoreMnemonic = PPC::STDCX;
13276 if (CmpOpcode == PPC::CMPW && (AtomicSize == 1 || AtomicSize == 2))
13287 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13289 F->insert(It, loopMBB);
13291 F->insert(It, loop2MBB);
13292 F->insert(It, exitMBB);
13298 Register TmpReg = (!BinOpcode) ? incr :
13299 RegInfo.createVirtualRegister( AtomicSize == 8 ? &PPC::G8RCRegClass
13300 : &PPC::GPRCRegClass);
13325 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
13330 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13332 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
13333 Register ExtReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13334 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
13364 switch(
MI.getOpcode()) {
13368 return TII->isSignExtended(
MI.getOperand(1).getReg(),
13369 &
MI.getMF()->getRegInfo());
13393 case PPC::EXTSB8_32_64:
13394 case PPC::EXTSB8_rec:
13395 case PPC::EXTSB_rec:
13398 case PPC::EXTSH8_32_64:
13399 case PPC::EXTSH8_rec:
13400 case PPC::EXTSH_rec:
13402 case PPC::EXTSWSLI:
13403 case PPC::EXTSWSLI_32_64:
13404 case PPC::EXTSWSLI_32_64_rec:
13405 case PPC::EXTSWSLI_rec:
13406 case PPC::EXTSW_32:
13407 case PPC::EXTSW_32_64:
13408 case PPC::EXTSW_32_64_rec:
13409 case PPC::EXTSW_rec:
13412 case PPC::SRAWI_rec:
13413 case PPC::SRAW_rec:
13423 unsigned OpIdx,
bool IsByte,
13428 bool IsSignExtended =
13431 if (!IsSignExtended) {
13432 Register ValueReg =
RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13434 TII->get(IsByte ? PPC::EXTSB : PPC::EXTSH), ValueReg)
13436 MI.getOperand(OpIdx).setReg(ValueReg);
13442 unsigned CmpOpcode,
unsigned CmpPred)
const {
13446 assert(!Subtarget.hasPartwordAtomics() &&
13447 "Assumes that part-word atomics are not available");
13455 const bool is8bit =
MI.getOperand(3).getImm() == 1;
13456 if (CmpOpcode == PPC::CMPW)
13464 bool is64bit = Subtarget.isPPC64();
13465 bool isLittleEndian = Subtarget.isLittleEndian();
13466 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13477 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13479 F->insert(It, loopMBB);
13481 F->insert(It, loop2MBB);
13482 F->insert(It, exitMBB);
13488 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13491 Register PtrReg = RegInfo.createVirtualRegister(RC);
13492 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
13494 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
13495 Register Incr2Reg = RegInfo.createVirtualRegister(GPRC);
13496 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
13497 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
13498 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
13499 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
13500 Register Tmp3Reg = RegInfo.createVirtualRegister(GPRC);
13501 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
13502 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
13503 Register SrwDestReg = RegInfo.createVirtualRegister(GPRC);
13506 (!BinOpcode) ? Incr2Reg : RegInfo.createVirtualRegister(GPRC);
13533 if (ptrA != ZeroReg) {
13534 Ptr1Reg = RegInfo.createVirtualRegister(RC);
13535 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13543 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13544 .
addReg(Ptr1Reg, {}, is64bit ? PPC::sub_32 : 0)
13547 .
addImm(is8bit ? 28 : 27);
13548 if (!isLittleEndian)
13549 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13551 .
addImm(is8bit ? 24 : 16);
13553 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13558 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13568 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13572 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13577 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13581 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
13584 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13591 Register SReg = RegInfo.createVirtualRegister(GPRC);
13592 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13596 unsigned ValueReg = SReg;
13597 unsigned CmpReg = Incr2Reg;
13598 if (CmpOpcode == PPC::CMPW) {
13599 ValueReg = RegInfo.createVirtualRegister(GPRC);
13600 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
13603 Register ValueSReg = RegInfo.createVirtualRegister(GPRC);
13604 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
13606 ValueReg = ValueSReg;
13638 .
addImm(is8bit ? 24 : 16)
13659 Register DstReg =
MI.getOperand(0).getReg();
13661 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
13666 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13667 "Invalid Pointer Size!");
13716 Register BufReg =
MI.getOperand(1).getReg();
13718 if (Subtarget.is64BitELFABI()) {
13731 BaseReg = Subtarget.isPPC64() ? PPC::X1 : PPC::R1;
13733 BaseReg = Subtarget.isPPC64() ? PPC::BP8 : PPC::BP;
13736 TII->get(Subtarget.isPPC64() ? PPC::STD : PPC::STW))
13759 TII->get(Subtarget.isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
13762 if (Subtarget.isPPC64()) {
13780 TII->get(PPC::PHI), DstReg)
13784 MI.eraseFromParent();
13798 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13799 "Invalid Pointer Size!");
13802 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13805 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
13806 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
13820 Register BufReg =
MI.getOperand(0).getReg();
13825 if (PVT == MVT::i64) {
13837 if (PVT == MVT::i64) {
13849 if (PVT == MVT::i64) {
13861 if (PVT == MVT::i64) {
13873 if (PVT == MVT::i64 && Subtarget.isSVR4ABI()) {
13883 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
13886 MI.eraseFromParent();
13902 "Unexpected stack alignment");
13906 unsigned StackProbeSize =
13909 StackProbeSize &= ~(StackAlign - 1);
13910 return StackProbeSize ? StackProbeSize : StackAlign;
13922 const bool isPPC64 = Subtarget.isPPC64();
13954 MF->
insert(MBBIter, TestMBB);
13955 MF->
insert(MBBIter, BlockMBB);
13956 MF->
insert(MBBIter, TailMBB);
13961 Register DstReg =
MI.getOperand(0).getReg();
13962 Register NegSizeReg =
MI.getOperand(1).getReg();
13974 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
13980 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
13981 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
13983 .
addDef(ActualNegSizeReg)
13985 .
add(
MI.getOperand(2))
13986 .
add(
MI.getOperand(3));
13992 .
addReg(ActualNegSizeReg);
13995 int64_t NegProbeSize = -(int64_t)ProbeSize;
14001 .
addImm(NegProbeSize >> 16);
14005 .
addImm(NegProbeSize & 0xFFFF);
14014 .
addReg(ActualNegSizeReg)
14023 .
addReg(ActualNegSizeReg);
14033 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
14060 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
14061 MaxCallFrameSizeReg)
14062 .
add(
MI.getOperand(2))
14063 .
add(
MI.getOperand(3));
14064 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
14066 .
addReg(MaxCallFrameSizeReg);
14072 MBB->addSuccessor(TestMBB);
14075 MI.eraseFromParent();
14077 ++NumDynamicAllocaProbed;
14085static bool IsSelect(
unsigned Opcode,
bool CheckOnlyCC =
false) {
14088 case PPC::SELECT_CC_I4:
14089 case PPC::SELECT_CC_I8:
14090 case PPC::SELECT_CC_F4:
14091 case PPC::SELECT_CC_F8:
14092 case PPC::SELECT_CC_F16:
14093 case PPC::SELECT_CC_VRRC:
14094 case PPC::SELECT_CC_VSFRC:
14095 case PPC::SELECT_CC_VSSRC:
14096 case PPC::SELECT_CC_VSRC:
14097 case PPC::SELECT_CC_SPE4:
14098 case PPC::SELECT_CC_SPE:
14101 case PPC::SELECT_I4:
14102 case PPC::SELECT_I8:
14103 case PPC::SELECT_F4:
14104 case PPC::SELECT_F8:
14105 case PPC::SELECT_F16:
14106 case PPC::SELECT_SPE:
14107 case PPC::SELECT_SPE4:
14108 case PPC::SELECT_VRRC:
14109 case PPC::SELECT_VSFRC:
14110 case PPC::SELECT_VSSRC:
14111 case PPC::SELECT_VSRC:
14112 return !CheckOnlyCC;
14128 assert(
IsSelect(
MI.getOpcode()) &&
"Instruction must be a SELECT variant");
14131 if (Subtarget.hasISEL() &&
14132 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
14133 MI.getOpcode() == PPC::SELECT_CC_I8 ||
14134 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
14136 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
14137 MI.getOpcode() == PPC::SELECT_CC_I8)
14138 Cond.push_back(
MI.getOperand(4));
14141 Cond.push_back(
MI.getOperand(1));
14144 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
14145 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
14146 MI.eraseFromParent();
14159 F->insert(It, copy0MBB);
14160 F->insert(It, sinkMBB);
14168 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
14184 .
addImm(
MI.getOperand(4).getImm())
14185 .
addReg(
MI.getOperand(1).getReg())
14189 .
addReg(
MI.getOperand(1).getReg())
14199 .
addReg(
MI.getOperand(3).getReg())
14201 .
addReg(
MI.getOperand(2).getReg())
14203 MI.eraseFromParent();
14218 loop1MBB =
F->CreateMachineBasicBlock(LLVM_BB);
14219 loop2MBB =
F->CreateMachineBasicBlock(LLVM_BB);
14220 exitMBB =
F->CreateMachineBasicBlock(LLVM_BB);
14221 F->insert(It, loop1MBB);
14222 F->insert(It, loop2MBB);
14223 F->insert(It, exitMBB);
14258 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
14260 unsigned LoadMnemonic = PPC::LDARX;
14261 unsigned StoreMnemonic = PPC::STDCX;
14262 switch (
MI.getOpcode()) {
14265 case PPC::ATOMIC_CMP_SWAP_I8:
14266 LoadMnemonic = PPC::LBARX;
14267 StoreMnemonic = PPC::STBCX;
14268 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14270 case PPC::ATOMIC_CMP_SWAP_I16:
14271 LoadMnemonic = PPC::LHARX;
14272 StoreMnemonic = PPC::STHCX;
14273 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14275 case PPC::ATOMIC_CMP_SWAP_I32:
14276 LoadMnemonic = PPC::LWARX;
14277 StoreMnemonic = PPC::STWCX;
14279 case PPC::ATOMIC_CMP_SWAP_I64:
14280 LoadMnemonic = PPC::LDARX;
14281 StoreMnemonic = PPC::STDCX;
14289 Register oldval =
MI.getOperand(3).getReg();
14290 Register newval =
MI.getOperand(4).getReg();
14304 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
14372 bool is64bit = Subtarget.isPPC64();
14374 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
14379 Register oldval =
MI.getOperand(3).getReg();
14380 Register newval =
MI.getOperand(4).getReg();
14388 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
14393 return RegInfo.createVirtualRegister(RC);
14397 Register Shift1Reg = createVReg(GPRC);
14398 Register ShiftReg = isLittleEndian ? Shift1Reg : createVReg(GPRC);
14399 Register NewVal2Reg = createVReg(GPRC);
14400 Register NewVal3Reg = createVReg(GPRC);
14401 Register OldVal2Reg = createVReg(GPRC);
14402 Register OldVal3Reg = createVReg(GPRC);
14403 Register MaskReg = createVReg(GPRC);
14404 Register Mask2Reg = createVReg(GPRC);
14405 Register Mask3Reg = createVReg(GPRC);
14406 Register Tmp2Reg = createVReg(GPRC);
14407 Register Tmp4Reg = createVReg(GPRC);
14408 Register TmpDestReg = createVReg(GPRC);
14409 Register TmpReg = createVReg(GPRC);
14410 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
14411 Register CrReg = createVReg(&PPC::CRRCRegClass);
14415 if (ptrA != ZeroReg) {
14416 Ptr1Reg = createVReg(RC);
14417 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
14424 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
14425 .
addReg(Ptr1Reg, {}, is64bit ? PPC::sub_32 : 0)
14428 .
addImm(is8bit ? 28 : 27);
14429 if (!isLittleEndian)
14430 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
14432 .
addImm(is8bit ? 24 : 16);
14434 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
14439 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
14446 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
14449 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
14456 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
14460 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
14463 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
14466 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
14476 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
14497 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
14542 switch (
MI.getOpcode()) {
14543 case TargetOpcode::STACKMAP:
14545 case TargetOpcode::PATCHPOINT:
14551 if (Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls())
14555 case PPC::EH_SjLj_SetJmp32:
14556 case PPC::EH_SjLj_SetJmp64:
14559 case PPC::EH_SjLj_LongJmp32:
14560 case PPC::EH_SjLj_LongJmp64:
14563 case PPC::ReadTB: {
14579 F->insert(It, readMBB);
14580 F->insert(It, sinkMBB);
14591 Register ReadAgainReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
14599 Register CmpReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14601 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
14613 case PPC::ATOMIC_LOAD_ADD_NOWP:
14616 case PPC::ATOMIC_LOAD_ADD:
14619 case PPC::ATOMIC_LOAD_ADD_I64:
14622 case PPC::ATOMIC_LOAD_AND_NOWP:
14625 case PPC::ATOMIC_LOAD_AND:
14628 case PPC::ATOMIC_LOAD_AND_I64:
14631 case PPC::ATOMIC_LOAD_OR_NOWP:
14634 case PPC::ATOMIC_LOAD_OR:
14637 case PPC::ATOMIC_LOAD_OR_I64:
14640 case PPC::ATOMIC_LOAD_XOR_NOWP:
14643 case PPC::ATOMIC_LOAD_XOR:
14646 case PPC::ATOMIC_LOAD_XOR_I64:
14649 case PPC::ATOMIC_LOAD_NAND_NOWP:
14652 case PPC::ATOMIC_LOAD_NAND:
14655 case PPC::ATOMIC_LOAD_NAND_I64:
14658 case PPC::ATOMIC_LOAD_SUB_NOWP:
14661 case PPC::ATOMIC_LOAD_SUB:
14664 case PPC::ATOMIC_LOAD_SUB_I64:
14667 case PPC::ATOMIC_LOAD_MIN_NOWP:
14670 case PPC::ATOMIC_LOAD_MIN:
14673 case PPC::ATOMIC_LOAD_MIN_I64:
14676 case PPC::ATOMIC_LOAD_MAX_NOWP:
14679 case PPC::ATOMIC_LOAD_MAX:
14682 case PPC::ATOMIC_LOAD_MAX_I64:
14685 case PPC::ATOMIC_LOAD_UMIN_NOWP:
14688 case PPC::ATOMIC_LOAD_UMIN:
14691 case PPC::ATOMIC_LOAD_UMIN_I64:
14694 case PPC::ATOMIC_LOAD_UMAX_NOWP:
14697 case PPC::ATOMIC_LOAD_UMAX:
14700 case PPC::ATOMIC_LOAD_UMAX_I64:
14703 case PPC::ATOMIC_SWAP_NOWP:
14706 case PPC::ATOMIC_SWAP:
14707 case PPC::ATOMIC_SWAP_I64:
14710 case PPC::ATOMIC_CMP_SWAP_I32:
14711 case PPC::ATOMIC_CMP_SWAP_I64:
14712 case PPC::ATOMIC_CMP_SWAP_I8:
14713 case PPC::ATOMIC_CMP_SWAP_I16: {
14715 bool useHardware =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
14716 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
14717 (Subtarget.hasPartwordAtomics() &&
14718 (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
14719 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16));
14727 case PPC::FADDrtz: {
14737 Register MFFSReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14752 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
14762 case PPC::ANDI_rec_1_EQ_BIT:
14763 case PPC::ANDI_rec_1_GT_BIT:
14764 case PPC::ANDI_rec_1_EQ_BIT8:
14765 case PPC::ANDI_rec_1_GT_BIT8: {
14766 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14767 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
14770 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14771 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
14774 Register Dest = RegInfo.createVirtualRegister(
14775 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
14779 .
addReg(
MI.getOperand(1).getReg())
14782 MI.getOperand(0).getReg())
14783 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
14786 case PPC::TCHECK_RET: {
14789 Register CRReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14792 MI.getOperand(0).getReg())
14796 case PPC::TBEGIN_RET: {
14798 unsigned Imm =
MI.getOperand(1).getImm();
14801 MI.getOperand(0).getReg())
14805 case PPC::SETRNDi: {
14807 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14811 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14813 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14824 unsigned Mode =
MI.getOperand(1).getImm();
14825 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
14829 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
14834 case PPC::SETRND: {
14842 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
14843 if (Subtarget.hasDirectMove()) {
14844 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
14848 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
14851 if (RC == &PPC::F8RCRegClass) {
14853 assert((RegInfo.getRegClass(DestReg) == &PPC::G8RCRegClass) &&
14854 "Unsupported RegClass.");
14856 StoreOp = PPC::STFD;
14860 assert((RegInfo.getRegClass(SrcReg) == &PPC::G8RCRegClass) &&
14861 (RegInfo.getRegClass(DestReg) == &PPC::F8RCRegClass) &&
14862 "Unsupported RegClass.");
14895 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14898 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14910 Register OldFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14912 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
14914 Register ImDefReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14915 Register ExtSrcReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14920 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
14921 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
14926 Register NewFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14927 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
14933 Register NewFPSCRReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14934 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
14945 case PPC::SETFLM: {
14949 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14951 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14953 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14956 Register NewFPSCRReg =
MI.getOperand(1).getReg();
14964 case PPC::PROBED_ALLOCA_32:
14965 case PPC::PROBED_ALLOCA_64:
14968 case PPC::SPLIT_QUADWORD: {
14975 .
addUse(Src, {}, PPC::sub_gp8_x1);
14978 .
addUse(Src, {}, PPC::sub_gp8_x0);
14981 case PPC::LQX_PSEUDO:
14982 case PPC::STQX_PSEUDO: {
14988 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
14994 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
14995 :
TII->get(PPC::STQ))
15005 MI.eraseFromParent();
15018 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
15021 return RefinementSteps;
15028 EVT VT =
Op.getValueType();
15031 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
15055PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
15058 EVT VT =
Op.getValueType();
15059 if (VT != MVT::f64 &&
15060 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
15063 return DAG.
getNode(PPCISD::FSQRT, SDLoc(
Op), VT,
Op);
15067 int Enabled,
int &RefinementSteps,
15068 bool &UseOneConstNR,
15069 bool Reciprocal)
const {
15071 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
15072 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
15073 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
15074 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
15080 UseOneConstNR = !Subtarget.needsTwoConstNR();
15081 return DAG.
getNode(PPCISD::FRSQRTE, SDLoc(Operand), VT, Operand);
15088 int &RefinementSteps)
const {
15090 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
15091 (VT == MVT::f64 && Subtarget.hasFRE()) ||
15092 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
15093 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
15096 return DAG.
getNode(PPCISD::FRE, SDLoc(Operand), VT, Operand);
15112 switch (Subtarget.getCPUDirective()) {
15139 unsigned Bytes,
int Dist,
15153 if (FS != BFS || FS != (
int)Bytes)
return false;
15158 int64_t Offset1 = 0, Offset2 = 0;
15161 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
15171 if (isGA1 && isGA2 && GV1 == GV2)
15172 return Offset1 == (Offset2 + Dist*Bytes);
15179 unsigned Bytes,
int Dist,
15182 EVT VT = LS->getMemoryVT();
15189 switch (
N->getConstantOperandVal(1)) {
15190 default:
return false;
15191 case Intrinsic::ppc_altivec_lvx:
15192 case Intrinsic::ppc_altivec_lvxl:
15193 case Intrinsic::ppc_vsx_lxvw4x:
15194 case Intrinsic::ppc_vsx_lxvw4x_be:
15197 case Intrinsic::ppc_vsx_lxvd2x:
15198 case Intrinsic::ppc_vsx_lxvd2x_be:
15201 case Intrinsic::ppc_altivec_lvebx:
15204 case Intrinsic::ppc_altivec_lvehx:
15207 case Intrinsic::ppc_altivec_lvewx:
15217 switch (
N->getConstantOperandVal(1)) {
15218 default:
return false;
15219 case Intrinsic::ppc_altivec_stvx:
15220 case Intrinsic::ppc_altivec_stvxl:
15221 case Intrinsic::ppc_vsx_stxvw4x:
15224 case Intrinsic::ppc_vsx_stxvd2x:
15227 case Intrinsic::ppc_vsx_stxvw4x_be:
15230 case Intrinsic::ppc_vsx_stxvd2x_be:
15233 case Intrinsic::ppc_altivec_stvebx:
15236 case Intrinsic::ppc_altivec_stvehx:
15239 case Intrinsic::ppc_altivec_stvewx:
15256 SDValue Chain = LD->getChain();
15257 EVT VT = LD->getMemoryVT();
15266 while (!Queue.empty()) {
15267 SDNode *ChainNext = Queue.pop_back_val();
15268 if (!Visited.
insert(ChainNext).second)
15275 if (!Visited.
count(ChainLD->getChain().getNode()))
15276 Queue.push_back(ChainLD->getChain().getNode());
15278 for (
const SDUse &O : ChainNext->
ops())
15279 if (!Visited.
count(O.getNode()))
15280 Queue.push_back(O.getNode());
15282 LoadRoots.
insert(ChainNext);
15293 for (
SDNode *
I : LoadRoots) {
15294 Queue.push_back(
I);
15296 while (!Queue.empty()) {
15297 SDNode *LoadRoot = Queue.pop_back_val();
15298 if (!Visited.
insert(LoadRoot).second)
15310 Queue.push_back(U);
15343 auto Final = Shifted;
15354 DAGCombinerInfo &DCI)
const {
15357 SelectionDAG &DAG = DCI.DAG;
15362 if (!DCI.isAfterLegalizeDAG())
15367 for (
const SDNode *U :
N->users())
15372 auto OpSize =
N->getOperand(0).getValueSizeInBits();
15376 if (OpSize <
Size) {
15394 DAGCombinerInfo &DCI)
const {
15395 SelectionDAG &DAG = DCI.DAG;
15398 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
15409 N->getValueType(0) != MVT::i1)
15412 if (
N->getOperand(0).getValueType() != MVT::i32 &&
15413 N->getOperand(0).getValueType() != MVT::i64)
15423 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
15434 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
15457 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15458 N->getOperand(0).getOpcode() !=
ISD::OR &&
15459 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15469 N->getOperand(1).getOpcode() !=
ISD::AND &&
15470 N->getOperand(1).getOpcode() !=
ISD::OR &&
15471 N->getOperand(1).getOpcode() !=
ISD::XOR &&
15482 SmallPtrSet<SDNode *, 16> Visited;
15484 for (
unsigned i = 0; i < 2; ++i) {
15488 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
15500 while (!BinOps.
empty()) {
15508 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15542 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15546 for (
const SDNode *User : Inputs[i].
getNode()->
users()) {
15547 if (User !=
N && !Visited.
count(User))
15556 if (
User->getOperand(0) == Inputs[i])
15559 if (
User->getOperand(0) == Inputs[i] ||
15560 User->getOperand(1) == Inputs[i])
15566 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15567 for (
const SDNode *User : PromOps[i].
getNode()->
users()) {
15568 if (User !=
N && !Visited.
count(User))
15577 if (
User->getOperand(0) == PromOps[i])
15580 if (
User->getOperand(0) == PromOps[i] ||
15581 User->getOperand(1) == PromOps[i])
15588 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15597 std::list<HandleSDNode> PromOpHandles;
15598 for (
auto &PromOp : PromOps)
15599 PromOpHandles.emplace_back(PromOp);
15606 while (!PromOpHandles.empty()) {
15607 SDValue PromOp = PromOpHandles.back().getValue();
15608 PromOpHandles.pop_back();
15617 PromOpHandles.emplace_front(PromOp);
15631 default:
C = 0;
break;
15644 PromOpHandles.emplace_front(PromOp);
15651 for (
unsigned i = 0; i < 2; ++i)
15661 return N->getOperand(0);
15669 DAGCombinerInfo &DCI)
const {
15670 SelectionDAG &DAG = DCI.DAG;
15687 if (
N->getValueType(0) != MVT::i32 &&
15688 N->getValueType(0) != MVT::i64)
15691 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
15692 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.isPPC64())))
15695 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15696 N->getOperand(0).getOpcode() !=
ISD::OR &&
15697 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15704 SmallPtrSet<SDNode *, 16> Visited;
15708 while (!BinOps.
empty()) {
15716 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15742 DenseMap<SDNode *, EVT> SelectTruncOp[2];
15747 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15752 if (User !=
N && !Visited.
count(User))
15758 if (
User->getOperand(0) == Inputs[i])
15759 SelectTruncOp[0].
insert(std::make_pair(User,
15760 User->getOperand(0).getValueType()));
15762 if (
User->getOperand(0) == Inputs[i])
15763 SelectTruncOp[0].
insert(std::make_pair(User,
15764 User->getOperand(0).getValueType()));
15765 if (
User->getOperand(1) == Inputs[i])
15766 SelectTruncOp[1].
insert(std::make_pair(User,
15767 User->getOperand(1).getValueType()));
15772 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15774 if (User !=
N && !Visited.
count(User))
15780 if (
User->getOperand(0) == PromOps[i])
15781 SelectTruncOp[0].
insert(std::make_pair(User,
15782 User->getOperand(0).getValueType()));
15784 if (
User->getOperand(0) == PromOps[i])
15785 SelectTruncOp[0].
insert(std::make_pair(User,
15786 User->getOperand(0).getValueType()));
15787 if (
User->getOperand(1) == PromOps[i])
15788 SelectTruncOp[1].
insert(std::make_pair(User,
15789 User->getOperand(1).getValueType()));
15794 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
15795 bool ReallyNeedsExt =
false;
15799 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15804 Inputs[i].getOperand(0).getValueSizeInBits();
15805 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
15810 OpBits-PromBits))) ||
15813 (OpBits-(PromBits-1)))) {
15814 ReallyNeedsExt =
true;
15822 std::list<HandleSDNode> PromOpHandles;
15823 for (
auto &PromOp : PromOps)
15824 PromOpHandles.emplace_back(PromOp);
15828 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15835 SDValue InSrc = Inputs[i].getOperand(0);
15853 while (!PromOpHandles.empty()) {
15855 PromOpHandles.pop_back();
15859 default:
C = 0;
break;
15872 PromOpHandles.emplace_front(PromOp);
15882 (SelectTruncOp[1].count(PromOp.
getNode()) &&
15884 PromOpHandles.emplace_front(PromOp);
15892 for (
unsigned i = 0; i < 2; ++i) {
15910 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
15911 if (SI0 != SelectTruncOp[0].
end())
15913 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
15914 if (SI1 != SelectTruncOp[1].
end())
15923 if (!ReallyNeedsExt)
15924 return N->getOperand(0);
15931 N->getValueSizeInBits(0), PromBits),
15932 dl,
N->getValueType(0)));
15935 "Invalid extension type");
15938 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
15948 auto isValidForConvert = [IsPPC64](
SDValue &Operand) {
15957 const APInt &Val =
C->getAPIntValue();
15963 if (IsPPC64 && Val.
ult(1ULL << 16))
15977 if (LoadNode->isVolatile())
15998 return (isValidForConvert(
LHS) && isValidForConvert(
RHS));
16008 "CC mus be ISD::SETNE or ISD::SETEQ");
16010 auto getV16i8Load = [&](
const SDValue &Operand) {
16028 LoadNode->getBasePtr(), NewMMO);
16069 SDValue LHSVec = getV16i8Load(
N->getOperand(0));
16070 SDValue RHSVec = getV16i8Load(
N->getOperand(1));
16073 DAG.
getConstant(Intrinsic::ppc_altivec_vcmpequb_p,
DL, MVT::i32);
16076 IntrID, CRSel, LHSVec, RHSVec);
16079 return DAG.
getSetCC(
DL,
N->getValueType(0), PredResult,
16097 auto IsAndWithOne = [](
SDValue &V) {
16108 auto IsCompareWithZero = [](
SDValue &V) {
16115 return (IsAndWithOne(
LHS) && IsCompareWithZero(
RHS)) ||
16116 (IsAndWithOne(
RHS) && IsCompareWithZero(
LHS));
16133 auto MakeXor1 = [&](
SDValue V) {
16134 EVT VT = V.getValueType();
16141 return MakeXor1(
LHS);
16144 return MakeXor1(
RHS);
16161 DAGCombinerInfo &DCI)
const {
16162 if (Subtarget.isISA3_1())
16165 EVT VT =
N->getValueType(0);
16166 if (VT != MVT::i32 && (VT != MVT::i64 || !Subtarget.isPPC64()))
16182 SelectionDAG &DAG = DCI.DAG;
16184 EVT XVT =
X.getValueType();
16188 MVT OpVT = Subtarget.isPPC64() ? MVT::i64 : MVT::i32;
16201 Addc, Addc, Carry);
16204 if (OpVT == MVT::i64 && VT == MVT::i32)
16211 DAGCombinerInfo &DCI)
const {
16213 "Should be called with a SETCC node");
16235 SelectionDAG &DAG = DCI.DAG;
16236 EVT VT =
N->getValueType(0);
16237 EVT OpVT =
LHS.getValueType();
16255 if (Subtarget.hasAltivec() &&
16260 return DAGCombineTruncBoolExt(
N, DCI);
16267 Op.getValueType() == MVT::f64;
16279combineElementTruncationToVectorTruncation(
SDNode *
N,
16280 DAGCombinerInfo &DCI)
const {
16282 "Should be called with a BUILD_VECTOR node");
16284 SelectionDAG &DAG = DCI.DAG;
16287 SDValue FirstInput =
N->getOperand(0);
16289 "The input operand must be an fp-to-int conversion.");
16294 if (FirstConversion == PPCISD::FCTIDZ ||
16295 FirstConversion == PPCISD::FCTIDUZ ||
16296 FirstConversion == PPCISD::FCTIWZ ||
16297 FirstConversion == PPCISD::FCTIWUZ) {
16298 bool IsSplat =
true;
16299 bool Is32Bit = FirstConversion == PPCISD::FCTIWZ ||
16300 FirstConversion == PPCISD::FCTIWUZ;
16303 EVT TargetVT =
N->getValueType(0);
16304 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
16305 SDValue NextOp =
N->getOperand(i);
16306 if (NextOp.
getOpcode() != PPCISD::MFVSR)
16309 if (NextConversion != FirstConversion)
16317 if (
N->getOperand(i) != FirstInput)
16328 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
16329 SDValue In =
N->getOperand(i).getOperand(0);
16339 Ops.push_back(Trunc);
16342 Ops.push_back(
In.isUndef() ? DAG.
getUNDEF(SrcVT) :
In.getOperand(0));
16346 if (FirstConversion == PPCISD::FCTIDZ ||
16347 FirstConversion == PPCISD::FCTIWZ)
16352 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
16354 return DAG.
getNode(Opcode, dl, TargetVT, BV);
16372 static const APInt BasePattern =
APInt(128, 0x8000000000000000ULL) << 64;
16376 if (FullVal == BasePattern)
16377 return std::make_tuple(Uim,
uint8_t{0});
16380 if (FullVal ==
APInt(128, 1))
16381 return std::make_tuple(Uim,
uint8_t{127});
16383 return std::nullopt;
16403 "Expected a BuildVectorSDNode in combineBVLoadsSpecialValue");
16407 EVT VT =
Op.getValueType();
16408 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
16422 for (
const SDValue &Operand :
Op.getNode()->op_values()) {
16432 for (
unsigned Index = 0;
Index < NumElems; ++
Index) {
16436 uint64_t ElemValue =
C->getZExtValue();
16440 ElemValue &= ((1ULL << ElemBits) - 1);
16444 (IsLittleEndian) ? (Index * ElemBits) : (128 - (
Index + 1) * ElemBits);
16447 APInt ElemAPInt(128, ElemValue);
16448 ElemAPInt <<= BitPos;
16451 FullVal |= ElemAPInt;
16458 const auto &[Uim, ShiftAmount] = *UIMOpt;
16462 if (ShiftAmount == 0) {
16467 <<
"combineBVLoadsSpecialValue: Instruction Emitted ";
16468 LxvkqInstr.
dump());
16472 assert(ShiftAmount == 127 &&
"Unexpected lxvkq shift amount value");
16484 DAG.
getMachineNode(PPC::VSRQ, Dl, VT, ShiftAmountVec, ShiftAmountVec),
16487 <<
"\n combineBVLoadsSpecialValue: Instruction Emitted ";
16503 "Should be called with a BUILD_VECTOR node");
16508 if (!
N->getValueType(0).getVectorElementType().isByteSized())
16511 bool InputsAreConsecutiveLoads =
true;
16512 bool InputsAreReverseConsecutive =
true;
16513 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
16514 SDValue FirstInput =
N->getOperand(0);
16515 bool IsRoundOfExtLoad =
false;
16525 N->getNumOperands() == 1)
16528 if (!IsRoundOfExtLoad)
16533 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
16535 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
16538 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
16544 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
16555 InputsAreConsecutiveLoads =
false;
16557 InputsAreReverseConsecutive =
false;
16560 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
16565 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
16566 "The loads cannot be both consecutive and reverse consecutive.");
16570 if (InputsAreConsecutiveLoads) {
16571 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
16575 ReturnSDVal = WideLoad;
16576 }
else if (InputsAreReverseConsecutive) {
16578 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
16583 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
16591 for (
auto *LD : InputLoads)
16593 return ReturnSDVal;
16604 unsigned NumElems =
Input.getValueType().getVectorNumElements();
16610 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16612 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
16614 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
16615 CorrectElems = CorrectElems >> 8;
16616 Elems = Elems >> 8;
16623 EVT VT =
N->getValueType(0);
16627 Input.getValueType().getVectorElementType(),
16661 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
16687 Elems = Elems << 8;
16696 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16697 if (!isSExtOfVecExtract(
N->getOperand(i))) {
16704 int TgtElemArrayIdx;
16705 int InputSize =
Input.getValueType().getScalarSizeInBits();
16706 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
16707 if (InputSize + OutputSize == 40)
16708 TgtElemArrayIdx = 0;
16709 else if (InputSize + OutputSize == 72)
16710 TgtElemArrayIdx = 1;
16711 else if (InputSize + OutputSize == 48)
16712 TgtElemArrayIdx = 2;
16713 else if (InputSize + OutputSize == 80)
16714 TgtElemArrayIdx = 3;
16715 else if (InputSize + OutputSize == 96)
16716 TgtElemArrayIdx = 4;
16720 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
16722 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
16723 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
16724 if (Elems != CorrectElems) {
16740 if (
N->getValueType(0) != MVT::v1i128)
16743 SDValue Operand =
N->getOperand(0);
16750 EVT MemoryType = LD->getMemoryVT();
16754 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
16755 MemoryType == MVT::i32 || MemoryType == MVT::i64;
16758 if (!ValidLDType ||
16764 LD->getChain(), LD->getBasePtr(),
16768 DAG.
getVTList(MVT::v1i128, MVT::Other),
16769 LoadOps, MemoryType, LD->getMemOperand());
16773 DAGCombinerInfo &DCI)
const {
16775 "Should be called with a BUILD_VECTOR node");
16777 SelectionDAG &DAG = DCI.DAG;
16780 if (!Subtarget.hasVSX())
16787 if (FirstInput.
getOpcode() == PPCISD::MFVSR) {
16788 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
16803 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
16812 if (Subtarget.isISA3_1()) {
16818 if (
N->getValueType(0) != MVT::v2f64)
16829 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
16840 if (!Ext1Op || !Ext2Op)
16849 if (FirstElem == 0 && SecondElem == 1)
16850 SubvecIdx = Subtarget.isLittleEndian() ? 1 : 0;
16851 else if (FirstElem == 2 && SecondElem == 3)
16852 SubvecIdx = Subtarget.isLittleEndian() ? 0 : 1;
16858 PPCISD::SINT_VEC_TO_FP : PPCISD::UINT_VEC_TO_FP;
16859 return DAG.
getNode(NodeType, dl, MVT::v2f64,
16864 DAGCombinerInfo &DCI)
const {
16867 "Need an int -> FP conversion node here");
16872 SelectionDAG &DAG = DCI.DAG;
16878 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
16880 if (!
Op.getOperand(0).getValueType().isSimple())
16882 if (
Op.getOperand(0).getValueType().getSimpleVT() <= MVT(MVT::i1) ||
16883 Op.getOperand(0).getValueType().getSimpleVT() > MVT(MVT::i64))
16886 SDValue FirstOperand(
Op.getOperand(0));
16887 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
16888 (FirstOperand.getValueType() == MVT::i8 ||
16889 FirstOperand.getValueType() == MVT::i16);
16890 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
16892 bool DstDouble =
Op.getValueType() == MVT::f64;
16893 unsigned ConvOp =
Signed ?
16894 (DstDouble ? PPCISD::FCFID : PPCISD::FCFIDS) :
16895 (DstDouble ? PPCISD::FCFIDU : PPCISD::FCFIDUS);
16900 SDValue Ops[] = { LDN->getChain(), LDN->getBasePtr(), WidthConst };
16903 Ops, MVT::i8, LDN->getMemOperand());
16908 SDValue ExtOps[] = { Ld, WidthConst };
16910 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
16912 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
16920 if (
Op.getOperand(0).getValueType() == MVT::i32)
16924 "UINT_TO_FP is supported only with FPCVT");
16928 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16933 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16940 Subtarget.hasFPCVT()) ||
16942 SDValue Src =
Op.getOperand(0).getOperand(0);
16943 if (Src.getValueType() == MVT::f32) {
16945 DCI.AddToWorklist(Src.getNode());
16946 }
else if (Src.getValueType() != MVT::f64) {
16958 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
16961 DCI.AddToWorklist(
FP.getNode());
16985 switch (
N->getOpcode()) {
16990 Chain = LD->getChain();
16991 Base = LD->getBasePtr();
16992 MMO = LD->getMemOperand();
17011 MVT VecTy =
N->getValueType(0).getSimpleVT();
17019 Chain =
Load.getValue(1);
17021 PPCISD::XXSWAPD, dl, DAG.
getVTList(MVT::v2f64, MVT::Other), Chain,
Load);
17025 if (VecTy != MVT::v2f64) {
17052 switch (
N->getOpcode()) {
17057 Chain = ST->getChain();
17058 Base = ST->getBasePtr();
17059 MMO = ST->getMemOperand();
17079 SDValue Src =
N->getOperand(SrcOpnd);
17080 MVT VecTy = Src.getValueType().getSimpleVT();
17083 if (VecTy != MVT::v2f64) {
17089 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
17095 StoreOps, VecTy, MMO);
17102 DAGCombinerInfo &DCI)
const {
17105 unsigned Opcode =
N->getOperand(1).getOpcode();
17107 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
17111 &&
"Not a FP_TO_INT Instruction!");
17114 EVT Op1VT =
N->getOperand(1).getValueType();
17117 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
17121 bool ValidTypeForStoreFltAsInt =
17122 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.isPPC64()) ||
17123 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
17126 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
17129 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
17137 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
17152 bool PrevElemFromFirstVec = Mask[0] < NumElts;
17153 for (
int i = 1, e = Mask.size(); i < e; i++) {
17154 if (PrevElemFromFirstVec && Mask[i] < NumElts)
17156 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
17158 PrevElemFromFirstVec = !PrevElemFromFirstVec;
17169 for (
int i = 0, e =
Op.getNumOperands(); i < e; i++) {
17170 FirstOp =
Op.getOperand(i);
17176 for (
int i = 1, e =
Op.getNumOperands(); i < e; i++)
17177 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
17187 Op =
Op.getOperand(0);
17203 int RHSFirstElt,
int RHSLastElt,
int HalfVec,
unsigned LHSNumValidElts,
17204 unsigned RHSNumValidElts,
const PPCSubtarget &Subtarget) {
17206 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - LHSNumValidElts;
17208 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - RHSNumValidElts;
17209 for (
int I = 0,
E = ShuffV.
size();
I <
E; ++
I) {
17210 int Idx = ShuffV[
I];
17211 if (Idx >= LHSFirstElt && Idx <= LHSLastElt)
17212 ShuffV[
I] += LHSEltFixup;
17213 else if (Idx >= RHSFirstElt && Idx <= RHSLastElt)
17214 ShuffV[
I] += RHSEltFixup;
17225 SDLoc dl(OrigSToV);
17228 "Expecting a SCALAR_TO_VECTOR here");
17241 "Cannot produce a permuted scalar_to_vector for one element vector");
17243 unsigned ResultInElt = NumElts / 2;
17249 return DAG.
getNode(PPCISD::SCALAR_TO_VECTOR_PERMUTED, dl, VT,
17254 int HalfVec,
int LHSLastElementDefined,
17255 int RHSLastElementDefined) {
17256 for (
int Index : ShuffV) {
17260 if ((LHSLastElementDefined >= 0) && (Index < HalfVec) &&
17261 (Index > LHSLastElementDefined))
17264 if ((RHSLastElementDefined >= 0) &&
17265 (Index > HalfVec + RHSLastElementDefined))
17272 int ScalarSize,
uint64_t ShuffleEltWidth,
unsigned &NumValidElts,
17273 int FirstElt,
int &LastElt,
SDValue VecShuffOperand,
SDValue SToVNode,
17289 LastElt = (
uint64_t)ScalarSize > ShuffleEltWidth
17290 ? ScalarSize / ShuffleEltWidth - 1 + FirstElt
17293 if (SToVPermuted.
getValueType() != VecShuffOperandType)
17294 SToVPermuted = DAG.
getBitcast(VecShuffOperandType, SToVPermuted);
17295 return SToVPermuted;
17315 int NumElts =
LHS.getValueType().getVectorNumElements();
17318 bool IsLittleEndian = Subtarget.isLittleEndian();
17325 if (!Subtarget.hasDirectMove())
17345 SmallVector<int, 16> ShuffV(Mask);
17348 if (SToVLHS || SToVRHS) {
17351 int ShuffleNumElts = ShuffV.
size();
17352 int HalfVec = ShuffleNumElts / 2;
17358 unsigned LHSNumValidElts = HalfVec;
17359 unsigned RHSNumValidElts = HalfVec;
17364 int LHSFirstElt = 0;
17365 int RHSFirstElt = ShuffleNumElts;
17366 int LHSLastElt = -1;
17367 int RHSLastElt = -1;
17375 int LHSScalarSize = 0;
17376 int RHSScalarSize = 0;
17379 if (!IsLittleEndian && LHSScalarSize >= 64)
17384 if (!IsLittleEndian && RHSScalarSize >= 64)
17387 if (LHSScalarSize != 0)
17389 LHSScalarSize, ShuffleEltWidth, LHSNumValidElts, LHSFirstElt,
17390 LHSLastElt,
LHS, SToVLHS, DAG, Subtarget);
17391 if (RHSScalarSize != 0)
17393 RHSScalarSize, ShuffleEltWidth, RHSNumValidElts, RHSFirstElt,
17394 RHSLastElt,
RHS, SToVRHS, DAG, Subtarget);
17405 ShuffV, LHSFirstElt, LHSLastElt, RHSFirstElt, RHSLastElt, HalfVec,
17406 LHSNumValidElts, RHSNumValidElts, Subtarget);
17432 if (IsLittleEndian) {
17435 if (Mask[0] < NumElts)
17436 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17440 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
17445 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17449 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
17454 if (Mask[0] < NumElts)
17455 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17459 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
17464 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17468 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
17478 if (IsLittleEndian)
17487 DAGCombinerInfo &DCI)
const {
17489 "Not a reverse memop pattern!");
17491 auto IsElementReverse = [](
const ShuffleVectorSDNode *SVN) ->
bool {
17494 auto I =
Mask.rbegin();
17495 auto E =
Mask.rend();
17497 for (;
I !=
E; ++
I) {
17505 SelectionDAG &DAG = DCI.DAG;
17508 if (!
isTypeLegal(VT) || !Subtarget.isLittleEndian() || !Subtarget.hasVSX())
17514 if (!Subtarget.hasP9Vector())
17517 if(!IsElementReverse(SVN))
17524 for (SDUse &Use : LSBase->
uses())
17525 if (
Use.getResNo() == 0 &&
17532 PPCISD::LOAD_VEC_BE, dl, DAG.
getVTList(VT, MVT::Other), LoadOps,
17547 PPCISD::STORE_VEC_BE, dl, DAG.
getVTList(MVT::Other), StoreOps,
17556 if (IntrinsicID == Intrinsic::ppc_stdcx)
17558 else if (IntrinsicID == Intrinsic::ppc_stwcx)
17560 else if (IntrinsicID == Intrinsic::ppc_sthcx)
17562 else if (IntrinsicID == Intrinsic::ppc_stbcx)
17571 if (
N->getOpcode() == PPCISD::ADDC &&
N->hasAnyUseOfValue(1)) {
17575 if (
LHS->getOpcode() == PPCISD::ADDE &&
17586 if (
N->getOpcode() == PPCISD::SUBE) {
17592 if (
LHS ==
RHS &&
LHS.getOpcode() == PPCISD::ADDC) {
17595 if (AddcLHS.
getOpcode() == PPCISD::ADDE &&
17617 SDValue CmpLHS =
N->getOperand(0);
17618 SDValue CmpRHS =
N->getOperand(1);
17619 SDValue TrueVal =
N->getOperand(2);
17620 SDValue FalseVal =
N->getOperand(3);
17634 if (FalseVal.getOpcode() !=
ISD::SRL || !FalseVal.hasOneUse())
17637 SDValue ShiftVal = FalseVal.getOperand(0);
17638 SDValue ShiftAmt = FalseVal.getOperand(1);
17642 if (!ShiftConst || !ShiftConst->getAPIntValue().isMinSignedValue())
17669 if (CtlzArg != CmpLHS)
17677 DAG.
getNode(PPCISD::SRL,
DL, FalseVal.getValueType(), ShiftVal, ShiftAmt);
17724 auto isZeroOrOne = [=](
SDValue &V) {
17726 V.getConstantOperandVal(0) == Intrinsic::ppc_test_data_class)
17731 if (!isZeroOrOne(NonNullConstant))
17741 EVT VType =
N->getValueType(0);
17745 return NewNonNullConstant;
17764 EVT XorVT =
N->getValueType(0);
17765 if ((XorVT != MVT::i32 && XorVT != MVT::i64))
17773 if (!XorConst || !XorConst->
isOne()) {
17775 if (!XorConst || !XorConst->
isOne())
17782 if (!
LHS.hasOneUse())
17790 SelectNode =
LHS.getOperand(0);
17804 if (MachineOpc != PPC::SELECT_CC_I4 && MachineOpc != PPC::SELECT_CC_I8)
17814 if (!ConstOp1 || !ConstOp2)
17818 if (!((ConstOp1->
isOne() && ConstOp2->
isZero()) ||
17827 MachineOpc = (XorVT == MVT::i32) ? PPC::SELECT_CC_I4 : PPC::SELECT_CC_I8;
17829 bool ConstOp1IsOne = ConstOp1->
isOne();
17832 {SelectNode.getOperand(0),
17833 DAG.getConstant(ConstOp1IsOne ? 0 : 1, DL, XorVT),
17834 DAG.getConstant(ConstOp1IsOne ? 1 : 0, DL, XorVT),
17835 SelectNode.getOperand(3)}),
17843 switch (
N->getOpcode()) {
17846 return combineADD(
N, DCI);
17878 return combineSHL(
N, DCI);
17880 return combineSRA(
N, DCI);
17882 return combineSRL(
N, DCI);
17884 return combineMUL(
N, DCI);
17886 case PPCISD::FNMSUB:
17887 return combineFMALike(
N, DCI);
17890 return N->getOperand(0);
17894 return N->getOperand(0);
17900 return N->getOperand(0);
17904 if (
SDValue SECC = combineSignExtendSetCC(
N, DCI))
17912 return DAGCombineExtBoolTrunc(
N, DCI);
17914 return combineTRUNCATE(
N, DCI);
17916 if (
SDValue CSCC = combineSetCC(
N, DCI))
17922 return DAGCombineTruncBoolExt(
N, DCI);
17925 return combineFPToIntToFP(
N, DCI);
17934 EVT Op1VT =
N->getOperand(1).getValueType();
17935 unsigned Opcode =
N->getOperand(1).getOpcode();
17939 SDValue Val = combineStoreFPToInt(
N, DCI);
17953 N->getOperand(1).getNode()->hasOneUse() &&
17954 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
17955 (Subtarget.hasLDBRX() && Subtarget.isPPC64() && Op1VT == MVT::i64))) {
17963 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
17970 if (Op1VT.
bitsGT(mVT)) {
17975 if (Op1VT == MVT::i64)
17980 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
18000 ST->getBasePtr(), ST->getOffset(), MemVT,
18001 ST->getMemOperand(), ST->getAddressingMode(),
18005 return ST->isUnindexed()
18014 if (Subtarget.needsSwapsForVSXMemOps() &&
18015 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
18016 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
18023 EVT VT = LD->getValueType(0);
18029 if (Subtarget.needsSwapsForVSXMemOps() &&
18030 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
18031 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
18042 auto ReplaceTwoFloatLoad = [&]() {
18043 if (VT != MVT::i64)
18058 if (!LD->hasNUsesOfValue(2, 0))
18061 auto UI = LD->user_begin();
18062 while (UI.getUse().getResNo() != 0) ++UI;
18064 while (UI.getUse().getResNo() != 0) ++UI;
18065 SDNode *RightShift = *UI;
18073 if (RightShift->getOpcode() !=
ISD::SRL ||
18075 RightShift->getConstantOperandVal(1) != 32 ||
18076 !RightShift->hasOneUse())
18079 SDNode *Trunc2 = *RightShift->user_begin();
18089 Bitcast->getValueType(0) != MVT::f32)
18095 if (Subtarget.isLittleEndian())
18101 SDValue BasePtr = LD->getBasePtr();
18102 if (LD->isIndexed()) {
18104 "Non-pre-inc AM on PPC?");
18112 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
18113 LD->getPointerInfo(), LD->getAlign(),
18114 MMOFlags, LD->getAAInfo());
18120 LD->getPointerInfo().getWithOffset(4),
18123 if (LD->isIndexed()) {
18137 if (ReplaceTwoFloatLoad())
18140 EVT MemVT = LD->getMemoryVT();
18143 if (LD->isUnindexed() && VT.
isVector() &&
18146 !Subtarget.hasP8Vector() &&
18147 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
18148 VT == MVT::v4f32))) &&
18149 LD->getAlign() < ABIAlignment) {
18151 SDValue Chain = LD->getChain();
18152 SDValue Ptr = LD->getBasePtr();
18153 bool isLittleEndian = Subtarget.isLittleEndian();
18180 MVT PermCntlTy, PermTy, LDTy;
18181 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
18182 : Intrinsic::ppc_altivec_lvsl;
18183 IntrLD = Intrinsic::ppc_altivec_lvx;
18184 IntrPerm = Intrinsic::ppc_altivec_vperm;
18185 PermCntlTy = MVT::v16i8;
18186 PermTy = MVT::v4i32;
18205 SDValue BaseLoadOps[] = { Chain, LDXIntID, Ptr };
18209 BaseLoadOps, LDTy, BaseMMO);
18218 int IncValue = IncOffset;
18235 SDValue ExtraLoadOps[] = { Chain, LDXIntID, Ptr };
18239 ExtraLoadOps, LDTy, ExtraMMO);
18250 if (isLittleEndian)
18252 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
18255 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
18258 Perm = Subtarget.hasAltivec()
18273 bool isLittleEndian = Subtarget.isLittleEndian();
18274 unsigned IID =
N->getConstantOperandVal(0);
18275 Intrinsic::ID Intr = (isLittleEndian ? Intrinsic::ppc_altivec_lvsr
18276 : Intrinsic::ppc_altivec_lvsl);
18277 if (IID == Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
18284 .zext(
Add.getScalarValueSizeInBits()))) {
18285 SDNode *BasePtr =
Add->getOperand(0).getNode();
18286 for (
SDNode *U : BasePtr->users()) {
18288 U->getConstantOperandVal(0) == IID) {
18299 SDNode *BasePtr =
Add->getOperand(0).getNode();
18300 for (
SDNode *U : BasePtr->users()) {
18303 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
18309 V->getConstantOperandVal(0) == IID) {
18321 (IID == Intrinsic::ppc_altivec_vmaxsw ||
18322 IID == Intrinsic::ppc_altivec_vmaxsh ||
18323 IID == Intrinsic::ppc_altivec_vmaxsb)) {
18326 if ((
V1.getSimpleValueType() == MVT::v4i32 ||
18327 V1.getSimpleValueType() == MVT::v8i16 ||
18328 V1.getSimpleValueType() == MVT::v16i8) &&
18333 V1.getOperand(1) == V2) {
18354 switch (
N->getConstantOperandVal(1)) {
18357 case Intrinsic::ppc_altivec_vsum4sbs:
18358 case Intrinsic::ppc_altivec_vsum4shs:
18359 case Intrinsic::ppc_altivec_vsum4ubs: {
18366 APInt APSplatBits, APSplatUndef;
18367 unsigned SplatBitSize;
18370 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
18371 !Subtarget.isLittleEndian());
18373 if (BVNIsConstantSplat && APSplatBits == 0)
18378 case Intrinsic::ppc_vsx_lxvw4x:
18379 case Intrinsic::ppc_vsx_lxvd2x:
18382 if (Subtarget.needsSwapsForVSXMemOps())
18390 if (Subtarget.needsSwapsForVSXMemOps()) {
18391 switch (
N->getConstantOperandVal(1)) {
18394 case Intrinsic::ppc_vsx_stxvw4x:
18395 case Intrinsic::ppc_vsx_stxvd2x:
18404 bool Is64BitBswapOn64BitTgt =
18405 Subtarget.isPPC64() &&
N->getValueType(0) == MVT::i64;
18407 N->getOperand(0).hasOneUse();
18408 if (IsSingleUseNormalLd &&
18409 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
18410 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
18421 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
18422 MVT::i64 : MVT::i32, MVT::Other),
18423 Ops, LD->getMemoryVT(), LD->getMemOperand());
18427 if (
N->getValueType(0) == MVT::i16)
18444 !IsSingleUseNormalLd)
18449 if (!LD->isSimple())
18451 SDValue BasePtr = LD->getBasePtr();
18453 LD->getPointerInfo(), LD->getAlign());
18458 LD->getMemOperand(), 4, 4);
18462 if (Subtarget.isLittleEndian())
18468 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
18477 if (!
N->getOperand(0).hasOneUse() &&
18478 !
N->getOperand(1).hasOneUse() &&
18479 !
N->getOperand(2).hasOneUse()) {
18482 SDNode *VCMPrecNode =
nullptr;
18484 SDNode *LHSN =
N->getOperand(0).getNode();
18486 if (
User->getOpcode() == PPCISD::VCMP_rec &&
18490 VCMPrecNode =
User;
18502 SDNode *FlagUser =
nullptr;
18504 FlagUser ==
nullptr; ++UI) {
18505 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
18518 return SDValue(VCMPrecNode, 0);
18529 SDValue LHS =
N->getOperand(2), RHS =
N->getOperand(3);
18540 auto RHSAPInt = RHS->getAsAPIntVal();
18541 if (!RHSAPInt.isIntN(64))
18544 unsigned Val = RHSAPInt.getZExtValue();
18545 auto isImpossibleCompare = [&]() {
18548 if (Val != 0 && Val != 1) {
18550 return N->getOperand(0);
18553 N->getOperand(0),
N->getOperand(4));
18558 unsigned StoreWidth = 0;
18561 if (
SDValue Impossible = isImpossibleCompare())
18573 SDValue Ops[] = {LHS.getOperand(0), LHS.getOperand(2), LHS.getOperand(3),
18577 PPCISD::STORE_COND, dl,
18579 MemNode->getMemoryVT(), MemNode->getMemOperand());
18583 if (
N->getOperand(0) == LHS.getValue(1))
18594 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other, InChain,
18596 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
18602 assert(isDot &&
"Can't compare against a vector result!");
18604 if (
SDValue Impossible = isImpossibleCompare())
18607 bool BranchOnWhenPredTrue = (CC ==
ISD::SETEQ) ^ (Val == 0);
18614 EVT VTs[] = { LHS.getOperand(2).getValueType(), MVT::Glue };
18619 switch (LHS.getConstantOperandVal(1)) {
18635 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other,
N->getOperand(0),
18638 N->getOperand(4), CompNode.
getValue(1));
18643 return DAGCombineBuildVector(
N, DCI);
18650 return DAGCombineBitcast(
N, DCI);
18661 EVT VT =
N->getValueType(0);
18662 if (VT == MVT::i64 && !Subtarget.isPPC64())
18664 if ((VT != MVT::i32 && VT != MVT::i64) ||
18672 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
18692 const APInt &DemandedElts,
18694 unsigned Depth)
const {
18696 switch (
Op.getOpcode()) {
18698 case PPCISD::LBRX: {
18701 Known.Zero = 0xFFFF0000;
18704 case PPCISD::ADDE: {
18705 if (
Op.getResNo() == 0) {
18710 Known.Zero = ~1ULL;
18715 switch (
Op.getConstantOperandVal(0)) {
18717 case Intrinsic::ppc_altivec_vcmpbfp_p:
18718 case Intrinsic::ppc_altivec_vcmpeqfp_p:
18719 case Intrinsic::ppc_altivec_vcmpequb_p:
18720 case Intrinsic::ppc_altivec_vcmpequh_p:
18721 case Intrinsic::ppc_altivec_vcmpequw_p:
18722 case Intrinsic::ppc_altivec_vcmpequd_p:
18723 case Intrinsic::ppc_altivec_vcmpequq_p:
18724 case Intrinsic::ppc_altivec_vcmpgefp_p:
18725 case Intrinsic::ppc_altivec_vcmpgtfp_p:
18726 case Intrinsic::ppc_altivec_vcmpgtsb_p:
18727 case Intrinsic::ppc_altivec_vcmpgtsh_p:
18728 case Intrinsic::ppc_altivec_vcmpgtsw_p:
18729 case Intrinsic::ppc_altivec_vcmpgtsd_p:
18730 case Intrinsic::ppc_altivec_vcmpgtsq_p:
18731 case Intrinsic::ppc_altivec_vcmpgtub_p:
18732 case Intrinsic::ppc_altivec_vcmpgtuh_p:
18733 case Intrinsic::ppc_altivec_vcmpgtuw_p:
18734 case Intrinsic::ppc_altivec_vcmpgtud_p:
18735 case Intrinsic::ppc_altivec_vcmpgtuq_p:
18742 switch (
Op.getConstantOperandVal(1)) {
18745 case Intrinsic::ppc_load2r:
18747 Known.Zero = 0xFFFF0000;
18756 switch (Subtarget.getCPUDirective()) {
18778 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
18786 uint64_t LoopSize = 0;
18787 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
18789 LoopSize +=
TII->getInstSizeInBytes(J);
18794 if (LoopSize > 16 && LoopSize <= 32)
18808 if (Constraint.
size() == 1) {
18809 switch (Constraint[0]) {
18827 }
else if (Constraint ==
"wc") {
18829 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
18830 Constraint ==
"wf" || Constraint ==
"ws" ||
18831 Constraint ==
"wi" || Constraint ==
"ww") {
18844 Value *CallOperandVal =
info.CallOperandVal;
18847 if (!CallOperandVal)
18854 else if ((
StringRef(constraint) ==
"wa" ||
18866 switch (*constraint) {
18896std::pair<unsigned, const TargetRegisterClass *>
18900 if (Constraint.
size() == 1) {
18902 switch (Constraint[0]) {
18904 if (VT == MVT::i64 && Subtarget.isPPC64())
18905 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
18906 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
18908 if (VT == MVT::i64 && Subtarget.isPPC64())
18909 return std::make_pair(0U, &PPC::G8RCRegClass);
18910 return std::make_pair(0U, &PPC::GPRCRegClass);
18916 if (Subtarget.hasSPE()) {
18917 if (VT == MVT::f32 || VT == MVT::i32)
18918 return std::make_pair(0U, &PPC::GPRCRegClass);
18919 if (VT == MVT::f64 || VT == MVT::i64)
18920 return std::make_pair(0U, &PPC::SPERCRegClass);
18922 if (VT == MVT::f32 || VT == MVT::i32)
18923 return std::make_pair(0U, &PPC::F4RCRegClass);
18924 if (VT == MVT::f64 || VT == MVT::i64)
18925 return std::make_pair(0U, &PPC::F8RCRegClass);
18929 if (Subtarget.hasAltivec() && VT.
isVector())
18930 return std::make_pair(0U, &PPC::VRRCRegClass);
18931 else if (Subtarget.hasVSX())
18933 return std::make_pair(0U, &PPC::VFRCRegClass);
18936 return std::make_pair(0U, &PPC::CRRCRegClass);
18938 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
18940 return std::make_pair(0U, &PPC::CRBITRCRegClass);
18941 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
18942 Constraint ==
"wf" || Constraint ==
"wi") &&
18943 Subtarget.hasVSX()) {
18947 return std::make_pair(0U, &PPC::VSRCRegClass);
18948 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18949 return std::make_pair(0U, &PPC::VSSRCRegClass);
18950 return std::make_pair(0U, &PPC::VSFRCRegClass);
18951 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
18952 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18953 return std::make_pair(0U, &PPC::VSSRCRegClass);
18955 return std::make_pair(0U, &PPC::VSFRCRegClass);
18956 }
else if (Constraint ==
"lr") {
18957 if (VT == MVT::i64)
18958 return std::make_pair(0U, &PPC::LR8RCRegClass);
18960 return std::make_pair(0U, &PPC::LRRCRegClass);
18965 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
18969 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
18970 int VSNum = atoi(Constraint.
data() + 3);
18971 assert(VSNum >= 0 && VSNum <= 63 &&
18972 "Attempted to access a vsr out of range");
18974 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
18975 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
18980 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
18981 int RegNum = atoi(Constraint.
data() + 2);
18982 if (RegNum > 31 || RegNum < 0)
18984 if (VT == MVT::f32 || VT == MVT::i32)
18985 return Subtarget.hasSPE()
18986 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
18987 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
18988 if (VT == MVT::f64 || VT == MVT::i64)
18989 return Subtarget.hasSPE()
18990 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
18991 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
18995 std::pair<unsigned, const TargetRegisterClass *> R =
19004 if (R.first && VT == MVT::i64 && Subtarget.isPPC64() &&
19005 PPC::GPRCRegClass.contains(R.first))
19006 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
19007 PPC::sub_32, &PPC::G8RCRegClass),
19008 &PPC::G8RCRegClass);
19011 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
19012 R.first = PPC::CR0;
19013 R.second = &PPC::CRRCRegClass;
19017 if (Subtarget.isAIXABI() && !TM.getAIXExtendedAltivecABI()) {
19018 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
19019 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
19020 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
19021 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
19022 "default AIX AltiVec ABI and cannot be used\n";
19032 std::vector<SDValue> &
Ops,
19037 if (Constraint.
size() > 1)
19040 char Letter = Constraint[0];
19055 EVT TCVT = MVT::i64;
19096 if (Result.getNode()) {
19097 Ops.push_back(Result);
19108 if (
I.getNumOperands() <= 1)
19112 auto IntrinsicID =
Ops[1].getNode()->getAsZExtVal();
19113 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
19114 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
19117 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
19133 if (Ty->isVectorTy() && AM.
BaseOffs != 0 && !Subtarget.hasP9Vector())
19145 switch (AM.
Scale) {
19173 unsigned Depth =
Op.getConstantOperandVal(0);
19197 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
19205 unsigned Depth =
Op.getConstantOperandVal(0);
19212 bool isPPC64 = PtrVT == MVT::i64;
19218 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
19220 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
19226 FrameAddr, MachinePointerInfo());
19230#define GET_REGISTER_MATCHER
19231#include "PPCGenAsmMatcher.inc"
19235 bool IsPPC64 = Subtarget.isPPC64();
19247 if ((IsPPC64 && Reg == PPC::R2) || Reg == PPC::R0)
19253 Reg = Reg.id() - PPC::R0 + PPC::X0;
19260 if (Subtarget.is32BitELFABI())
19265 if (Subtarget.isAIXABI())
19279 return Subtarget.isGVIndirectSymbol(
G->getGlobal());
19295 case Intrinsic::ppc_atomicrmw_xchg_i128:
19296 case Intrinsic::ppc_atomicrmw_add_i128:
19297 case Intrinsic::ppc_atomicrmw_sub_i128:
19298 case Intrinsic::ppc_atomicrmw_nand_i128:
19299 case Intrinsic::ppc_atomicrmw_and_i128:
19300 case Intrinsic::ppc_atomicrmw_or_i128:
19301 case Intrinsic::ppc_atomicrmw_xor_i128:
19302 case Intrinsic::ppc_cmpxchg_i128:
19304 Info.memVT = MVT::i128;
19305 Info.ptrVal =
I.getArgOperand(0);
19307 Info.align =
Align(16);
19312 case Intrinsic::ppc_atomic_load_i128:
19314 Info.memVT = MVT::i128;
19315 Info.ptrVal =
I.getArgOperand(0);
19317 Info.align =
Align(16);
19321 case Intrinsic::ppc_atomic_store_i128:
19323 Info.memVT = MVT::i128;
19324 Info.ptrVal =
I.getArgOperand(2);
19326 Info.align =
Align(16);
19330 case Intrinsic::ppc_altivec_lvx:
19331 case Intrinsic::ppc_altivec_lvxl:
19332 case Intrinsic::ppc_altivec_lvebx:
19333 case Intrinsic::ppc_altivec_lvehx:
19334 case Intrinsic::ppc_altivec_lvewx:
19335 case Intrinsic::ppc_vsx_lxvd2x:
19336 case Intrinsic::ppc_vsx_lxvw4x:
19337 case Intrinsic::ppc_vsx_lxvd2x_be:
19338 case Intrinsic::ppc_vsx_lxvw4x_be:
19339 case Intrinsic::ppc_vsx_lxvl:
19340 case Intrinsic::ppc_vsx_lxvll: {
19343 case Intrinsic::ppc_altivec_lvebx:
19346 case Intrinsic::ppc_altivec_lvehx:
19349 case Intrinsic::ppc_altivec_lvewx:
19352 case Intrinsic::ppc_vsx_lxvd2x:
19353 case Intrinsic::ppc_vsx_lxvd2x_be:
19363 Info.ptrVal =
I.getArgOperand(0);
19366 Info.align =
Align(1);
19371 case Intrinsic::ppc_altivec_stvx:
19372 case Intrinsic::ppc_altivec_stvxl:
19373 case Intrinsic::ppc_altivec_stvebx:
19374 case Intrinsic::ppc_altivec_stvehx:
19375 case Intrinsic::ppc_altivec_stvewx:
19376 case Intrinsic::ppc_vsx_stxvd2x:
19377 case Intrinsic::ppc_vsx_stxvw4x:
19378 case Intrinsic::ppc_vsx_stxvd2x_be:
19379 case Intrinsic::ppc_vsx_stxvw4x_be:
19380 case Intrinsic::ppc_vsx_stxvl:
19381 case Intrinsic::ppc_vsx_stxvll: {
19384 case Intrinsic::ppc_altivec_stvebx:
19387 case Intrinsic::ppc_altivec_stvehx:
19390 case Intrinsic::ppc_altivec_stvewx:
19393 case Intrinsic::ppc_vsx_stxvd2x:
19394 case Intrinsic::ppc_vsx_stxvd2x_be:
19404 Info.ptrVal =
I.getArgOperand(1);
19407 Info.align =
Align(1);
19412 case Intrinsic::ppc_stdcx:
19413 case Intrinsic::ppc_stwcx:
19414 case Intrinsic::ppc_sthcx:
19415 case Intrinsic::ppc_stbcx: {
19417 auto Alignment =
Align(8);
19419 case Intrinsic::ppc_stdcx:
19422 case Intrinsic::ppc_stwcx:
19424 Alignment =
Align(4);
19426 case Intrinsic::ppc_sthcx:
19428 Alignment =
Align(2);
19430 case Intrinsic::ppc_stbcx:
19432 Alignment =
Align(1);
19437 Info.ptrVal =
I.getArgOperand(0);
19439 Info.align = Alignment;
19453 const AttributeList &FuncAttributes)
const {
19457 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
19458 if (
Op.isMemset() && Subtarget.hasVSX()) {
19459 uint64_t TailSize =
Op.size() % 16;
19463 if (TailSize > 2 && TailSize <= 4) {
19468 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
19473 if (Subtarget.isPPC64()) {
19484 assert(Ty->isIntegerTy());
19486 unsigned BitSize = Ty->getPrimitiveSizeInBits();
19487 return !(BitSize == 0 || BitSize > 64);
19495 return NumBits1 == 64 && NumBits2 == 32;
19503 return NumBits1 == 64 && NumBits2 == 32;
19510 EVT MemVT = LD->getMemoryVT();
19511 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
19512 (Subtarget.isPPC64() && MemVT == MVT::i32)) &&
19528 "invalid fpext types");
19530 if (DestVT == MVT::f128)
19545 unsigned *
Fast)
const {
19559 !Subtarget.allowsUnalignedFPAccess())
19563 if (Subtarget.hasVSX()) {
19564 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
19565 VT != MVT::v4f32 && VT != MVT::v4i32)
19572 if (VT == MVT::ppcf128)
19587 if (!ConstNode->getAPIntValue().isSignedIntN(64))
19595 int64_t
Imm = ConstNode->getSExtValue();
19600 uint64_t UImm =
static_cast<uint64_t
>(
Imm);
19616 if (Subtarget.hasSPE() || Subtarget.useSoftFloat())
19618 switch (Ty->getScalarType()->getTypeID()) {
19623 return Subtarget.hasP9Vector();
19631 if (!
I->hasOneUse())
19635 assert(
User &&
"A single use instruction with no uses.");
19637 switch (
I->getOpcode()) {
19638 case Instruction::FMul: {
19640 if (
User->getOpcode() != Instruction::FSub &&
19641 User->getOpcode() != Instruction::FAdd)
19648 bool AllowContract =
I->getFastMathFlags().allowContract() &&
19649 User->getFastMathFlags().allowContract();
19655 case Instruction::Load: {
19668 if (
User->getOpcode() != Instruction::Store)
19688 static const MCPhysReg ScratchRegs[] = {
19689 PPC::X12, PPC::LR8, PPC::CTR8, 0
19692 return ScratchRegs;
19697 return Subtarget.isPPC64() ? PPC::X3 : PPC::R3;
19702 return Subtarget.isPPC64() ? PPC::X4 : PPC::R4;
19707 EVT VT ,
unsigned DefinedValues)
const {
19708 if (VT == MVT::v2i64)
19709 return Subtarget.hasDirectMove();
19711 if (Subtarget.hasVSX())
19738 return PPCISD::FNMSUB;
19739 case PPCISD::FNMSUB:
19745 bool LegalOps,
bool OptForSize,
19747 unsigned Depth)
const {
19751 unsigned Opc =
Op.getOpcode();
19752 EVT VT =
Op.getValueType();
19756 case PPCISD::FNMSUB:
19776 if (Flags.hasNoSignedZeros()) {
19780 N0Cost,
Depth + 1);
19784 N1Cost,
Depth + 1);
19786 if (NegN0 && N0Cost <= N1Cost) {
19787 Cost = std::min(N0Cost, N2Cost);
19789 }
else if (NegN1) {
19790 Cost = std::min(N1Cost, N2Cost);
19810 if (M.getStackProtectorGuard() ==
"tls" || Subtarget.isTargetLinux())
19816 bool ForCodeSize)
const {
19817 if (!VT.
isSimple() || !Subtarget.hasVSX())
19827 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
19832 APSInt IntResult(16,
false);
19837 if (IsExact && IntResult <= 15 && IntResult >= -16)
19839 return Imm.isZero();
19842 return Imm.isPosZero();
19854 unsigned Opcode =
N->getOpcode();
19874 if (Mask->getZExtValue() == OpSizeInBits - 1)
19881 DAGCombinerInfo &DCI)
const {
19882 EVT VT =
N->getValueType(0);
19885 unsigned Opc =
N->getOpcode();
19887 "Unexpected opcode.");
19894 if (EltTy != MVT::i64 && EltTy != MVT::i32)
19899 bool AddSplatCase =
false;
19903 AddSplatCase =
true;
19907 if (!AddSplatCase) {
19911 unsigned SplatBitSize;
19913 APInt APSplatBits, APSplatUndef;
19915 bool BVNIsConstantSplat =
19917 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
19918 if (!BVNIsConstantSplat || SplatBitSize != EltBits)
19929 if (SplatBits == (EltBits - 1)) {
19933 NewOpc = PPCISD::SHL;
19936 NewOpc = PPCISD::SRL;
19939 NewOpc = PPCISD::SRA;
19943 return DCI.DAG.getNode(NewOpc,
DL, VT, N0, SplatOnes);
19951 if (EltTy != MVT::i64 || SplatBits != 1)
19954 return DCI.DAG.getNode(
ISD::ADD, SDLoc(
N), VT, N0, N0);
19957SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19961 if (
N->getValueType(0).isVector())
19962 return combineVectorShift(
N, DCI);
19966 if (!Subtarget.isISA3_0() || !Subtarget.isPPC64() ||
19969 N->getValueType(0) != MVT::i64)
19984 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
19990SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19994 if (
N->getValueType(0).isVector())
19995 return combineVectorShift(
N, DCI);
20000SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20004 if (
N->getValueType(0).isVector())
20005 return combineVectorShift(
N, DCI);
20016 if (!Subtarget.isPPC64())
20022 auto isZextOfCompareWithConstant = [](
SDValue Op) {
20024 Op.getValueType() != MVT::i64)
20028 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
20029 Cmp.getOperand(0).getValueType() != MVT::i64)
20033 int64_t NegConstant = 0 -
Constant->getSExtValue();
20042 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
20043 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
20046 if (LHSHasPattern && !RHSHasPattern)
20048 else if (!LHSHasPattern && !RHSHasPattern)
20052 EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
20055 SDValue Z = Cmp.getOperand(0);
20057 int64_t NegConstant = 0 -
Constant->getSExtValue();
20070 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
20088 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
20118 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
20121 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
20129 if (!GSDN || !ConstNode)
20157 EVT VT =
N->getValueType(0);
20158 if (!Subtarget.hasVSX())
20162 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
20174 unsigned NumOfEles =
RHS.getNumOperands();
20175 for (
unsigned i = 0; i < NumOfEles; ++i) {
20177 if (!CN || CN->getSExtValue() != 1)
20192SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20214 DAGCombinerInfo &DCI)
const {
20216 if (Subtarget.useCRBits()) {
20218 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
20219 return CRTruncValue;
20226 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
20229 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
20239 EltToExtract = EltToExtract ? 0 : 1;
20249 return DCI.DAG.getNode(
20251 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
20256SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20257 SelectionDAG &DAG = DCI.DAG;
20260 if (!ConstOpOrElement)
20268 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne, EVT VT) ->
bool {
20269 switch (this->Subtarget.getCPUDirective()) {
20292 return IsAddOne && IsNeg ? VT.
isVector() :
true;
20296 EVT VT =
N->getValueType(0);
20301 APInt MulAmtAbs = MulAmt.
abs();
20303 if ((MulAmtAbs - 1).isPowerOf2()) {
20307 if (!IsProfitable(IsNeg,
true, VT))
20320 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
20324 if (!IsProfitable(IsNeg,
false, VT))
20345 DAGCombinerInfo &DCI)
const {
20349 SDNodeFlags
Flags =
N->getFlags();
20350 EVT VT =
N->getValueType(0);
20351 SelectionDAG &DAG = DCI.DAG;
20352 unsigned Opc =
N->getOpcode();
20354 bool LegalOps = !DCI.isBeforeLegalizeOps();
20362 if (!
Flags.hasNoSignedZeros())
20378bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
20380 if (!Subtarget.is64BitELFABI())
20390 if (!TM.Options.GuaranteedTailCallOpt &&
DisableSCO)
20395 if (!Callee ||
Callee->isVarArg())
20408bool PPCTargetLowering::
20409isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
20414 if (CI->getBitWidth() > 64)
20416 int64_t ConstVal = CI->getZExtValue();
20418 (
isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
20427PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
20433 if ((Flags & FlagSet) == FlagSet)
20436 if ((Flags & FlagSet) == FlagSet)
20439 if ((Flags & FlagSet) == FlagSet)
20442 if ((Flags & FlagSet) == FlagSet)
20463 if ((FrameIndexAlign % 4) != 0)
20464 FlagSet &=
~PPC::MOF_RPlusSImm16Mult4;
20465 if ((FrameIndexAlign % 16) != 0)
20466 FlagSet &=
~PPC::MOF_RPlusSImm16Mult16;
20470 if ((FrameIndexAlign % 4) == 0)
20472 if ((FrameIndexAlign % 16) == 0)
20486 if ((
Imm & 0x3) == 0)
20488 if ((
Imm & 0xf) == 0)
20494 const APInt &ConstImm = CN->getAPIntValue();
20513 const APInt &ConstImm = CN->getAPIntValue();
20523 }
else if (
RHS.getOpcode() == PPCISD::Lo && !
RHS.getConstantOperandVal(1))
20534 return (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR ||
20543unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
20548 if (!Subtarget.hasP9Vector())
20553 if (Subtarget.hasPrefixInstrs())
20556 if (Subtarget.hasSPE())
20565 unsigned ParentOp = Parent->
getOpcode();
20569 if ((ID == Intrinsic::ppc_vsx_lxvp) || (ID == Intrinsic::ppc_vsx_stxvp)) {
20570 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
20582 if (LSB->isIndexed())
20588 assert(MN &&
"Parent should be a MemSDNode!");
20593 "Not expecting scalar integers larger than 16 bytes!");
20596 else if (
Size == 32)
20603 else if (
Size == 256) {
20604 assert(Subtarget.pairedVectorMemops() &&
20605 "256-bit vectors are only available when paired vector memops is "
20613 else if (MemVT == MVT::f128 || MemVT.
isVector())
20644 FlagSet &= ~PPC::MOF_NoExt;
20649 bool IsNonP1034BitConst =
20653 IsNonP1034BitConst)
20666 int16_t ForceXFormImm = 0;
20669 Disp =
N.getOperand(0);
20670 Base =
N.getOperand(1);
20681 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
20682 Disp =
N.getOperand(0);
20683 Base =
N.getOperand(1);
20688 Disp = DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20697 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
20703 if (PartVT == MVT::f64 &&
20704 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
20713SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
20717 EVT RetVT =
Op.getValueType();
20724 EVT ArgVT =
N.getValueType();
20728 Entry.IsZExt = !Entry.IsSExt;
20729 Args.push_back(Entry);
20737 (RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
20750SDValue PPCTargetLowering::lowerLibCallBasedOnType(
20751 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
20753 if (
Op.getValueType() == MVT::f32)
20754 return lowerToLibCall(LibCallFloatName,
Op, DAG);
20756 if (
Op.getValueType() == MVT::f64)
20757 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
20762bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
20763 SDNodeFlags
Flags =
Op.getNode()->getFlags();
20764 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
20768bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
20769 return Op.getNode()->getFlags().hasApproximateFuncs();
20772bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
20776SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
20777 const char *LibCallFloatName,
20778 const char *LibCallDoubleNameFinite,
20779 const char *LibCallFloatNameFinite,
20782 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
20785 if (!isLowringToMASSFiniteSafe(
Op))
20786 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
20789 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
20790 LibCallDoubleNameFinite,
Op, DAG);
20794 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
20795 "__xl_powf_finite",
Op, DAG);
20799 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
20800 "__xl_sinf_finite",
Op, DAG);
20804 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
20805 "__xl_cosf_finite",
Op, DAG);
20809 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
20810 "__xl_logf_finite",
Op, DAG);
20814 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
20815 "__xl_log10f_finite",
Op, DAG);
20819 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
20820 "__xl_expf_finite",
Op, DAG);
20845 unsigned Flags = computeMOFlags(Parent,
N, DAG);
20856 assert(Subtarget.isUsingPCRelativeCalls() &&
20857 "Must be using PC-Relative calls when a valid PC-Relative node is "
20887 Disp =
N.getOperand(1).getOperand(0);
20892 Base =
N.getOperand(0);
20900 EVT CNType = CN->getValueType(0);
20901 uint64_t CNImm = CN->getZExtValue();
20912 if ((CNType == MVT::i32 ||
isInt<32>(CNImm)) &&
20914 int32_t Addr = (int32_t)CNImm;
20919 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
20935 unsigned Opcode =
N.getOpcode();
20943 Base =
N.getOperand(0);
20962 Base = FI ?
N :
N.getOperand(1);
20963 Disp = FI ? DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20974 bool IsVarArg)
const {
20984 return Subtarget.isPPC64() && Subtarget.hasQuadwordAtomics();
21021 return Intrinsic::ppc_atomicrmw_xchg_i128;
21023 return Intrinsic::ppc_atomicrmw_add_i128;
21025 return Intrinsic::ppc_atomicrmw_sub_i128;
21027 return Intrinsic::ppc_atomicrmw_and_i128;
21029 return Intrinsic::ppc_atomicrmw_or_i128;
21031 return Intrinsic::ppc_atomicrmw_xor_i128;
21033 return Intrinsic::ppc_atomicrmw_nand_i128;
21041 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
21045 Value *IncrLo = Builder.CreateTrunc(Incr, Int64Ty,
"incr_lo");
21047 Builder.CreateTrunc(Builder.CreateLShr(Incr, 64), Int64Ty,
"incr_hi");
21048 Value *LoHi = Builder.CreateIntrinsic(
21050 {AlignedAddr, IncrLo, IncrHi});
21051 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
21052 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
21053 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
21054 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
21055 return Builder.CreateOr(
21056 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
21063 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
21069 Value *CmpLo = Builder.CreateTrunc(CmpVal, Int64Ty,
"cmp_lo");
21071 Builder.CreateTrunc(Builder.CreateLShr(CmpVal, 64), Int64Ty,
"cmp_hi");
21072 Value *NewLo = Builder.CreateTrunc(NewVal, Int64Ty,
"new_lo");
21074 Builder.CreateTrunc(Builder.CreateLShr(NewVal, 64), Int64Ty,
"new_hi");
21077 Builder.CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
21079 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
21080 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
21081 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
21082 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
21083 return Builder.CreateOr(
21084 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
21088 return Subtarget.useCRBits();
21093bool PPCTargetLowering::isShuffleMaskLegal(
ArrayRef<int> Mask,
EVT VT)
const {
21104 DAGCombinerInfo &DCI)
const {
21109 EVT ResVT =
N->getValueType(0);
21111 EVT SrcVT = Src.getValueType();
21116 if (ResVT != MVT::i16 && ResVT != MVT::i8)
21119 GenerateVBPERM(DAG, dl, Src, SrcVT, TruncResVT, IsLittleEndian);
21132 bool IsV16i8 = (ResVT == MVT::v16i1 && SrcVT == MVT::v16i8);
21133 bool IsV8i16 = (ResVT == MVT::v8i1 && SrcVT == MVT::v8i16);
21134 bool IsV8i8 = (ResVT == MVT::v8i1 && SrcVT == MVT::v8i8);
21136 if (!IsV16i8 && !IsV8i16 && !IsV8i8)
21144 SmallVector<int, 16> BitIndices(16, 128);
21148 BitIndices[Idx] = EltSize * (NumElts - Idx) - 1;
21149 if (IsV8i8 && IsLE)
21150 BitIndices[Idx] += 64;
21153 std::reverse(BitIndices.begin(), BitIndices.end());
21155 for (
auto Idx : BitIndices)
21160 DAG.
getConstant(Intrinsic::ppc_altivec_vbpermq, dl, MVT::i32),
21168 bool BVNIsConstantSplat,
21169 unsigned SplatBitSize)
const {
21171 if (!BVNIsConstantSplat || !Subtarget.hasVSX() || !Subtarget.hasP8Vector() ||
21172 Subtarget.hasP10Vector())
21175 EVT VT =
Op->getValueType(0);
21176 if (!((SplatBitSize == 64 && VT == MVT::v2f64) ||
21177 (SplatBitSize == 32 && VT == MVT::v4f32)))
21184 APFloat APFloatVal = CN->getValueAPF();
21186 APSInt IntResult(16,
false);
21189 if (!(IsExact && IntResult <= 15 && IntResult >= -16 && !APFloatVal.
isZero()))
21192 int64_t
IntVal = IntResult.getSExtValue();
21197 if (SplatBitSize == 64)
21200 DAG.
getConstant(Intrinsic::ppc_vsx_xvcvsxwdp, dl, MVT::i32), IntSplat);
21202 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< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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).
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static bool isConstantOrUndef(const SDValue Op)
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 or function.
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.
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...
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
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.
Register getExceptionSelectorRegister(ExceptionHandling EH, const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
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.
ConstraintType getConstraintType(StringRef Constraint) const override
getConstraintType - Given a constraint, return the type of constraint it is for this target.
const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const override
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
bool shallExtractConstSplatVectorElementToStore(Type *VectorTy, unsigned ElemSizeInBits, unsigned &Index) const override
Return true if the target shall perform extract vector element and store given that the vector is kno...
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op, const AttributeList &FuncAttributes) const override
It returns EVT::Other if the type should be determined using generic target-independent logic.
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
SDValue expandVSXStoreForLE(SDNode *N, DAGCombinerInfo &DCI) const
void CollectTargetIntrinsicOperands(const CallInst &I, SmallVectorImpl< SDValue > &Ops, SelectionDAG &DAG) const override
unsigned getStackProbeSize(const MachineFunction &MF) const
Register getExceptionPointerRegister(ExceptionHandling EH, const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
PPCTargetLowering(const PPCTargetMachine &TM, const PPCSubtarget &STI)
bool useLoadStackGuardNode(const Module &M) const override
Override to support customized stack guard loading.
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster than a pair of fmul and fadd i...
MachineBasicBlock * EmitAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned BinOpcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const override
Is unaligned memory access allowed for the given type, and is it fast relative to software emulation.
bool shouldExpandBuildVectorWithShuffles(EVT VT, unsigned DefinedValues) const override
bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
Similar to the 16-bit case but for instructions that take a 34-bit displacement field (prefixed loads...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
bool isJumpTableRelative() const override
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
PPC::AddrMode SelectOptimalAddrMode(const SDNode *Parent, SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign Align) const
SelectOptimalAddrMode - Based on a node N and it's Parent (a MemSDNode), compute the address flags of...
bool SelectAddressPCRel(SDValue N, SDValue &Base) const
SelectAddressPCRel - Represent the specified address as pc relative to be represented as [pc+imm].
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the ISD::SETCC ValueType
bool SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressEVXRegReg - Given the specified addressed, check to see if it can be more efficiently re...
bool isLegalICmpImmediate(int64_t Imm) const override
isLegalICmpImmediate - Return true if the specified immediate is legal icmp immediate,...
MachineBasicBlock * EmitPartwordAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned Opcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
bool isAccessedAsGotIndirect(SDValue N) const
Align getPrefLoopAlignment(MachineLoop *ML) const override
Return the preferred loop alignment.
bool shouldInlineQuadwordAtomics() const
Instruction * emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Inserts in the IR a target-specific intrinsic specifying a fence.
bool isLegalAddImmediate(int64_t Imm) const override
isLegalAddImmediate - Return true if the specified immediate is legal add immediate,...
Common code between 32-bit and 64-bit PowerPC targets.
static PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
Wrapper class representing virtual and physical registers.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
This class provides iterator support for SDUse operands that use a specific SDNode.
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
LLVM_ABI void dump() const
Dump this node, for debugging.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
iterator_range< value_op_iterator > op_values() const
iterator_range< use_iterator > uses()
SDNodeFlags getFlags() const
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
user_iterator user_begin() const
Provide iteration support to walk over all users of an SDNode.
static use_iterator use_end()
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node, in exactly one operand.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
bool isMachineOpcode() const
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getMachineOpcode() const
unsigned getOpcode() const
unsigned getNumOperands() const
static SectionKind getMetadata()
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
LLVM_ABI SDValue getStackArgumentTokenFactor(SDValue Chain)
Compute a TokenFactor to force all the incoming stack arguments to be loaded from the stack.
const TargetSubtargetInfo & getSubtarget() const
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDValue getFreeze(SDValue V)
Return a freeze using the SDLoc of the value operand.
LLVM_ABI SDValue makeEquivalentMemoryOrdering(SDValue OldChain, SDValue NewMemOpChain)
If an existing load has uses of its chain, create a token factor node with that chain and the new mem...
LLVM_ABI SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, LocationSize Size=LocationSize::precise(0), const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false, SDNodeFlags Flags={})
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
bool willNotOverflowSub(bool IsSigned, SDValue N0, SDValue N1) const
Determine if the result of the sub of 2 nodes can never overflow.
LLVM_ABI Align getEVTAlign(EVT MemoryVT) const
Compute the default alignment value for the given type.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
LLVM_ABI SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align DstAlign, Align SrcAlign, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
const TargetLowering & getTargetLoweringInfo() const
static constexpr unsigned MaxRecursionDepth
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
LLVM_ABI bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
LLVM_ABI SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, SDValue Offset, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
LLVM_ABI SDValue getTokenFactor(const SDLoc &DL, SmallVectorImpl< SDValue > &Vals)
Creates a new TokenFactor containing Vals.
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Helper function to build ISD::STORE nodes.
LLVM_ABI bool areNonVolatileConsecutiveLoads(LoadSDNode *LD, LoadSDNode *Base, unsigned Bytes, int Dist) const
Return true if loads are next to each other and can be merged.
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI SDValue getMDNode(const MDNode *MD)
Return an MDNodeSDNode which holds an MDNode.
LLVM_ABI void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
LLVM_ABI SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV)
Returns an ISD::VECTOR_SHUFFLE node semantically equivalent to the shuffle node in input but with swa...
LLVM_ABI SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
LLVM_ABI bool SignBitIsZero(SDValue Op, unsigned Depth=0) const
Return true if the sign bit of Op is known to be zero.
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
LLVM_ABI SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI bool isKnownNeverZero(SDValue Op, unsigned Depth=0) const
Test whether the given SDValue is known to contain non-zero value(s).
LLVM_ABI SDValue getBoolExtOrTrunc(SDValue Op, const SDLoc &SL, EVT VT, EVT OpVT)
Convert Op, which must be of integer type, to the integer type VT, by using an extension appropriate ...
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
LLVM_ABI SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
LLVM_ABI SDValue getBoolConstant(bool V, const SDLoc &DL, EVT VT, EVT OpVT)
Create a true or false constant of type VT using the target's BooleanContent for type OpVT.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
LLVM_ABI bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
LLVM_ABI SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVM_ABI SDValue getCondCode(ISD::CondCode Cond)
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
LLVM_ABI SDValue getMCSymbol(MCSymbol *Sym, EVT VT)
LLVM_ABI SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
LLVM_ABI std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
LLVM_ABI SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
int getMaskElt(unsigned Idx) const
ArrayRef< int > getMask() const
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getValue() const
Represent a constant reference to a string, i.e.
constexpr size_t size() const
Get the string size.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
Class to represent struct types.
Information about stack frame layout on the target.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
virtual bool isShuffleMaskLegal(ArrayRef< int >, EVT) const
Targets can use this to indicate that they only support some VECTOR_SHUFFLE operations,...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual bool shouldExpandBuildVectorWithShuffles(EVT, unsigned DefinedValues) const
void setMinimumBitTestCmps(unsigned Val)
Set the minimum of largest of number of comparisons to generate BitTest.
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
MachineBasicBlock * emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const
Replace/modify any TargetFrameIndex operands with a targte-dependent sequence of memory operands that...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
virtual AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *RMW) const
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
void setMinStackArgumentAlignment(Align Alignment)
Set the minimum stack alignment of an argument.
MVT getVectorIdxTy(const DataLayout &DL) const
Returns the type to be used for the index operand of: ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT...
const TargetMachine & getTargetMachine() const
unsigned MaxLoadsPerMemcmp
Specify maximum number of load instructions per memcmp call.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
void setIndexedLoadAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed load does or does not work with the specified type and indicate w...
void setPrefLoopAlignment(Align Alignment)
Set the target's preferred loop alignment.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Sched::Preference getSchedulingPreference() const
Return target scheduling preference.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
bool isOperationCustom(unsigned Op, EVT VT) const
Return true if the operation uses custom lowering, regardless of whether the type is legal or not.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
bool hasBigEndianPartOrdering(EVT VT, const DataLayout &DL) const
When splitting a value of the specified type into parts, does the Lo or Hi part come first?
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL) const
Returns the type for the shift amount of a shift opcode.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
virtual Align getPrefLoopAlignment(MachineLoop *ML=nullptr) const
Return the preferred loop alignment.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
void setIndexedStoreAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed store does or does not work with the specified type and indicate ...
virtual bool isJumpTableRelative() const
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setMinimumJumpTableEntries(unsigned Val)
Indicate the minimum number of blocks to generate jump tables.
void setPartialReduceMLAAction(unsigned Opc, MVT AccVT, MVT InputVT, LegalizeAction Action)
Indicate how a PARTIAL_REDUCE_U/SMLA node with Acc type AccVT and Input type InputVT should be treate...
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
unsigned MaxLoadsPerMemcmpOptSize
Likewise for functions with the OptSize attribute.
void setMinCmpXchgSizeInBits(unsigned SizeInBits)
Sets the minimum cmpxchg or ll/sc size supported by the backend.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
unsigned GatherAllAliasesMaxDepth
Depth that GatherAllAliases should continue looking for chain dependencies when trying to find a more...
NegatibleCost
Enum that specifies when a float negation is beneficial.
virtual bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const
Returns true if arguments should be sign-extended in lib calls.
std::vector< ArgListEntry > ArgListTy
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
void setJumpIsExpensive(bool isExpensive=true)
Tells the code generator not to expand logic operations on comparison predicates into separate sequen...
virtual MCSymbol * getFunctionEntryPointSymbol(const GlobalValue *Func, const TargetMachine &TM) const
If supported, return the function entry point symbol.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
SDValue lowerCmpEqZeroToCtlzSrl(SDValue Op, SelectionDAG &DAG) const
void softenSetCCOperands(SelectionDAG &DAG, EVT VT, SDValue &NewLHS, SDValue &NewRHS, ISD::CondCode &CCCode, const SDLoc &DL, const SDValue OldLHS, const SDValue OldRHS) const
Soften the operands of a comparison.
SDValue getCheaperNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, unsigned Depth=0) const
This is the helper function to return the newly negated expression only when the cost is cheaper.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool isPositionIndependent() const
virtual SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const
Returns relocation base for the given PIC jumptable.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
TargetLowering(const TargetLowering &)=delete
bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node, SDValue &Chain) const
Check whether a given call node is in tail position within its function.
virtual SDValue getSqrtResultForDenormInput(SDValue Operand, SelectionDAG &DAG) const
Return a target-dependent result if the input operand is not suitable for use with a square root esti...
virtual bool useLoadStackGuardNode(const Module &M) const
If this function returns true, SelectionDAGBuilder emits a LOAD_STACK_GUARD node when it is lowering ...
virtual unsigned combineRepeatedFPDivisors() const
Indicate whether this target prefers to combine FDIVs with the same divisor.
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
virtual SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG, const DenormalMode &Mode, SDNodeFlags Flags={}) const
Return a target-dependent comparison result if the input operand is suitable for use with a square ro...
virtual bool isGAPlusOffset(SDNode *N, const GlobalValue *&GA, int64_t &Offset) const
Returns true (and the GlobalValue and the offset) if the node is a GlobalAddress + offset.
virtual unsigned getJumpTableEncoding() const
Return the entry encoding for a jump table in the current function.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::LibcallImpl LibcallImpl, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
Primary interface to the complete machine description for the target machine.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
const STC & getSubtarget(const Function &F) const
This method returns a pointer to the specified type of TargetSubtargetInfo.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
virtual TargetLoweringObjectFile * getObjFileLowering() const
Reloc::Model getRelocationModel() const
Returns the code generation relocation model.
bool shouldAssumeDSOLocal(const GlobalValue *GV) const
CodeModel::Model getCodeModel() const
Returns the code model.
bool getFunctionSections() const
Return true if functions should be emitted into their own section, corresponding to -ffunction-sectio...
unsigned PPCGenScalarMASSEntries
Enables scalar MASS conversions.
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
LLVM_ABI bool isEmptyTy() const
Return true if this type is empty, that is, it has no elements or all of its elements are empty.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
@ FloatTyID
32-bit floating point type
@ DoubleTyID
64-bit floating point type
@ FP128TyID
128-bit floating point type (112-bit significand)
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isFunctionTy() const
True if this is an instance of FunctionType.
bool isIntegerTy() const
True if this is an instance of IntegerType.
A Use represents the edge between a Value definition and its users.
User * getUser() const
Returns the User that contains this Use.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI bool isConstantSplatVectorAllOnes(const SDNode *N, bool BuildVectorOnly=false)
Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where all of the elements are ~0 ...
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
@ PARTIAL_REDUCE_SMLA
PARTIAL_REDUCE_[U|S]MLA(Accumulator, Input1, Input2) The partial reduction nodes sign or zero extend ...
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ BSWAP
Byte Swap and Counting operators.
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ INIT_TRAMPOLINE
INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ SET_ROUNDING
Set rounding mode.
@ SIGN_EXTEND
Conversion operators.
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ BR
Control flow instructions. These all have token chains.
@ PREFETCH
PREFETCH - This corresponds to a prefetch intrinsic.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ SSUBO
Same for subtraction.
@ BR_JT
BR_JT - Jumptable branch.
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ GET_ROUNDING
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimumNumber or maximumNumber on two values,...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ INLINEASM_BR
INLINEASM_BR - Branching version of inline asm. Used by asm-goto.
@ EH_DWARF_CFA
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA),...
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ INLINEASM
INLINEASM - Represents an inline asm block.
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ CALLSEQ_START
CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of a call sequence,...
@ GET_DYNAMIC_AREA_OFFSET
GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of the most recent dynamic alloca.
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ ADJUST_TRAMPOLINE
ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
bool isEXTLoad(const SDNode *N)
Returns true if the specified node is a EXTLOAD.
LLVM_ABI bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
bool isSEXTLoad(const SDNode *N)
Returns true if the specified node is a SEXTLOAD.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
bool isUnsignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs an unsigned comparison when used with intege...
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
This namespace contains an enum with a value for every intrinsic/builtin function known by LLVM.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
@ MO_TLSLDM_FLAG
MO_TLSLDM_FLAG - on AIX the ML relocation type is only valid for a reference to a TOC symbol from the...
@ MO_PIC_LO_FLAG
MO_PIC_LO_FLAG = MO_PIC_FLAG | MO_LO.
@ MO_TPREL_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TPREL_FLAG.
@ MO_GOT_TPREL_PCREL_FLAG
MO_GOT_TPREL_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_GOT_PCREL_FLAG
MO_GOT_PCREL_FLAG = MO_PCREL_FLAG | MO_GOT_FLAG.
@ MO_TLSGDM_FLAG
MO_TLSGDM_FLAG - If this bit is set the symbol reference is relative to the region handle of TLS Gene...
@ MO_PCREL_FLAG
MO_PCREL_FLAG - If this bit is set, the symbol reference is relative to the current instruction addre...
@ MO_TLSLD_FLAG
MO_TLSLD_FLAG - If this bit is set the symbol reference is relative to TLS Local Dynamic model.
@ MO_TLS_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TLS.
@ MO_PLT
On PPC, the 12 bits are not enough for all target operand flags.
@ MO_TLS
Symbol for VK_TLS fixup attached to an ADD instruction.
@ MO_TPREL_FLAG
MO_TPREL_FLAG - If this bit is set, the symbol reference is relative to the thread pointer and the sy...
@ MO_LO
MO_LO, MO_HA - lo16(symbol) and ha16(symbol)
@ MO_GOT_TLSLD_PCREL_FLAG
MO_GOT_TLSLD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_HA_FLAG
MO_PIC_HA_FLAG = MO_PIC_FLAG | MO_HA.
@ MO_TLSGD_FLAG
MO_TLSGD_FLAG - If this bit is set the symbol reference is relative to TLS General Dynamic model for ...
@ MO_GOT_TLSGD_PCREL_FLAG
MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_FLAG
MO_PIC_FLAG - If this bit is set, the symbol reference is relative to the function's picbase,...
@ MFOCRF
R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
@ VADD_SPLAT
VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded during instruction selection to optimi...
@ PPC32_PICGOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
@ SRA_ADDZE
The combination of sra[wd]i and addze used to implemented signed integer division by a power of 2.
Define some predicates that are used for node matching.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
SDValue get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG)
get_VSPLTI_elt - If this is a build_vector of constants which can be formed by using a vspltis[bhw] i...
bool isXXBRDShuffleMask(ShuffleVectorSDNode *N)
isXXBRDShuffleMask - Return true if this is a shuffle mask suitable for a XXBRD instruction.
bool isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for a VRGH* instruction with the ...
bool isVPKUDUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUDUMShuffleMask - Return true if this is the shuffle mask for a VPKUDUM instruction.
bool isVMRGEOShuffleMask(ShuffleVectorSDNode *N, bool CheckEven, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGEOShuffleMask - Return true if this is a shuffle mask suitable for a VMRGEW or VMRGOW instructi...
bool isXXBRQShuffleMask(ShuffleVectorSDNode *N)
isXXBRQShuffleMask - Return true if this is a shuffle mask suitable for a XXBRQ instruction.
bool isXXBRWShuffleMask(ShuffleVectorSDNode *N)
isXXBRWShuffleMask - Return true if this is a shuffle mask suitable for a XXBRW instruction.
bool isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXPERMDIShuffleMask - Return true if this is a shuffle mask suitable for a XXPERMDI instruction.
bool isXXBRHShuffleMask(ShuffleVectorSDNode *N)
isXXBRHShuffleMask - Return true if this is a shuffle mask suitable for a XXBRH instruction.
unsigned getSplatIdxForPPCMnemonics(SDNode *N, unsigned EltSize, SelectionDAG &DAG)
getSplatIdxForPPCMnemonics - Return the splat index as a value that is appropriate for PPC mnemonics ...
bool isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXSLDWIShuffleMask - Return true if this is a shuffle mask suitable for a XXSLDWI instruction.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo, const LibcallLoweringInfo *LibcallLowering)
int isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift amount, otherwise return -1.
bool isVMRGLShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for a VRGL* instruction with the ...
bool isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, unsigned &InsertAtByte, bool &Swap, bool IsLE)
isXXINSERTWMask - Return true if this VECTOR_SHUFFLE can be handled by the XXINSERTW instruction intr...
bool isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize)
isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand specifies a splat of a singl...
bool isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a VPKUWUM instruction.
bool isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a VPKUHUM instruction.
Invariant opcodes: All instruction sets have these as their low opcodes.
@ XTY_ER
External reference.
initializer< Ty > init(const Ty &Val)
constexpr uint64_t PointerSize
aarch64 pointer size.
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
NodeAddr< NodeBase * > Node
NodeAddr< FuncNode * > Func
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
static bool isIndirectCall(const MachineInstr &MI)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool checkConvertToNonDenormSingle(APFloat &ArgAPFloat)
LLVM_ABI void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
RelativeUniformCounterPtr Values
@ Known
Known to have no common set bits.
LLVM_ABI SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
bool isIntS16Immediate(SDNode *N, int16_t &Imm)
isIntS16Immediate - This method tests to see if the node is either a 32-bit or 64-bit immediate,...
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
static bool isRunOfOnes64(uint64_t Val, unsigned &MB, unsigned &ME)
bool isa_and_nonnull(const Y &Val)
bool RetCC_PPC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
bool CC_PPC64_ELF(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
unsigned M1(unsigned Val)
bool isReleaseOrStronger(AtomicOrdering AO)
auto dyn_cast_or_null(const Y &Val)
constexpr bool has_single_bit(T Value) noexcept
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
bool convertToNonDenormSingle(APInt &ArgAPInt)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
bool CC_PPC32_SVR4_ByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
bool CC_PPC32_SVR4(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
constexpr RegState getDefRegState(bool B)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
bool RetCC_PPC_Cold(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
@ Success
The lock was released successfully.
LLVM_ABI bool isOneOrOneSplat(SDValue V, bool AllowUndefs=false)
Return true if the value is a constant 1 integer or a splatted vector of a constant 1 integer (with n...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
const unsigned PerfectShuffleTable[6561+1]
AtomicOrdering
Atomic ordering for LLVM's memory model.
bool isIntS34Immediate(SDNode *N, int64_t &Imm)
isIntS34Immediate - This method tests if value of node given can be accurately represented as a sign ...
To bit_cast(const From &from) noexcept
@ Mul
Product of integers.
@ Xor
Bitwise or logical XOR of integers.
@ And
Bitwise or logical AND of integers.
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
@ Fast
Assign the register banks as fast as possible (default).
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
LLVM_ABI bool isPhysRegUsedAfter(Register Reg, MachineBasicBlock::iterator MBI)
Check if physical register Reg is used after MBI.
unsigned M0(unsigned Val)
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
bool isAcquireOrStronger(AtomicOrdering AO)
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
constexpr unsigned BitWidth
bool CC_PPC32_SVR4_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME)
Returns true iff Val consists of one contiguous run of 1s with any number of 0s on either side.
@ Increment
Incrementally increasing token ID.
@ Enabled
Convert any .debug_str_offsets tables to DWARF64 if needed.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
MCRegisterClass TargetRegisterClass
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This is used by foldLoadsRecursive() to capture a Root Load node which is of type or(load,...
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Represent subnormal handling kind for floating point instruction inputs and outputs.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool bitsLT(EVT VT) const
Return true if this has less bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
LLVM_ABI std::string getEVTString() const
This function returns value type as a string, e.g. "i32".
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
unsigned getByValSize() const
void setByValSize(unsigned S)
Align getNonZeroByValAlign() const
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
bool isConstant() const
Returns true if we know the value of all bits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Structure that collects some common arguments that get passed around between the functions for call l...
const CallingConv::ID CallConv
These are IR-level optimization flags that may be propagated to SDNodes.
void setNoFPExcept(bool b)
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
CallLoweringInfo & setIsPostTypeLegalization(bool Value=true)
CallLoweringInfo & setLibCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setZExtResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setTailCall(bool Value=true)
CallLoweringInfo & setSExtResult(bool Value=true)
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
CallLoweringInfo & setChain(SDValue InChain)
bool isBeforeLegalizeOps() const
bool isAfterLegalizeDAG() const
LLVM_ABI void AddToWorklist(SDNode *N)
bool isBeforeLegalize() const
LLVM_ABI SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)
This structure is used to pass arguments to makeLibCall function.