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");
181 initializeAddrModeMap();
184 bool isPPC64 = Subtarget.isPPC64();
186 const MVT RegVT = Subtarget.getScalarIntVT();
194 if (!Subtarget.hasEFPU2())
211 if (!Subtarget.hasP10Vector()) {
240 if (Subtarget.isISA3_0()) {
273 if (!Subtarget.hasSPE()) {
280 if (Subtarget.useCRBits()) {
283 if (isPPC64 || Subtarget.hasFPCVT()) {
349 if (Subtarget.isISA3_0()) {
384 if (!Subtarget.hasSPE()) {
389 if (Subtarget.hasVSX()) {
394 if (Subtarget.hasFSQRT()) {
399 if (Subtarget.hasFPRND()) {
440 if (Subtarget.hasSPE()) {
450 if (Subtarget.hasSPE())
454 if (!Subtarget.hasFSQRT() && !(Subtarget.hasFRSQRTE() && Subtarget.hasFRE()))
457 if (!Subtarget.hasFSQRT() &&
458 !(Subtarget.hasFRSQRTES() && Subtarget.hasFRES()))
461 if (Subtarget.hasFCPSGN()) {
469 if (Subtarget.hasFPRND()) {
483 if (Subtarget.isISA3_1()) {
489 (Subtarget.hasP9Vector() && isPPC64) ?
Custom :
Expand);
493 if (Subtarget.isISA3_0()) {
513 if (!Subtarget.useCRBits()) {
526 if (!Subtarget.useCRBits())
529 if (Subtarget.hasFPU()) {
540 if (!Subtarget.useCRBits())
545 if (Subtarget.hasSPE()) {
569 if (Subtarget.hasDirectMove() && isPPC64) {
629 if (Subtarget.is64BitELFABI()) {
640 }
else if (Subtarget.is32BitELFABI()) {
648 if (Subtarget.is32BitELFABI())
664 if (Subtarget.isISA3_0() && isPPC64) {
692 if (Subtarget.hasSPE()) {
714 if (Subtarget.has64BitSupport()) {
729 if (Subtarget.hasLFIWAX() || isPPC64) {
735 if (Subtarget.hasSPE()) {
745 if (Subtarget.hasFPCVT()) {
746 if (Subtarget.has64BitSupport()) {
767 if (Subtarget.use64BitRegs()) {
785 if (Subtarget.has64BitSupport()) {
792 if (Subtarget.hasVSX()) {
805 if (Subtarget.hasAltivec()) {
806 for (
MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
821 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
834 if (Subtarget.hasVSX()) {
843 if (Subtarget.hasP8Altivec() && (VT.SimpleTy != MVT::v1i128)) {
853 if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
927 if (!Subtarget.hasP8Vector()) {
969 if (Subtarget.hasAltivec())
970 for (
auto VT : {MVT::v4i32, MVT::v8i16, MVT::v16i8})
973 if (Subtarget.hasP8Altivec())
984 if (Subtarget.hasVSX()) {
990 if (Subtarget.hasP8Altivec())
995 if (Subtarget.isISA3_1()) {
1041 if (Subtarget.hasVSX()) {
1044 if (Subtarget.hasP8Vector()) {
1048 if (Subtarget.hasDirectMove() && isPPC64) {
1097 if (Subtarget.hasP8Vector())
1106 if (Subtarget.hasP8Altivec()) {
1133 if (Subtarget.isISA3_1())
1236 if (Subtarget.hasP8Altivec()) {
1241 if (Subtarget.hasP9Vector()) {
1246 if (Subtarget.useCRBits()) {
1306 }
else if (Subtarget.hasVSX()) {
1331 for (
MVT VT : {MVT::f32, MVT::f64}) {
1350 if (Subtarget.hasP9Altivec()) {
1351 if (Subtarget.isISA3_1()) {
1374 if (Subtarget.hasP10Vector()) {
1379 if (Subtarget.pairedVectorMemops()) {
1384 if (Subtarget.hasMMA()) {
1385 if (Subtarget.isISAFuture()) {
1401 if (Subtarget.has64BitSupport())
1404 if (Subtarget.isISA3_1())
1422 if (Subtarget.hasAltivec()) {
1439 if (Subtarget.hasFPCVT())
1442 if (Subtarget.useCRBits())
1451 if (Subtarget.useCRBits()) {
1457 if (Subtarget.useCRBits()) {
1473 auto CPUDirective = Subtarget.getCPUDirective();
1474 switch (CPUDirective) {
1497 if (Subtarget.enableMachineScheduler())
1571void PPCTargetLowering::initializeAddrModeMap() {
1622 if (MaxAlign == MaxMaxAlign)
1625 if (MaxMaxAlign >= 32 &&
1626 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1627 MaxAlign =
Align(32);
1628 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1630 MaxAlign =
Align(16);
1634 if (EltAlign > MaxAlign)
1635 MaxAlign = EltAlign;
1637 for (
auto *EltTy : STy->elements()) {
1640 if (EltAlign > MaxAlign)
1641 MaxAlign = EltAlign;
1642 if (MaxAlign == MaxMaxAlign)
1655 if (Subtarget.hasAltivec())
1661 return Subtarget.useSoftFloat();
1665 return Subtarget.hasSPE();
1673 Type *VectorTy,
unsigned ElemSizeInBits,
unsigned &Index)
const {
1674 if (!Subtarget.isPPC64() || !Subtarget.hasVSX())
1678 if (VTy->getScalarType()->isIntegerTy()) {
1680 if (ElemSizeInBits == 32) {
1681 Index = Subtarget.isLittleEndian() ? 2 : 1;
1684 if (ElemSizeInBits == 64) {
1685 Index = Subtarget.isLittleEndian() ? 1 : 0;
1696 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1713 return CFP->getValueAPF().isZero();
1718 return CFP->getValueAPF().isZero();
1726 return Op < 0 ||
Op == Val;
1738 if (ShuffleKind == 0) {
1741 for (
unsigned i = 0; i != 16; ++i)
1744 }
else if (ShuffleKind == 2) {
1747 for (
unsigned i = 0; i != 16; ++i)
1750 }
else if (ShuffleKind == 1) {
1751 unsigned j = IsLE ? 0 : 1;
1752 for (
unsigned i = 0; i != 8; ++i)
1769 if (ShuffleKind == 0) {
1772 for (
unsigned i = 0; i != 16; i += 2)
1776 }
else if (ShuffleKind == 2) {
1779 for (
unsigned i = 0; i != 16; i += 2)
1783 }
else if (ShuffleKind == 1) {
1784 unsigned j = IsLE ? 0 : 2;
1785 for (
unsigned i = 0; i != 8; i += 2)
1806 if (!Subtarget.hasP8Vector())
1810 if (ShuffleKind == 0) {
1813 for (
unsigned i = 0; i != 16; i += 4)
1819 }
else if (ShuffleKind == 2) {
1822 for (
unsigned i = 0; i != 16; i += 4)
1828 }
else if (ShuffleKind == 1) {
1829 unsigned j = IsLE ? 0 : 4;
1830 for (
unsigned i = 0; i != 8; i += 4)
1847 unsigned LHSStart,
unsigned RHSStart) {
1848 if (
N->getValueType(0) != MVT::v16i8)
1850 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
1851 "Unsupported merge size!");
1853 for (
unsigned i = 0; i != 8/UnitSize; ++i)
1854 for (
unsigned j = 0; j != UnitSize; ++j) {
1856 LHSStart+j+i*UnitSize) ||
1858 RHSStart+j+i*UnitSize))
1873 if (ShuffleKind == 1)
1875 else if (ShuffleKind == 2)
1880 if (ShuffleKind == 1)
1882 else if (ShuffleKind == 0)
1898 if (ShuffleKind == 1)
1900 else if (ShuffleKind == 2)
1905 if (ShuffleKind == 1)
1907 else if (ShuffleKind == 0)
1957 unsigned RHSStartValue) {
1958 if (
N->getValueType(0) != MVT::v16i8)
1961 for (
unsigned i = 0; i < 2; ++i)
1962 for (
unsigned j = 0; j < 4; ++j)
1964 i*RHSStartValue+j+IndexOffset) ||
1966 i*RHSStartValue+j+IndexOffset+8))
1988 unsigned indexOffset = CheckEven ? 4 : 0;
1989 if (ShuffleKind == 1)
1991 else if (ShuffleKind == 2)
1997 unsigned indexOffset = CheckEven ? 0 : 4;
1998 if (ShuffleKind == 1)
2000 else if (ShuffleKind == 0)
2016 if (
N->getValueType(0) != MVT::v16i8)
2023 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2026 if (i == 16)
return -1;
2031 if (ShiftAmt < i)
return -1;
2036 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2038 for (++i; i != 16; ++i)
2041 }
else if (ShuffleKind == 1) {
2043 for (++i; i != 16; ++i)
2050 ShiftAmt = 16 - ShiftAmt;
2059 EVT VT =
N->getValueType(0);
2060 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2061 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2064 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2068 if (
N->getMaskElt(0) % EltSize != 0)
2073 unsigned ElementBase =
N->getMaskElt(0);
2076 if (ElementBase >= 16)
2081 for (
unsigned i = 1; i != EltSize; ++i)
2082 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2085 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2087 if (
N->getMaskElt(i) < 0) {
2088 for (
unsigned j = 1; j != EltSize; ++j)
2089 if (
N->getMaskElt(i + j) >= 0)
2092 for (
unsigned j = 0; j != EltSize; ++j)
2093 if (
N->getMaskElt(i + j) !=
N->getMaskElt(j))
2110 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2111 "Unexpected element width.");
2112 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2114 unsigned NumOfElem = 16 / Width;
2115 unsigned MaskVal[16];
2116 for (
unsigned i = 0; i < NumOfElem; ++i) {
2117 MaskVal[0] =
N->getMaskElt(i * Width);
2118 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2120 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2124 for (
unsigned int j = 1; j < Width; ++j) {
2125 MaskVal[j] =
N->getMaskElt(i * Width + j);
2126 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2136 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2141 unsigned M0 =
N->getMaskElt(0) / 4;
2142 unsigned M1 =
N->getMaskElt(4) / 4;
2143 unsigned M2 =
N->getMaskElt(8) / 4;
2144 unsigned M3 =
N->getMaskElt(12) / 4;
2145 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2146 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2151 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2152 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2153 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2154 InsertAtByte = IsLE ? 12 : 0;
2159 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2160 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2161 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2162 InsertAtByte = IsLE ? 8 : 4;
2167 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2168 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2169 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2170 InsertAtByte = IsLE ? 4 : 8;
2175 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2176 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2177 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2178 InsertAtByte = IsLE ? 0 : 12;
2185 if (
N->getOperand(1).isUndef()) {
2188 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2189 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2190 InsertAtByte = IsLE ? 12 : 0;
2193 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2194 InsertAtByte = IsLE ? 8 : 4;
2197 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2198 InsertAtByte = IsLE ? 4 : 8;
2201 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2202 InsertAtByte = IsLE ? 0 : 12;
2211 bool &Swap,
bool IsLE) {
2212 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2218 unsigned M0 =
N->getMaskElt(0) / 4;
2219 unsigned M1 =
N->getMaskElt(4) / 4;
2220 unsigned M2 =
N->getMaskElt(8) / 4;
2221 unsigned M3 =
N->getMaskElt(12) / 4;
2225 if (
N->getOperand(1).isUndef()) {
2226 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2227 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2230 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2236 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2240 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2245 ShiftElts = (8 -
M0) % 8;
2246 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2251 ShiftElts = (4 -
M0) % 4;
2256 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2261 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2273 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2278 for (
int i = 0; i < 16; i += Width)
2279 if (
N->getMaskElt(i) != i + Width - 1)
2310 bool &Swap,
bool IsLE) {
2311 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2317 unsigned M0 =
N->getMaskElt(0) / 8;
2318 unsigned M1 =
N->getMaskElt(8) / 8;
2319 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2323 if (
N->getOperand(1).isUndef()) {
2324 if ((
M0 |
M1) < 2) {
2325 DM = IsLE ? (((
~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2333 if (
M0 > 1 &&
M1 < 2) {
2343 DM = (((
~M1) & 1) << 1) + ((~
M0) & 1);
2348 }
else if (
M0 > 1 &&
M1 < 2) {
2356 DM = (
M0 << 1) + (
M1 & 1);
2371 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2376 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2392 unsigned EltSize = 16/
N->getNumOperands();
2393 if (EltSize < ByteSize) {
2394 unsigned Multiple = ByteSize/EltSize;
2396 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2399 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2400 if (
N->getOperand(i).isUndef())
continue;
2404 if (!UniquedVals[i&(Multiple-1)].
getNode())
2405 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2406 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2416 bool LeadingZero =
true;
2417 bool LeadingOnes =
true;
2418 for (
unsigned i = 0; i != Multiple-1; ++i) {
2419 if (!UniquedVals[i].
getNode())
continue;
2426 if (!UniquedVals[Multiple-1].
getNode())
2433 if (!UniquedVals[Multiple-1].
getNode())
2444 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2445 if (
N->getOperand(i).isUndef())
continue;
2447 OpVal =
N->getOperand(i);
2448 else if (OpVal !=
N->getOperand(i))
2454 unsigned ValSizeInBytes = EltSize;
2457 Value = CN->getZExtValue();
2459 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2466 if (ValSizeInBytes < ByteSize)
return SDValue();
2477 if (MaskVal == 0)
return SDValue();
2497 Imm = (int16_t)
N->getAsZExtVal();
2498 if (
N->getValueType(0) == MVT::i32)
2499 return Imm == (int32_t)
N->getAsZExtVal();
2501 return Imm == (int64_t)
N->getAsZExtVal();
2519 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2527 for (
SDNode *U :
N->users()) {
2529 if (Memop->getMemoryVT() == MVT::f64) {
2530 Base =
N.getOperand(0);
2531 Index =
N.getOperand(1);
2574 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2576 if (
N.getOperand(1).getOpcode() == PPCISD::Lo)
2579 Base =
N.getOperand(0);
2580 Index =
N.getOperand(1);
2582 }
else if (
N.getOpcode() ==
ISD::OR) {
2584 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2596 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2597 Base =
N.getOperand(0);
2598 Index =
N.getOperand(1);
2668 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2674 Base =
N.getOperand(0);
2677 }
else if (
N.getOperand(1).getOpcode() == PPCISD::Lo) {
2679 assert(!
N.getOperand(1).getConstantOperandVal(1) &&
2680 "Cannot handle constant offsets yet!");
2681 Disp =
N.getOperand(1).getOperand(0);
2686 Base =
N.getOperand(0);
2689 }
else if (
N.getOpcode() ==
ISD::OR) {
2692 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2706 Base =
N.getOperand(0);
2719 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm))) {
2722 CN->getValueType(0));
2727 if ((CN->getValueType(0) == MVT::i32 ||
2728 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2729 (!EncodingAlignment ||
2730 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2731 int Addr = (int)CN->getZExtValue();
2738 unsigned Opc = CN->getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2759 if (
N.getValueType() != MVT::i64)
2772 Base =
N.getOperand(0);
2788 Base =
N.getOperand(0);
2821 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2822 Base =
N.getOperand(0);
2823 Index =
N.getOperand(1);
2845 if (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR)
2866 EVT MemVT = LD->getMemoryVT();
2873 if (!ST.hasP8Vector())
2878 if (!ST.hasP9Vector())
2890 if (
Use.getResNo() == 0 &&
2892 Use.
getUser()->getOpcode() != PPCISD::SCALAR_TO_VECTOR_PERMUTED)
2912 Ptr = LD->getBasePtr();
2913 VT = LD->getMemoryVT();
2914 Alignment = LD->getAlign();
2916 Ptr = ST->getBasePtr();
2917 VT = ST->getMemoryVT();
2918 Alignment = ST->getAlign();
2957 if (VT != MVT::i64) {
2962 if (Alignment <
Align(4))
2972 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
2989 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3031 EVT VT = Subtarget.getScalarIntVT();
3033 : Subtarget.isAIXABI()
3038 PPCISD::TOC_ENTRY, dl, DAG.
getVTList(VT, MVT::Other),
Ops, VT,
3045 EVT PtrVT =
Op.getValueType();
3051 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3052 if (Subtarget.isUsingPCRelativeCalls()) {
3057 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, ConstPool);
3061 return getTOCEntry(DAG, SDLoc(CP), GA);
3064 unsigned MOHiFlag, MOLoFlag;
3068 if (IsPIC && Subtarget.isSVR4ABI()) {
3071 return getTOCEntry(DAG, SDLoc(CP), GA);
3094 if (Subtarget.isPPC64() || Subtarget.isAIXABI())
3101 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3118 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3131 EVT PtrVT =
Op.getValueType();
3149 return getTOCEntry(DAG,
SDLoc(JT), GA);
3152 unsigned MOHiFlag, MOLoFlag;
3156 if (IsPIC && Subtarget.isSVR4ABI()) {
3159 return getTOCEntry(DAG, SDLoc(GA), GA);
3169 EVT PtrVT =
Op.getValueType();
3174 if (Subtarget.isUsingPCRelativeCalls()) {
3185 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3188 return getTOCEntry(DAG, SDLoc(BASDN), GA);
3197 unsigned MOHiFlag, MOLoFlag;
3207 if (Subtarget.isAIXABI())
3208 return LowerGlobalTLSAddressAIX(
Op, DAG);
3210 return LowerGlobalTLSAddressLinux(
Op, DAG);
3232 if (
I.getOpcode() == Instruction::Call)
3234 if (
Function *CF = CI->getCalledFunction())
3235 if (CF->isDeclaration() &&
3236 CF->getIntrinsicID() == Intrinsic::threadlocal_address)
3244 unsigned TLSGVCnt = TLSGV.
size();
3254 <<
" function is using the TLS-IE model for TLS-LD access.\n");
3267 const GlobalValue *GV = GA->
getGlobal();
3269 bool Is64Bit = Subtarget.isPPC64();
3273 if (Subtarget.hasAIXShLibTLSModelOpt())
3283 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3284 bool HasAIXSmallTLSGlobalAttr =
false;
3287 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3291 if (GVar->hasAttribute(
"aix-small-tls"))
3292 HasAIXSmallTLSGlobalAttr =
true;
3311 if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) &&
3312 IsTLSLocalExecModel) {
3317 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA, TLSReg);
3327 TLSReg = DAG.
getNode(PPCISD::GET_TPOINTER, dl, PtrVT);
3332 if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr)
3334 "currently only supported on AIX (64-bit mode).");
3336 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, VariableOffset);
3340 bool HasAIXSmallLocalDynamicTLS = Subtarget.hasAIXSmallLocalDynamicTLS();
3344 if (!Is64Bit && HasAIXSmallLocalDynamicTLS)
3346 "currently only supported on AIX (64-bit mode).");
3354 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3357 GlobalVariable *TLSGV =
3361 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3364 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3366 DAG.
getNode(PPCISD::TLSLD_AIX, dl, PtrVT, ModuleHandleTOC);
3375 if (HasAIXSmallLocalDynamicTLS) {
3380 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA,
3384 return DAG.
getNode(
ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
3397 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3398 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3399 return DAG.
getNode(PPCISD::TLSGD_AIX, dl, PtrVT, VariableOffset,
3414 const GlobalValue *GV = GA->
getGlobal();
3416 bool is64bit = Subtarget.isPPC64();
3424 if (Subtarget.isUsingPCRelativeCalls()) {
3429 DAG.
getNode(PPCISD::TLS_LOCAL_EXEC_MAT_ADDR, dl, PtrVT, TGA);
3430 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, MatAddr);
3441 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, TGALo,
Hi);
3445 bool IsPCRel = Subtarget.isUsingPCRelativeCalls();
3452 SDValue MatPCRel = DAG.
getNode(PPCISD::MAT_PCREL_ADDR, dl, PtrVT, TGA);
3454 MachinePointerInfo());
3461 DAG.
getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl, PtrVT, GOTReg, TGA);
3463 if (!TM.isPositionIndependent())
3464 GOTPtr = DAG.
getNode(PPCISD::PPC32_GOT, dl, PtrVT);
3470 TPOffset = DAG.
getNode(PPCISD::LD_GOT_TPREL_L, dl, PtrVT, TGA, GOTPtr);
3472 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TPOffset, TGATLS);
3476 if (Subtarget.isUsingPCRelativeCalls()) {
3479 return DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3487 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSGD_HA, dl, PtrVT,
3495 return DAG.
getNode(PPCISD::ADDI_TLSGD_L_ADDR, dl, PtrVT,
3500 if (Subtarget.isUsingPCRelativeCalls()) {
3504 DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3505 return DAG.
getNode(PPCISD::PADDI_DTPREL, dl, PtrVT, MatPCRel, TGA);
3513 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSLD_HA, dl, PtrVT,
3522 PtrVT, GOTPtr, TGA, TGA);
3524 PtrVT, TLSAddr, TGA);
3525 return DAG.
getNode(PPCISD::ADDI_DTPREL_L, dl, PtrVT, DtvOffsetHi, TGA);
3533 EVT PtrVT =
Op.getValueType();
3536 const GlobalValue *GV = GSDN->
getGlobal();
3540 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3541 if (Subtarget.isUsingPCRelativeCalls()) {
3548 MachinePointerInfo());
3553 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, GA);
3558 return getTOCEntry(DAG,
DL, GA);
3561 unsigned MOHiFlag, MOLoFlag;
3565 if (IsPIC && Subtarget.isSVR4ABI()) {
3569 return getTOCEntry(DAG,
DL, GA);
3581 bool IsStrict =
Op->isStrictFPOpcode();
3587 EVT LHSVT =
LHS.getValueType();
3591 if (LHSVT == MVT::f128) {
3592 assert(!Subtarget.hasP9Vector() &&
3593 "SETCC for f128 is already legal under Power9!");
3604 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3606 if (
Op.getValueType() == MVT::v2i64) {
3609 if (
LHS.getValueType() == MVT::v2i64) {
3617 int ShuffV[] = {1, 0, 3, 2};
3622 dl, MVT::v4i32, Shuff, SetCC32));
3639 if (
C->isAllOnes() ||
C->isZero())
3649 EVT VT =
Op.getValueType();
3657 SDNode *
Node =
Op.getNode();
3658 EVT VT =
Node->getValueType(0);
3665 assert(!Subtarget.isPPC64() &&
"LowerVAARG is PPC32 only");
3669 VAListPtr, MachinePointerInfo(SV), MVT::i8);
3672 if (VT == MVT::i64) {
3691 FprPtr, MachinePointerInfo(SV), MVT::i8);
3702 DAG.
getLoad(MVT::i32, dl, InChain, OverflowAreaPtr, MachinePointerInfo());
3703 InChain = OverflowArea.
getValue(1);
3706 DAG.
getLoad(MVT::i32, dl, InChain, RegSaveAreaPtr, MachinePointerInfo());
3736 MachinePointerInfo(SV), MVT::i8);
3749 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3750 MachinePointerInfo(), MVT::i32);
3752 return DAG.
getLoad(VT, dl, InChain, Result, MachinePointerInfo());
3756 assert(!Subtarget.isPPC64() &&
"LowerVACOPY is PPC32 only");
3762 false,
true,
nullptr, std::nullopt,
3763 MachinePointerInfo(), MachinePointerInfo());
3768 return Op.getOperand(0);
3773 PPCFunctionInfo &MFI = *MF.
getInfo<PPCFunctionInfo>();
3777 "Expecting Inline ASM node.");
3787 if (
Op.getOperand(
NumOps - 1).getValueType() == MVT::Glue)
3792 const InlineAsm::Flag
Flags(
Op.getConstantOperandVal(i));
3793 unsigned NumVals =
Flags.getNumOperandRegisters();
3796 switch (
Flags.getKind()) {
3807 for (; NumVals; --NumVals, ++i) {
3809 if (
Reg != PPC::LR &&
Reg != PPC::LR8)
3832 if (Subtarget.isAIXABI()) {
3836 uint64_t
PointerSize = Subtarget.isPPC64() ? 8 : 4;
3837 MaybeAlign PointerAlign(PointerSize);
3838 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
3841 : MachineMemOperand::MONone;
3848 const Value *TrampolineAddr =
3858 DAG.
getLoad(PtrVT, dl, Chain, FPtr, MachinePointerInfo(Func, 0),
3859 PointerAlign, MMOFlags);
3861 OutChains[0] = DAG.
getStore(EPLoadChain, dl, LoadEntryPoint, Trmp,
3862 MachinePointerInfo(TrampolineAddr, 0));
3866 SDValue TOCFromDescriptorPtr =
3868 SDValue TOCReg = DAG.
getLoad(PtrVT, dl, Chain, TOCFromDescriptorPtr,
3869 MachinePointerInfo(Func, TOCPointerOffset),
3870 PointerAlign, MMOFlags);
3871 SDValue TrampolineTOCPointer =
3875 DAG.
getStore(TOCLoadChain, dl, TOCReg, TrampolineTOCPointer,
3876 MachinePointerInfo(TrampolineAddr, TOCPointerOffset));
3882 DAG.
getStore(Chain, dl, Nest, EnvPointer,
3883 MachinePointerInfo(TrampolineAddr, EnvPointerOffset));
3890 bool isPPC64 = (PtrVT == MVT::i64);
3894 Args.emplace_back(Trmp, IntPtrTy);
3897 DAG.
getConstant(isPPC64 ? 48 : 40, dl, Subtarget.getScalarIntVT()),
3899 Args.emplace_back(FPtr, IntPtrTy);
3900 Args.emplace_back(Nest, IntPtrTy);
3903 TargetLowering::CallLoweringInfo CLI(DAG);
3904 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3908 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
3909 return CallResult.second;
3914 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
3919 if (Subtarget.isPPC64() || Subtarget.isAIXABI()) {
3924 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
3925 MachinePointerInfo(SV));
3959 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
3962 uint64_t StackOffset = PtrVT.getSizeInBits()/8 - 1;
3965 uint64_t FPROffset = 1;
3973 MachinePointerInfo(SV), MVT::i8);
3974 uint64_t nextOffset = FPROffset;
3981 MachinePointerInfo(SV, nextOffset), MVT::i8);
3982 nextOffset += StackOffset;
3983 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
3986 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
3987 MachinePointerInfo(SV, nextOffset));
3988 nextOffset += FrameOffset;
3989 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
3992 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
3993 MachinePointerInfo(SV, nextOffset));
3998static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
3999 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
4000 PPC::F11, PPC::F12, PPC::F13};
4005 unsigned PtrByteSize) {
4007 if (Flags.isByVal())
4008 ArgSize = Flags.getByValSize();
4012 if (!Flags.isInConsecutiveRegs())
4013 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4022 unsigned PtrByteSize) {
4023 Align Alignment(PtrByteSize);
4026 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4027 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4028 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4029 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4030 Alignment =
Align(16);
4033 if (Flags.isByVal()) {
4034 auto BVAlign = Flags.getNonZeroByValAlign();
4035 if (BVAlign > PtrByteSize) {
4036 if (BVAlign.value() % PtrByteSize != 0)
4038 "ByVal alignment is not a multiple of the pointer size");
4040 Alignment = BVAlign;
4045 if (Flags.isInConsecutiveRegs()) {
4049 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4063 unsigned PtrByteSize,
unsigned LinkageSize,
4064 unsigned ParamAreaSize,
unsigned &ArgOffset,
4065 unsigned &AvailableFPRs,
4066 unsigned &AvailableVRs) {
4067 bool UseMemory =
false;
4072 ArgOffset =
alignTo(ArgOffset, Alignment);
4075 if (ArgOffset >= LinkageSize + ParamAreaSize)
4080 if (Flags.isInConsecutiveRegsLast())
4081 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4084 if (ArgOffset > LinkageSize + ParamAreaSize)
4089 if (!Flags.isByVal()) {
4090 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4091 if (AvailableFPRs > 0) {
4095 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4096 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4097 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4098 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4099 if (AvailableVRs > 0) {
4111 unsigned NumBytes) {
4115SDValue PPCTargetLowering::LowerFormalArguments(
4119 if (Subtarget.isAIXABI())
4120 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4122 if (Subtarget.is64BitELFABI())
4123 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4125 assert(Subtarget.is32BitELFABI());
4126 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4130SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4166 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4172 const Align PtrAlign(4);
4180 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4181 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4184 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4185 CCValAssign &VA = ArgLocs[i];
4189 const TargetRegisterClass *RC;
4197 RC = &PPC::GPRCRegClass;
4200 if (Subtarget.hasP8Vector())
4201 RC = &PPC::VSSRCRegClass;
4202 else if (Subtarget.hasSPE())
4203 RC = &PPC::GPRCRegClass;
4205 RC = &PPC::F4RCRegClass;
4208 if (Subtarget.hasVSX())
4209 RC = &PPC::VSFRCRegClass;
4210 else if (Subtarget.hasSPE())
4212 RC = &PPC::GPRCRegClass;
4214 RC = &PPC::F8RCRegClass;
4219 RC = &PPC::VRRCRegClass;
4222 RC = &PPC::VRRCRegClass;
4226 RC = &PPC::VRRCRegClass;
4233 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4234 assert(i + 1 < e &&
"No second half of double precision argument");
4239 if (!Subtarget.isLittleEndian())
4241 ArgValue = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64, ArgValueLo,
4246 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4247 if (ValVT == MVT::i1)
4262 ArgOffset += ArgSize - ObjSize;
4280 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4285 unsigned MinReservedArea = CCByValInfo.getStackSize();
4286 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4302 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4303 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4305 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4308 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4311 unsigned NumFPArgRegs = std::size(FPArgRegs);
4320 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4321 NumFPArgRegs * MVT(MVT::f64).getSizeInBits()/8;
4324 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4337 VReg = MF.
addLiveIn(GPArgReg, &PPC::GPRCRegClass);
4352 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4356 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4369 if (!MemOps.
empty())
4380 const SDLoc &dl)
const {
4384 else if (
Flags.isZExt())
4391SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4397 bool isELFv2ABI = Subtarget.isELFv2ABI();
4398 bool isLittleEndian = Subtarget.isLittleEndian();
4401 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4404 "fastcc not supported on varargs functions");
4410 unsigned PtrByteSize = 8;
4411 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4414 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4415 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4418 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4419 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4422 const unsigned Num_GPR_Regs = std::size(GPR);
4424 const unsigned Num_VR_Regs = std::size(VR);
4432 bool HasParameterArea = !isELFv2ABI || isVarArg;
4433 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4434 unsigned NumBytes = LinkageSize;
4435 unsigned AvailableFPRs = Num_FPR_Regs;
4436 unsigned AvailableVRs = Num_VR_Regs;
4437 for (
const ISD::InputArg &In : Ins) {
4438 if (
In.Flags.isNest())
4442 LinkageSize, ParamAreaSize, NumBytes,
4443 AvailableFPRs, AvailableVRs))
4444 HasParameterArea =
true;
4451 unsigned ArgOffset = LinkageSize;
4452 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4455 unsigned CurArgIdx = 0;
4456 for (
unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) {
4458 bool needsLoad =
false;
4459 EVT ObjectVT = Ins[ArgNo].VT;
4460 EVT OrigVT = Ins[ArgNo].ArgVT;
4462 unsigned ArgSize = ObjSize;
4463 ISD::ArgFlagsTy
Flags = Ins[ArgNo].Flags;
4464 if (Ins[ArgNo].isOrigArg()) {
4465 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4466 CurArgIdx = Ins[ArgNo].getOrigArgIndex();
4471 unsigned CurArgOffset;
4473 auto ComputeArgOffset = [&]() {
4477 ArgOffset =
alignTo(ArgOffset, Alignment);
4478 CurArgOffset = ArgOffset;
4485 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4486 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4491 if (
Flags.isByVal()) {
4492 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4498 ObjSize =
Flags.getByValSize();
4499 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4521 if (HasParameterArea ||
4522 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4529 if (ObjSize < PtrByteSize) {
4533 if (!isLittleEndian) {
4539 if (GPR_idx != Num_GPR_Regs) {
4546 MachinePointerInfo(&*FuncArg), ObjType);
4551 ArgOffset += PtrByteSize;
4560 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4561 if (GPR_idx == Num_GPR_Regs)
4572 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4576 MachinePointerInfo(&*FuncArg, j), ObjType);
4580 ArgOffset += ArgSize;
4589 if (
Flags.isNest()) {
4594 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4595 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4603 if (GPR_idx != Num_GPR_Regs) {
4608 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4611 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4617 ArgSize = PtrByteSize;
4628 if (FPR_idx != Num_FPR_Regs) {
4631 if (ObjectVT == MVT::f32)
4633 Subtarget.hasP8Vector()
4634 ? &PPC::VSSRCRegClass
4635 : &PPC::F4RCRegClass);
4638 ? &PPC::VSFRCRegClass
4639 : &PPC::F8RCRegClass);
4654 if (ObjectVT == MVT::f32) {
4655 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4673 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4674 ArgOffset += ArgSize;
4675 if (
Flags.isInConsecutiveRegsLast())
4676 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4690 if (VR_idx != Num_VR_Regs) {
4707 if (ObjSize < ArgSize && !isLittleEndian)
4708 CurArgOffset += ArgSize - ObjSize;
4711 ArgVal = DAG.
getLoad(ObjectVT, dl, Chain, FIN, MachinePointerInfo());
4718 unsigned MinReservedArea;
4719 if (HasParameterArea)
4720 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4722 MinReservedArea = LinkageSize;
4739 int Depth = ArgOffset;
4748 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4749 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4761 if (!MemOps.
empty())
4770 unsigned ParamSize) {
4772 if (!isTailCall)
return 0;
4776 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4778 if (SPDiff < FI->getTailCallSPDelta())
4794 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4853 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
4856 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4868 const unsigned PtrByteSize = 8;
4872 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4873 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4876 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4877 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4880 const unsigned NumGPRs = std::size(GPR);
4881 const unsigned NumFPRs = 13;
4882 const unsigned NumVRs = std::size(VR);
4883 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4885 unsigned NumBytes = LinkageSize;
4886 unsigned AvailableFPRs = NumFPRs;
4887 unsigned AvailableVRs = NumVRs;
4890 if (Param.Flags.isNest())
continue;
4893 LinkageSize, ParamAreaSize, NumBytes,
4894 AvailableFPRs, AvailableVRs))
4905 auto CalleeArgEnd = CB.
arg_end();
4908 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
4909 const Value* CalleeArg = *CalleeArgIter;
4910 const Value* CallerArg = &(*CallerArgIter);
4911 if (CalleeArg == CallerArg)
4937 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
4947bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
4952 bool isCalleeExternalSymbol)
const {
4955 if (
DisableSCO && !TailCallOpt)
return false;
4958 if (isVarArg)
return false;
4965 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5001 if (!Subtarget.isUsingPCRelativeCalls() &&
5006 if (!Subtarget.isUsingPCRelativeCalls() &&
5034bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5047 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5068 if (!
C)
return nullptr;
5070 int Addr =
C->getZExtValue();
5071 if ((Addr & 3) != 0 ||
5077 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5084struct TailCallArgumentInfo {
5089 TailCallArgumentInfo() =
default;
5099 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5100 SDValue Arg = TailCallArgs[i].Arg;
5101 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5102 int FI = TailCallArgs[i].FrameIdx;
5105 Chain, dl, Arg, FIN,
5114 int SPDiff,
const SDLoc &dl) {
5120 int SlotSize = Subtarget.isPPC64() ? 8 : 4;
5121 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5123 NewRetAddrLoc,
true);
5126 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5136 int SPDiff,
unsigned ArgOffset,
5138 int Offset = ArgOffset + SPDiff;
5141 EVT VT = IsPPC64 ? MVT::i64 : MVT::i32;
5143 TailCallArgumentInfo
Info;
5145 Info.FrameIdxOp = FIN;
5153SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5158 LROpOut = getReturnAddrFrameIndex(DAG);
5159 LROpOut = DAG.
getLoad(Subtarget.getScalarIntVT(), dl, Chain, LROpOut,
5160 MachinePointerInfo());
5177 Chain, dl, Dst, Src, SizeNode, Flags.getNonZeroByValAlign(),
false,
false,
5185 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5209 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5219 if (!MemOpChains2.
empty())
5243SDValue PPCTargetLowering::LowerCallResult(
5251 CCRetInfo.AnalyzeCallResult(
5257 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5258 CCValAssign &VA = RVLocs[i];
5263 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5273 if (!Subtarget.isLittleEndian())
5275 Val = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64,
Lo,
Hi);
5341 bool IsStrictFPCall =
false) {
5343 return PPCISD::TC_RETURN;
5345 unsigned RetOpc = 0;
5360 RetOpc = PPCISD::CALL_NOTOC;
5375 RetOpc = PPCISD::CALL;
5376 if (IsStrictFPCall) {
5380 case PPCISD::BCTRL_LOAD_TOC:
5381 RetOpc = PPCISD::BCTRL_LOAD_TOC_RM;
5384 RetOpc = PPCISD::BCTRL_RM;
5386 case PPCISD::CALL_NOTOC:
5387 RetOpc = PPCISD::CALL_NOTOC_RM;
5390 RetOpc = PPCISD::CALL_RM;
5392 case PPCISD::CALL_NOP:
5393 RetOpc = PPCISD::CALL_NOP_RM;
5407 auto isLocalCallee = [&]() {
5423 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5440 return getAIXFuncEntryPointSymbolSDNode(GV);
5447 const char *SymName = S->getSymbol();
5454 return getAIXFuncEntryPointSymbolSDNode(
F);
5460 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5468 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5475 assert(Callee.getNode() &&
"What no callee?");
5481 "Expected a CALLSEQ_STARTSDNode.");
5498 SDValue MTCTROps[] = {Chain, Callee, Glue};
5499 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5500 Chain = DAG.
getNode(PPCISD::MTCTR, dl, ReturnTypes,
5540 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5559 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5560 Alignment, MMOFlags);
5567 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5574 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5586 "Nest parameter is not supported on AIX.");
5602 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5605 const bool IsPPC64 = Subtarget.isPPC64();
5610 Ops.push_back(Chain);
5614 Ops.push_back(Callee);
5634 Ops.push_back(AddTOC);
5645 Ops.push_back(DAG.
getRegister(IsPPC64 ? PPC::CTR8 : PPC::CTR, RegVT));
5654 for (
const auto &[
Reg,
N] : RegsToPass)
5672 assert(Mask &&
"Missing call preserved mask for calling convention");
5677 Ops.push_back(Glue);
5680SDValue PPCTargetLowering::FinishCall(
5687 if ((Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls()) ||
5688 Subtarget.isAIXABI())
5695 if (!CFlags.IsIndirect)
5697 else if (Subtarget.usesFunctionDescriptors())
5699 dl, CFlags.HasNest, Subtarget);
5709 if (CFlags.IsTailCall) {
5717 (CFlags.IsIndirect && Subtarget.isUsingPCRelativeCalls())) &&
5718 "Expecting a global address, external symbol, absolute value, "
5719 "register or an indirect tail call when PC Relative calls are "
5722 assert(CallOpc == PPCISD::TC_RETURN &&
5723 "Unexpected call opcode for a tail call.");
5730 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5731 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes,
Ops);
5743 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5746 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5766 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5767 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5771bool PPCTargetLowering::isEligibleForTCO(
5776 bool isCalleeExternalSymbol)
const {
5780 if (Subtarget.
isSVR4ABI() && Subtarget.isPPC64())
5781 return IsEligibleForTailCallOptimization_64SVR4(
5782 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5783 isCalleeExternalSymbol);
5785 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5813 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5828 "Callee should be an llvm::Function object.");
5831 <<
"\nTCO callee: ");
5838 "site marked musttail");
5845 Callee = LowerGlobalAddress(Callee, DAG);
5848 CallConv, isTailCall, isVarArg, isPatchPoint,
5851 Subtarget.is64BitELFABI() &&
5855 if (Subtarget.isAIXABI())
5856 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5859 assert(Subtarget.isSVR4ABI());
5860 if (Subtarget.isPPC64())
5861 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5863 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5867SDValue PPCTargetLowering::LowerCall_32SVR4(
5878 const bool IsVarArg = CFlags.IsVarArg;
5879 const bool IsTailCall = CFlags.IsTailCall;
5885 const Align PtrAlign(4);
5896 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
5904 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.
getContext());
5907 CCInfo.AllocateStack(Subtarget.getFrameLowering()->getLinkageSize(),
5914 unsigned NumArgs = Outs.
size();
5916 for (
unsigned i = 0; i != NumArgs; ++i) {
5917 MVT ArgVT = Outs[i].VT;
5918 ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
5923 Outs[i].OrigTy, CCInfo);
5926 ArgFlags, Outs[i].OrigTy, CCInfo);
5931 errs() <<
"Call operand #" << i <<
" has unhandled type "
5944 CCState CCByValInfo(CallConv, IsVarArg, MF, ByValArgLocs, *DAG.
getContext());
5947 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
5954 unsigned NumBytes = CCByValInfo.getStackSize();
5968 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
5979 bool seenFloatArg =
false;
5984 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
5986 ++i, ++RealArgIdx) {
5987 CCValAssign &VA = ArgLocs[i];
5988 SDValue Arg = OutVals[RealArgIdx];
5989 ISD::ArgFlagsTy
Flags = Outs[RealArgIdx].Flags;
5991 if (
Flags.isByVal()) {
5996 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
5997 CCValAssign &ByValVA = ByValArgLocs[
j++];
6019 Chain = CallSeqStart = NewCallSeqStart;
6038 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6039 bool IsLE = Subtarget.isLittleEndian();
6040 SDValue SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6043 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6045 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6060 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()));
6069 if (!MemOpChains.
empty())
6075 for (
const auto &[
Reg,
N] : RegsToPass) {
6083 SDVTList VTs = DAG.
getVTList(MVT::Other, MVT::Glue);
6086 Chain = DAG.
getNode(seenFloatArg ? PPCISD::CR6SET : PPCISD::CR6UNSET, dl,
6096 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6097 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6102SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6114 return NewCallSeqStart;
6117SDValue PPCTargetLowering::LowerCall_64SVR4(
6124 bool isELFv2ABI = Subtarget.isELFv2ABI();
6125 bool isLittleEndian = Subtarget.isLittleEndian();
6127 bool IsSibCall =
false;
6131 unsigned PtrByteSize = 8;
6144 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
6146 assert(!(IsFastCall && CFlags.IsVarArg) &&
6147 "fastcc not supported on varargs functions");
6153 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
6154 unsigned NumBytes = LinkageSize;
6155 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6158 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6159 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6162 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6163 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6166 const unsigned NumGPRs = std::size(GPR);
6168 const unsigned NumVRs = std::size(VR);
6174 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6175 if (!HasParameterArea) {
6176 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6177 unsigned AvailableFPRs = NumFPRs;
6178 unsigned AvailableVRs = NumVRs;
6179 unsigned NumBytesTmp = NumBytes;
6180 for (
unsigned i = 0; i !=
NumOps; ++i) {
6181 if (Outs[i].
Flags.isNest())
continue;
6183 PtrByteSize, LinkageSize, ParamAreaSize,
6184 NumBytesTmp, AvailableFPRs, AvailableVRs))
6185 HasParameterArea =
true;
6191 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6196 HasParameterArea =
false;
6199 for (
unsigned i = 0; i !=
NumOps; ++i) {
6200 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6201 EVT ArgVT = Outs[i].VT;
6202 EVT OrigVT = Outs[i].ArgVT;
6208 if (
Flags.isByVal()) {
6209 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6210 if (NumGPRsUsed > NumGPRs)
6211 HasParameterArea =
true;
6218 if (++NumGPRsUsed <= NumGPRs)
6228 if (++NumVRsUsed <= NumVRs)
6232 if (++NumVRsUsed <= NumVRs)
6237 if (++NumFPRsUsed <= NumFPRs)
6241 HasParameterArea =
true;
6248 NumBytes =
alignTo(NumBytes, Alignement);
6251 if (
Flags.isInConsecutiveRegsLast())
6252 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6255 unsigned NumBytesActuallyUsed = NumBytes;
6265 if (HasParameterArea)
6266 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6268 NumBytes = LinkageSize;
6283 if (CFlags.IsTailCall)
6295 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6306 unsigned ArgOffset = LinkageSize;
6312 for (
unsigned i = 0; i !=
NumOps; ++i) {
6314 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6315 EVT ArgVT = Outs[i].VT;
6316 EVT OrigVT = Outs[i].ArgVT;
6325 auto ComputePtrOff = [&]() {
6329 ArgOffset =
alignTo(ArgOffset, Alignment);
6340 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6341 GPR_idx = std::min(GPR_idx, NumGPRs);
6348 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6354 if (
Flags.isByVal()) {
6372 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6373 if (GPR_idx != NumGPRs) {
6375 MachinePointerInfo(), VT);
6377 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6379 ArgOffset += PtrByteSize;
6384 if (GPR_idx == NumGPRs &&
Size < 8) {
6386 if (!isLittleEndian) {
6391 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6394 ArgOffset += PtrByteSize;
6403 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6404 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6409 if (
Size < 8 && GPR_idx != NumGPRs) {
6419 if (!isLittleEndian) {
6423 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6429 DAG.
getLoad(PtrVT, dl, Chain, PtrOff, MachinePointerInfo());
6431 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6434 ArgOffset += PtrByteSize;
6440 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6443 if (GPR_idx != NumGPRs) {
6444 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6447 MachinePointerInfo(), ObjType);
6450 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6451 ArgOffset += PtrByteSize;
6453 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6465 if (
Flags.isNest()) {
6467 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6474 if (GPR_idx != NumGPRs) {
6475 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6480 assert(HasParameterArea &&
6481 "Parameter area must exist to pass an argument in memory.");
6483 true, CFlags.IsTailCall,
false, MemOpChains,
6484 TailCallArguments, dl);
6486 ArgOffset += PtrByteSize;
6489 ArgOffset += PtrByteSize;
6502 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6503 bool NeededLoad =
false;
6506 if (FPR_idx != NumFPRs)
6507 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6510 if (!NeedGPROrStack)
6512 else if (GPR_idx != NumGPRs && !IsFastCall) {
6526 }
else if (!
Flags.isInConsecutiveRegs()) {
6532 }
else if (ArgOffset % PtrByteSize != 0) {
6536 if (!isLittleEndian)
6541 }
else if (
Flags.isInConsecutiveRegsLast()) {
6544 if (!isLittleEndian)
6554 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6562 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6567 assert(HasParameterArea &&
6568 "Parameter area must exist to pass an argument in memory.");
6570 true, CFlags.IsTailCall,
false, MemOpChains,
6571 TailCallArguments, dl);
6578 if (!IsFastCall || NeededLoad) {
6580 Flags.isInConsecutiveRegs()) ? 4 : 8;
6581 if (
Flags.isInConsecutiveRegsLast())
6582 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6602 if (CFlags.IsVarArg) {
6603 assert(HasParameterArea &&
6604 "Parameter area must exist if we have a varargs call.");
6608 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
6610 if (VR_idx != NumVRs) {
6612 DAG.
getLoad(MVT::v4f32, dl, Store, PtrOff, MachinePointerInfo());
6614 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6617 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6618 if (GPR_idx == NumGPRs)
6623 DAG.
getLoad(PtrVT, dl, Store, Ix, MachinePointerInfo());
6625 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6631 if (VR_idx != NumVRs) {
6632 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6637 assert(HasParameterArea &&
6638 "Parameter area must exist to pass an argument in memory.");
6640 true, CFlags.IsTailCall,
true, MemOpChains,
6641 TailCallArguments, dl);
6652 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6653 "mismatch in size of parameter area");
6654 (void)NumBytesActuallyUsed;
6656 if (!MemOpChains.
empty())
6662 if (CFlags.IsIndirect) {
6666 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6671 unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
6681 if (isELFv2ABI && !CFlags.IsPatchPoint)
6682 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6688 for (
const auto &[
Reg,
N] : RegsToPass) {
6693 if (CFlags.IsTailCall && !IsSibCall)
6697 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6698 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6705 "Required alignment greater than stack alignment.");
6725 return RequiredAlign <= 8;
6730 return RequiredAlign <= 4;
6738 State.getMachineFunction().getSubtarget());
6739 const bool IsPPC64 = Subtarget.isPPC64();
6740 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6741 const Align PtrAlign(PtrSize);
6742 const Align StackAlign(16);
6745 if (ValVT == MVT::f128)
6749 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6750 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6752 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6753 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6756 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6757 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6758 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6763 MCRegister EnvReg = State.AllocateReg(IsPPC64 ? PPC::X11 : PPC::R11);
6772 if (ByValAlign > StackAlign)
6774 "16 are not supported.");
6777 const Align ObjAlign = ByValAlign > PtrAlign ? ByValAlign : PtrAlign;
6781 if (ByValSize == 0) {
6783 State.getStackSize(), RegVT, LocInfo));
6788 unsigned NextReg = State.getFirstUnallocated(GPRs);
6789 while (NextReg != GPRs.
size() &&
6794 State.AllocateStack(PtrSize, PtrAlign);
6795 assert(
Reg &&
"Alocating register unexpectedly failed.");
6797 NextReg = State.getFirstUnallocated(GPRs);
6800 const unsigned StackSize =
alignTo(ByValSize, ObjAlign);
6801 unsigned Offset = State.AllocateStack(StackSize, ObjAlign);
6821 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6825 const unsigned Offset = State.AllocateStack(PtrSize, PtrAlign);
6844 State.AllocateStack(IsPPC64 ? 8 : StoreSize,
Align(4));
6850 for (
unsigned I = 0;
I < StoreSize;
I += PtrSize) {
6852 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
6853 if (State.isVarArg()) {
6885 const unsigned VecSize = 16;
6886 const Align VecAlign(VecSize);
6888 if (!State.isVarArg()) {
6891 if (
MCRegister VReg = State.AllocateReg(VR)) {
6898 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6903 unsigned NextRegIndex = State.getFirstUnallocated(GPRs);
6906 while (NextRegIndex != GPRs.
size() &&
6910 State.AllocateStack(PtrSize, PtrAlign);
6911 assert(
Reg &&
"Allocating register unexpectedly failed.");
6913 NextRegIndex = State.getFirstUnallocated(GPRs);
6921 if (
MCRegister VReg = State.AllocateReg(VR)) {
6924 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
6925 State.AllocateReg(GPRs);
6926 State.AllocateStack(VecSize, VecAlign);
6930 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6936 if (NextRegIndex == GPRs.
size()) {
6937 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6945 if (GPRs[NextRegIndex] == PPC::R9) {
6946 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6950 const MCRegister FirstReg = State.AllocateReg(PPC::R9);
6951 const MCRegister SecondReg = State.AllocateReg(PPC::R10);
6952 assert(FirstReg && SecondReg &&
6953 "Allocating R9 or R10 unexpectedly failed.");
6964 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6967 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
6969 assert(
Reg &&
"Failed to allocated register for vararg vector argument");
6984 assert((IsPPC64 || SVT != MVT::i64) &&
6985 "i64 should have been split for 32-bit codegen.");
6993 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
6995 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
6997 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
7005 return &PPC::VRRCRegClass;
7018 else if (Flags.isZExt())
7030 "Reg must be a valid argument register!");
7031 return LASize + 4 * (
Reg - PPC::R3);
7036 "Reg must be a valid argument register!");
7037 return LASize + 8 * (
Reg - PPC::X3);
7083SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7090 "Unexpected calling convention!");
7098 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7100 const bool IsPPC64 = Subtarget.isPPC64();
7101 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7107 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
7108 CCState CCInfo(CallConv, isVarArg, MF, ArgLocs, *DAG.
getContext());
7112 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7113 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7114 uint64_t SaveStackPos = CCInfo.getStackSize();
7116 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7120 for (
size_t I = 0, End = ArgLocs.
size();
I != End; ) {
7121 CCValAssign &VA = ArgLocs[
I++];
7126 EVT ArgVT = Ins[VA.
getValNo()].ArgVT;
7127 bool ArgSignExt = Ins[VA.
getValNo()].Flags.isSExt();
7139 LocVT.
SimpleTy, IsPPC64, Subtarget.hasP8Vector(), Subtarget.hasVSX());
7141 MVT SaveVT = RegClass == &PPC::G8RCRegClass ? MVT::i64 : LocVT;
7147 MachinePointerInfo(),
Align(PtrByteSize));
7153 unsigned StoreSize =
7155 SaveStackPos =
alignTo(SaveStackPos + StoreSize, PtrByteSize);
7158 auto HandleMemLoc = [&]() {
7161 assert((ValSize <= LocSize) &&
7162 "Object size is larger than size of MemLoc");
7165 if (LocSize > ValSize)
7166 CurArgOffset += LocSize - ValSize;
7168 const bool IsImmutable =
7174 DAG.
getLoad(ValVT, dl, Chain, FIN, MachinePointerInfo());
7208 assert(isVarArg &&
"Only use custom memloc for vararg.");
7211 const unsigned OriginalValNo = VA.
getValNo();
7212 (void)OriginalValNo;
7214 auto HandleCustomVecRegLoc = [&]() {
7215 assert(
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7216 "Missing custom RegLoc.");
7219 "Unexpected Val type for custom RegLoc.");
7221 "ValNo mismatch between custom MemLoc and RegLoc.");
7225 Subtarget.hasVSX()));
7232 HandleCustomVecRegLoc();
7233 HandleCustomVecRegLoc();
7237 if (
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7239 "Only 2 custom RegLocs expected for 64-bit codegen.");
7240 HandleCustomVecRegLoc();
7241 HandleCustomVecRegLoc();
7285 const unsigned Size =
7297 if (
Flags.isByVal()) {
7301 const PPCFrameLowering *FL = Subtarget.getFrameLowering();
7303 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7311 const TargetRegisterClass *RegClass =
7312 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7314 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7327 CopyFrom.
getValue(1), dl, CopyFrom,
7337 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7340 "RegLocs should be for ByVal argument.");
7342 const CCValAssign RL = ArgLocs[
I++];
7347 if (
Offset != StackSize) {
7349 "Expected MemLoc for remaining bytes.");
7350 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7364 Subtarget.hasVSX()));
7381 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7383 unsigned CallerReservedArea = std::max<unsigned>(
7384 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7390 CallerReservedArea =
7395 int VAListIndex = 0;
7399 if (CCInfo.getStackSize() < (LinkageSize + MinParameterSaveArea)) {
7400 unsigned FixedStackSize =
7401 LinkageSize + MinParameterSaveArea - CCInfo.getStackSize();
7417 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7418 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7420 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7421 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7422 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7428 GPRIndex = (CCInfo.getStackSize() - LinkageSize) / PtrByteSize,
7430 GPRIndex < NumGPArgRegs; ++GPRIndex,
Offset += PtrByteSize) {
7433 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7434 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7437 MachinePointerInfo MPI =
7447 if (!MemOps.
empty())
7453SDValue PPCTargetLowering::LowerCall_AIX(
7466 "Unexpected calling convention!");
7468 if (CFlags.IsPatchPoint)
7471 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7475 CCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7482 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7483 const bool IsPPC64 = Subtarget.isPPC64();
7485 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7486 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7487 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7495 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7496 const unsigned NumBytes = std::max<unsigned>(
7497 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7513 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E;) {
7514 const unsigned ValNo = ArgLocs[
I].getValNo();
7516 ISD::ArgFlagsTy
Flags = Outs[ValNo].Flags;
7518 if (
Flags.isByVal()) {
7519 const unsigned ByValSize =
Flags.getByValSize();
7527 auto GetLoad = [&](EVT VT,
unsigned LoadOffset) {
7533 MachinePointerInfo(), VT);
7536 unsigned LoadOffset = 0;
7539 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7542 LoadOffset += PtrByteSize;
7543 const CCValAssign &ByValVA = ArgLocs[
I++];
7545 "Unexpected location for pass-by-value argument.");
7549 if (LoadOffset == ByValSize)
7553 assert(ArgLocs[
I].getValNo() == ValNo &&
7554 "Expected additional location for by-value argument.");
7556 if (ArgLocs[
I].isMemLoc()) {
7557 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7558 const CCValAssign &ByValVA = ArgLocs[
I++];
7559 ISD::ArgFlagsTy MemcpyFlags =
Flags;
7562 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7568 CallSeqStart, MemcpyFlags, DAG, dl);
7577 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7578 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7579 "Unexpected register residue for by-value argument.");
7581 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7585 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7595 "Unexpected load emitted during handling of pass-by-value "
7603 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7608 const CCValAssign &ByValVA = ArgLocs[
I++];
7613 CCValAssign &VA = ArgLocs[
I++];
7638 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7644 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
7646 const unsigned OriginalValNo = VA.
getValNo();
7648 unsigned LoadOffset = 0;
7649 auto HandleCustomVecRegLoc = [&]() {
7650 assert(
I !=
E &&
"Unexpected end of CCvalAssigns.");
7651 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7652 "Expected custom RegLoc.");
7653 CCValAssign RegVA = ArgLocs[
I++];
7655 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7661 LoadOffset += PtrByteSize;
7667 HandleCustomVecRegLoc();
7668 HandleCustomVecRegLoc();
7670 if (
I !=
E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7671 ArgLocs[
I].getValNo() == OriginalValNo) {
7673 "Only 2 custom RegLocs expected for 64-bit codegen.");
7674 HandleCustomVecRegLoc();
7675 HandleCustomVecRegLoc();
7686 DAG.
getStore(Chain, dl, Arg, PtrOff,
7688 Subtarget.getFrameLowering()->getStackAlign()));
7695 "Unexpected register handling for calling convention.");
7701 "Custom register handling only expected for VarArg.");
7706 if (Arg.getValueType().getStoreSize() == LocVT.
getStoreSize())
7710 else if (Arg.getValueType().getFixedSizeInBits() <
7718 assert(Arg.getValueType() == MVT::f64 && CFlags.IsVarArg && !IsPPC64 &&
7719 "Unexpected custom register for argument!");
7720 CCValAssign &GPR1 = VA;
7729 CCValAssign &PeekArg = ArgLocs[
I];
7732 CCValAssign &GPR2 = ArgLocs[
I++];
7740 if (!MemOpChains.
empty())
7745 if (CFlags.IsIndirect) {
7746 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7747 const MCRegister TOCBaseReg = Subtarget.getTOCPointerRegister();
7748 const MCRegister StackPtrReg = Subtarget.getStackPointerRegister();
7749 const MVT PtrVT = Subtarget.getScalarIntVT();
7750 const unsigned TOCSaveOffset =
7751 Subtarget.getFrameLowering()->getTOCSaveOffset();
7766 for (
auto Reg : RegsToPass) {
7771 const int SPDiff = 0;
7772 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7773 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7781 const Type *RetTy)
const {
7783 CCState CCInfo(CallConv, isVarArg, MF, RVLocs,
Context);
7784 return CCInfo.CheckReturn(
7799 CCInfo.AnalyzeReturn(Outs,
7808 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7809 CCValAssign &VA = RVLocs[i];
7812 SDValue Arg = OutVals[RealResIdx];
7827 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7828 bool isLittleEndian = Subtarget.isLittleEndian();
7831 DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7835 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7850 RetOps.push_back(Glue);
7852 return DAG.
getNode(PPCISD::RET_GLUE, dl, MVT::Other, RetOps);
7856PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7861 EVT IntVT =
Op.getValueType();
7865 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7869 return DAG.
getNode(PPCISD::DYNAREAOFFSET, dl, VTs,
Ops);
7881 bool isPPC64 = Subtarget.isPPC64();
7882 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7891 DAG.
getLoad(PtrVT, dl, Chain, StackPtr, MachinePointerInfo());
7897 return DAG.
getStore(Chain, dl, LoadLinkSP, StackPtr, MachinePointerInfo());
7902 bool isPPC64 = Subtarget.isPPC64();
7907 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
7913 int LROffset = Subtarget.getFrameLowering()->getReturnSaveOffset();
7923PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
7925 bool isPPC64 = Subtarget.isPPC64();
7930 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
7936 int FPOffset = Subtarget.getFrameLowering()->getFramePointerSaveOffset();
7959 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7961 SDVTList VTs = DAG.
getVTList(PtrVT, MVT::Other);
7963 return DAG.
getNode(PPCISD::PROBED_ALLOCA, dl, VTs,
Ops);
7964 return DAG.
getNode(PPCISD::DYNALLOC, dl, VTs,
Ops);
7971 bool isPPC64 = Subtarget.isPPC64();
7981 return DAG.
getNode(PPCISD::EH_SJLJ_SETJMP,
DL,
7983 Op.getOperand(0),
Op.getOperand(1));
7989 return DAG.
getNode(PPCISD::EH_SJLJ_LONGJMP,
DL, MVT::Other,
7990 Op.getOperand(0),
Op.getOperand(1));
7994 if (
Op.getValueType().isVector())
7995 return LowerVectorLoad(
Op, DAG);
7997 assert(
Op.getValueType() == MVT::i1 &&
7998 "Custom lowering only for i1 loads");
8007 MachineMemOperand *MMO =
LD->getMemOperand();
8011 BasePtr, MVT::i8, MMO);
8019 if (
Op.getOperand(1).getValueType().isVector())
8020 return LowerVectorStore(
Op, DAG);
8022 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
8023 "Custom lowering only for i1 stores");
8033 MachineMemOperand *MMO =
ST->getMemOperand();
8042 assert(
Op.getValueType() == MVT::i1 &&
8043 "Custom lowering only for i1 results");
8071 EVT TrgVT =
Op.getValueType();
8095 if (SrcSize == 256) {
8106 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8112 SmallVector<int, 16> ShuffV;
8113 if (Subtarget.isLittleEndian())
8114 for (
unsigned i = 0; i < TrgNumElts; ++i)
8117 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8121 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8134 EVT ResVT =
Op.getValueType();
8135 EVT CmpVT =
Op.getOperand(0).getValueType();
8137 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8143 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8156 SDNodeFlags
Flags =
Op.getNode()->getFlags();
8160 if (Subtarget.hasP9Vector() &&
LHS == TV &&
RHS == FV) {
8192 if (
LHS.getValueType() == MVT::f32)
8194 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8197 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8205 if (
LHS.getValueType() == MVT::f32)
8207 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8214 if (
LHS.getValueType() == MVT::f32)
8216 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8228 if (
Cmp.getValueType() == MVT::f32)
8230 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8233 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8238 if (
Cmp.getValueType() == MVT::f32)
8240 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8244 if (
Cmp.getValueType() == MVT::f32)
8246 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8250 if (
Cmp.getValueType() == MVT::f32)
8252 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8256 if (
Cmp.getValueType() == MVT::f32)
8258 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8267 case PPCISD::FCTIDZ:
8268 return PPCISD::STRICT_FCTIDZ;
8269 case PPCISD::FCTIWZ:
8270 return PPCISD::STRICT_FCTIWZ;
8271 case PPCISD::FCTIDUZ:
8272 return PPCISD::STRICT_FCTIDUZ;
8273 case PPCISD::FCTIWUZ:
8274 return PPCISD::STRICT_FCTIWUZ;
8276 return PPCISD::STRICT_FCFID;
8277 case PPCISD::FCFIDU:
8278 return PPCISD::STRICT_FCFIDU;
8279 case PPCISD::FCFIDS:
8280 return PPCISD::STRICT_FCFIDS;
8281 case PPCISD::FCFIDUS:
8282 return PPCISD::STRICT_FCFIDUS;
8289 bool IsStrict =
Op->isStrictFPOpcode();
8298 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8300 MVT DestTy =
Op.getSimpleValueType();
8301 assert(Src.getValueType().isFloatingPoint() &&
8302 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8303 DestTy == MVT::i64) &&
8304 "Invalid FP_TO_INT types");
8305 if (Src.getValueType() == MVT::f32) {
8309 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8314 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8320 Opc = IsSigned ? PPCISD::FCTIWZ
8321 : (Subtarget.hasFPCVT() ? PPCISD::FCTIWUZ : PPCISD::FCTIDZ);
8324 assert((IsSigned || Subtarget.hasFPCVT()) &&
8325 "i64 FP_TO_UINT is supported only with FPCVT");
8326 Opc = IsSigned ? PPCISD::FCTIDZ : PPCISD::FCTIDUZ;
8328 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8340void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8342 const SDLoc &dl)
const {
8346 bool IsStrict =
Op->isStrictFPOpcode();
8349 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8350 (IsSigned || Subtarget.hasFPCVT());
8353 MachinePointerInfo MPI =
8361 Alignment =
Align(4);
8362 MachineMemOperand *MMO =
8368 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8372 if (
Op.getValueType() == MVT::i32 && !i32Stack &&
8373 !Subtarget.isLittleEndian()) {
8382 RLI.Alignment = Alignment;
8390 const SDLoc &dl)
const {
8393 if (
Op->isStrictFPOpcode())
8400 const SDLoc &dl)
const {
8401 bool IsStrict =
Op->isStrictFPOpcode();
8404 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8405 EVT SrcVT = Src.getValueType();
8406 EVT DstVT =
Op.getValueType();
8409 if (SrcVT == MVT::f128)
8410 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8414 if (SrcVT == MVT::ppcf128) {
8415 if (DstVT == MVT::i32) {
8420 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8431 {Op.getOperand(0), Lo, Hi}, Flags);
8434 {Res.getValue(1), Res}, Flags);
8440 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8464 {Chain, Src, FltOfs}, Flags);
8468 {Chain, Val}, Flags);
8471 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8489 if (Subtarget.hasDirectMove() && Subtarget.isPPC64())
8490 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8493 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8495 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8496 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8507bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8512 if (
Op->isStrictFPOpcode())
8517 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8521 Op.getOperand(0).getValueType())) {
8523 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8528 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8529 LD->isNonTemporal())
8531 if (
LD->getMemoryVT() != MemVT)
8541 RLI.Ptr =
LD->getBasePtr();
8542 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8544 "Non-pre-inc AM on PPC?");
8549 RLI.Chain =
LD->getChain();
8550 RLI.MPI =
LD->getPointerInfo();
8551 RLI.IsDereferenceable =
LD->isDereferenceable();
8552 RLI.IsInvariant =
LD->isInvariant();
8553 RLI.Alignment =
LD->getAlign();
8554 RLI.AAInfo =
LD->getAAInfo();
8555 RLI.Ranges =
LD->getRanges();
8557 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8564bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8565 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8572 if (!Subtarget.hasP9Vector() &&
8576 for (SDUse &Use : Origin->
uses()) {
8579 if (
Use.getResNo() != 0)
8606 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8607 unsigned ConvOpc = IsSingle ? (IsSigned ? PPCISD::FCFIDS : PPCISD::FCFIDUS)
8608 : (IsSigned ? PPCISD::FCFID : PPCISD::FCFIDU);
8609 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8610 if (
Op->isStrictFPOpcode()) {
8612 Chain =
Op.getOperand(0);
8614 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8616 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8624 const SDLoc &dl)
const {
8625 assert((
Op.getValueType() == MVT::f32 ||
8626 Op.getValueType() == MVT::f64) &&
8627 "Invalid floating point type as target of conversion");
8628 assert(Subtarget.hasFPCVT() &&
8629 "Int to FP conversions with direct moves require FPCVT");
8630 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8631 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8634 unsigned MovOpc = (WordInt && !
Signed) ? PPCISD::MTVSRZ : PPCISD::MTVSRA;
8653 for (
unsigned i = 1; i < NumConcat; ++i)
8660 const SDLoc &dl)
const {
8661 bool IsStrict =
Op->isStrictFPOpcode();
8662 unsigned Opc =
Op.getOpcode();
8663 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8666 "Unexpected conversion type");
8667 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8668 "Supports conversions to v2f64/v4f32 only.");
8672 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8675 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8680 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8682 SmallVector<int, 16> ShuffV;
8683 for (
unsigned i = 0; i < WideNumElts; ++i)
8686 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8687 int SaveElts = FourEltRes ? 4 : 2;
8688 if (Subtarget.isLittleEndian())
8689 for (
int i = 0; i < SaveElts; i++)
8690 ShuffV[i * Stride] = i;
8692 for (
int i = 1; i <= SaveElts; i++)
8693 ShuffV[i * Stride - 1] = i - 1;
8701 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8702 EVT ExtVT = Src.getValueType();
8703 if (Subtarget.hasP9Altivec())
8714 {Op.getOperand(0), Extend}, Flags);
8716 return DAG.
getNode(
Opc, dl,
Op.getValueType(), Extend);
8724 bool IsStrict =
Op->isStrictFPOpcode();
8725 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8730 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8732 EVT InVT = Src.getValueType();
8733 EVT OutVT =
Op.getValueType();
8736 return LowerINT_TO_FPVector(
Op, DAG, dl);
8739 if (
Op.getValueType() == MVT::f128)
8740 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8743 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8746 if (Src.getValueType() == MVT::i1) {
8758 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8759 Subtarget.isPPC64() && Subtarget.hasFPCVT())
8760 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8762 assert((IsSigned || Subtarget.hasFPCVT()) &&
8763 "UINT_TO_FP is supported only with FPCVT");
8765 if (Src.getValueType() == MVT::i64) {
8780 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT() &&
8781 !
Op->getFlags().hasApproximateFuncs()) {
8821 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8822 Bits = DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8823 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8826 }
else if (Subtarget.hasLFIWAX() &&
8827 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8828 MachineMemOperand *MMO =
8830 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8834 Ops, MVT::i32, MMO);
8837 }
else if (Subtarget.hasFPCVT() &&
8838 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8839 MachineMemOperand *MMO =
8841 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8845 Ops, MVT::i32, MMO);
8848 }
else if (((Subtarget.hasLFIWAX() &&
8850 (Subtarget.hasFPCVT() &&
8865 "Expected an i32 store");
8871 RLI.Alignment =
Align(4);
8873 MachineMemOperand *MMO =
8875 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8878 PPCISD::LFIWZX : PPCISD::LFIWAX,
8879 dl, DAG.
getVTList(MVT::f64, MVT::Other),
8880 Ops, MVT::i32, MMO);
8881 Chain =
Bits.getValue(1);
8889 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8893 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)},
8902 assert(Src.getValueType() == MVT::i32 &&
8903 "Unhandled INT_TO_FP type in custom expander!");
8913 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
8916 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
8926 "Expected an i32 store");
8932 RLI.Alignment =
Align(4);
8935 MachineMemOperand *MMO =
8937 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8943 if (ReusingLoad && RLI.ResChain) {
8947 assert(Subtarget.isPPC64() &&
8948 "i32->FP without LFIWAX supported only on PPC64");
8957 Chain, dl, Ext64, FIdx,
8963 MVT::f64, dl, Chain, FIdx,
8972 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8976 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)}, Flags);
8993 uint64_t
Mode = CVal->getZExtValue();
8994 assert(
Mode < 4 &&
"Unsupported rounding mode!");
8995 unsigned InternalRnd =
Mode ^ (~(
Mode >> 1) & 1);
8996 if (Subtarget.isISA3_0())
8999 PPC::MFFSCRNI, Dl, {MVT::f64, MVT::Other},
9000 {DAG.getConstant(InternalRnd, Dl, MVT::i32, true), Chain}),
9003 (InternalRnd & 2) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9004 {DAG.
getConstant(30, Dl, MVT::i32,
true), Chain});
9006 (InternalRnd & 1) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9024 if (!Subtarget.isISA3_0()) {
9025 MFFS = DAG.
getNode(PPCISD::MFFS, Dl, {MVT::f64, MVT::Other}, Chain);
9029 if (Subtarget.isPPC64()) {
9030 if (Subtarget.isISA3_0()) {
9035 PPC::RLDIMI, Dl, MVT::i64,
9040 NewFPSCR =
SDValue(InsertRN, 0);
9047 SDValue Addr = Subtarget.isLittleEndian()
9051 if (Subtarget.isISA3_0()) {
9052 Chain = DAG.
getStore(Chain, Dl, DstFlag, Addr, MachinePointerInfo());
9054 Chain = DAG.
getStore(Chain, Dl, MFFS, StackSlot, MachinePointerInfo());
9056 DAG.
getLoad(MVT::i32, Dl, Chain, Addr, MachinePointerInfo());
9059 PPC::RLWIMI, Dl, MVT::i32,
9060 {Tmp, DstFlag, DAG.getTargetConstant(0, Dl, MVT::i32),
9061 DAG.getTargetConstant(30, Dl, MVT::i32),
9062 DAG.getTargetConstant(31, Dl, MVT::i32)}),
9064 Chain = DAG.
getStore(Chain, Dl, Tmp, Addr, MachinePointerInfo());
9067 DAG.
getLoad(MVT::f64, Dl, Chain, StackSlot, MachinePointerInfo());
9070 if (Subtarget.isISA3_0())
9076 PPC::MTFSF, Dl, MVT::Other,
9104 EVT VT =
Op.getValueType();
9109 SDValue MFFS = DAG.
getNode(PPCISD::MFFS, dl, {MVT::f64, MVT::Other}, Chain);
9120 Chain = DAG.
getStore(Chain, dl, MFFS, StackSlot, MachinePointerInfo());
9124 "Stack slot adjustment is valid only on big endian subtargets!");
9127 CWD = DAG.
getLoad(MVT::i32, dl, Chain, Addr, MachinePointerInfo());
9154 EVT VT =
Op.getValueType();
9158 VT ==
Op.getOperand(1).getValueType() &&
9178 SDValue OutOps[] = { OutLo, OutHi };
9183 EVT VT =
Op.getValueType();
9187 VT ==
Op.getOperand(1).getValueType() &&
9207 SDValue OutOps[] = { OutLo, OutHi };
9213 EVT VT =
Op.getValueType();
9216 VT ==
Op.getOperand(1).getValueType() &&
9236 SDValue OutOps[] = { OutLo, OutHi };
9243 EVT VT =
Op.getValueType();
9250 EVT AmtVT =
Z.getValueType();
9260 X = DAG.
getNode(PPCISD::SHL, dl, VT,
X, IsFSHL ? Z : SubZ);
9261 Y = DAG.
getNode(PPCISD::SRL, dl, VT,
Y, IsFSHL ? SubZ : Z);
9273 static const MVT VTys[] = {
9274 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9277 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9280 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9285 EVT CanonicalVT = VTys[SplatSize-1];
9298 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9299 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9308 EVT DestVT = MVT::Other) {
9309 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9318 EVT DestVT = MVT::Other) {
9321 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9333 for (
unsigned i = 0; i != 16; ++i)
9354 EVT VecVT = V->getValueType(0);
9355 bool RightType = VecVT == MVT::v2f64 ||
9356 (HasP8Vector && VecVT == MVT::v4f32) ||
9357 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9361 bool IsSplat =
true;
9362 bool IsLoad =
false;
9368 if (V->isConstant())
9370 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9371 if (V->getOperand(i).isUndef())
9375 if (V->getOperand(i).getOpcode() ==
ISD::LOAD ||
9377 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9379 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9381 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD))
9385 if (V->getOperand(i) != Op0 ||
9386 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9389 return !(IsSplat && IsLoad);
9399 (
Op.getValueType() != MVT::f128))
9404 if ((
Lo.getValueType() != MVT::i64) || (
Hi.getValueType() != MVT::i64))
9407 if (!Subtarget.isLittleEndian())
9410 return DAG.
getNode(PPCISD::BUILD_FP128, dl, MVT::f128,
Lo,
Hi);
9418 InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED) {
9419 IsPermuted = InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED;
9432 APFloat APFloatToConvert = ArgAPFloat;
9433 bool LosesInfo =
true;
9438 ArgAPFloat = APFloatToConvert;
9460 APFloat APFloatToConvert = ArgAPFloat;
9461 bool LosesInfo =
true;
9465 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9474 EVT Ty =
Op->getValueType(0);
9477 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9486 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9490 if (Ty == MVT::v2i64) {
9493 if (MemVT == MVT::i32) {
9495 Opcode = PPCISD::ZEXT_LD_SPLAT;
9497 Opcode = PPCISD::SEXT_LD_SPLAT;
9505 bool IsLittleEndian) {
9511 APInt ConstValue(VTSize, 0);
9515 unsigned BitPos = 0;
9523 ConstValue.
insertBits(CN->getAPIntValue().zextOrTrunc(EltWidth),
9524 IsLittleEndian ? BitPos : VTSize - EltWidth - BitPos);
9528 for (
unsigned J = 0; J < 16; ++J) {
9530 if (ExtractValue != 0x00 && ExtractValue != 0xFF)
9532 if (ExtractValue == 0xFF)
9547 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9549 if (Subtarget.hasP10Vector()) {
9550 APInt BitMask(32, 0);
9556 BitMask != 0 && BitMask != 0xffff) {
9558 MachineSDNode *MSDNode =
9570 if (
SDValue VecPat = combineBVLoadsSpecialValue(
Op, DAG))
9574 APInt APSplatBits, APSplatUndef;
9575 unsigned SplatBitSize;
9577 bool BVNIsConstantSplat =
9579 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
9585 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9586 Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
9589 if ((
Op->getValueType(0) == MVT::v2f64) &&
9592 PPCISD::XXSPLTI_SP_TO_DP, dl, MVT::v2f64,
9608 PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9614 DAG.
getNode(PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9622 bool IsSplat64 =
false;
9623 uint64_t SplatBits = 0;
9624 int32_t SextVal = 0;
9625 if (BVNIsConstantSplat && SplatBitSize <= 64) {
9627 if (SplatBitSize <= 32) {
9629 }
else if (SplatBitSize == 64 && Subtarget.hasP8Altivec()) {
9630 int64_t Splat64Val =
static_cast<int64_t
>(SplatBits);
9631 bool P9Vector = Subtarget.hasP9Vector();
9632 int32_t
Hi = P9Vector ? 127 : 15;
9633 int32_t
Lo = P9Vector ? -128 : -16;
9634 IsSplat64 = Splat64Val >=
Lo && Splat64Val <=
Hi;
9635 SextVal =
static_cast<int32_t
>(SplatBits);
9639 if (!BVNIsConstantSplat || (SplatBitSize > 32 && !IsSplat64)) {
9640 unsigned NewOpcode = PPCISD::LD_SPLAT;
9646 const SDValue *InputLoad = &
Op.getOperand(0);
9651 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9652 unsigned ElementSize =
9653 MemorySize * ((NewOpcode == PPCISD::LD_SPLAT) ? 1 : 2);
9655 assert(((ElementSize == 2 * MemorySize)
9656 ? (NewOpcode == PPCISD::ZEXT_LD_SPLAT ||
9657 NewOpcode == PPCISD::SEXT_LD_SPLAT)
9658 : (NewOpcode == PPCISD::LD_SPLAT)) &&
9659 "Unmatched element size and opcode!\n");
9664 unsigned NumUsesOfInputLD = 128 / ElementSize;
9666 if (BVInOp.isUndef())
9681 if (NumUsesOfInputLD == 1 &&
9682 (
Op->getValueType(0) == MVT::v2i64 && NewOpcode != PPCISD::LD_SPLAT &&
9683 !Subtarget.isLittleEndian() && Subtarget.hasVSX() &&
9684 Subtarget.hasLFIWAX()))
9692 if (NumUsesOfInputLD == 1 && Subtarget.isLittleEndian() &&
9693 Subtarget.isISA3_1() && ElementSize <= 16)
9696 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9698 Subtarget.hasVSX()) {
9705 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other),
Ops,
9706 LD->getMemoryVT(),
LD->getMemOperand());
9718 if (Subtarget.hasVSX() && Subtarget.isPPC64() &&
9720 Subtarget.hasP8Vector()))
9726 unsigned SplatSize = SplatBitSize / 8;
9731 if (SplatBits == 0) {
9733 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9745 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 2)
9747 Op.getValueType(), DAG, dl);
9749 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 4)
9754 if (Subtarget.hasP9Vector() && SplatSize == 1)
9760 if (SextVal >= -16 && SextVal <= 15) {
9763 unsigned UseSize = SplatSize == 8 ? 4 : SplatSize;
9773 if (Subtarget.hasP9Vector() && SextVal >= -128 && SextVal <= 127) {
9779 switch (SplatSize) {
9783 IID = Intrinsic::ppc_altivec_vupklsb;
9787 IID = Intrinsic::ppc_altivec_vextsb2w;
9791 IID = Intrinsic::ppc_altivec_vextsb2d;
9798 assert(!IsSplat64 &&
"Unhandled 64-bit splat pattern");
9807 if (SextVal >= -32 && SextVal <= 31) {
9812 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9813 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9816 if (VT ==
Op.getValueType())
9825 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9839 static const signed char SplatCsts[] = {
9840 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9841 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9844 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9847 int i = SplatCsts[idx];
9851 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9854 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9856 static const unsigned IIDs[] = {
9857 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9858 Intrinsic::ppc_altivec_vslw
9865 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9867 static const unsigned IIDs[] = {
9868 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9869 Intrinsic::ppc_altivec_vsrw
9876 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9877 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9879 static const unsigned IIDs[] = {
9880 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
9881 Intrinsic::ppc_altivec_vrlw
9888 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
9890 unsigned Amt = Subtarget.isLittleEndian() ? 15 : 1;
9894 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
9896 unsigned Amt = Subtarget.isLittleEndian() ? 14 : 2;
9900 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
9902 unsigned Amt = Subtarget.isLittleEndian() ? 13 : 3;
9915 unsigned OpNum = (PFEntry >> 26) & 0x0F;
9916 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
9917 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
9933 if (LHSID == (1*9+2)*9+3)
return LHS;
9934 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
9946 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
9947 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
9948 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
9949 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
9952 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
9953 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
9954 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
9955 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
9958 for (
unsigned i = 0; i != 16; ++i)
9959 ShufIdxs[i] = (i&3)+0;
9962 for (
unsigned i = 0; i != 16; ++i)
9963 ShufIdxs[i] = (i&3)+4;
9966 for (
unsigned i = 0; i != 16; ++i)
9967 ShufIdxs[i] = (i&3)+8;
9970 for (
unsigned i = 0; i != 16; ++i)
9971 ShufIdxs[i] = (i&3)+12;
9992 const unsigned BytesInVector = 16;
9993 bool IsLE = Subtarget.isLittleEndian();
9997 unsigned ShiftElts = 0, InsertAtByte = 0;
10001 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
10002 0, 15, 14, 13, 12, 11, 10, 9};
10003 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
10004 1, 2, 3, 4, 5, 6, 7, 8};
10006 ArrayRef<int>
Mask =
N->getMask();
10007 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
10019 bool FoundCandidate =
false;
10023 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
10026 for (
unsigned i = 0; i < BytesInVector; ++i) {
10027 unsigned CurrentElement =
Mask[i];
10030 if (V2.
isUndef() && CurrentElement != VINSERTBSrcElem)
10033 bool OtherElementsInOrder =
true;
10036 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
10043 (!V2.
isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
10044 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
10045 OtherElementsInOrder =
false;
10052 if (OtherElementsInOrder) {
10059 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
10060 : BigEndianShifts[CurrentElement & 0xF];
10061 Swap = CurrentElement < BytesInVector;
10063 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
10064 FoundCandidate =
true;
10069 if (!FoundCandidate)
10079 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10081 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8, V1, Shl,
10084 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8, V1, V2,
10093 const unsigned NumHalfWords = 8;
10094 const unsigned BytesInVector = NumHalfWords * 2;
10099 bool IsLE = Subtarget.isLittleEndian();
10103 unsigned ShiftElts = 0, InsertAtByte = 0;
10107 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
10108 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
10111 uint32_t OriginalOrderLow = 0x1234567;
10112 uint32_t OriginalOrderHigh = 0x89ABCDEF;
10115 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10116 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10133 bool FoundCandidate =
false;
10136 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10137 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10139 uint32_t MaskOtherElts = ~(0xF <<
MaskShift);
10140 uint32_t TargetOrder = 0x0;
10147 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
10148 TargetOrder = OriginalOrderLow;
10152 if (MaskOneElt == VINSERTHSrcElem &&
10153 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10154 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10155 FoundCandidate =
true;
10161 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
10163 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10165 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
10166 : BigEndianShifts[MaskOneElt & 0x7];
10167 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10168 Swap = MaskOneElt < NumHalfWords;
10169 FoundCandidate =
true;
10175 if (!FoundCandidate)
10187 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10190 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
10195 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
10210 auto ShuffleMask = SVN->
getMask();
10225 ShuffleMask = CommutedSV->
getMask();
10234 APInt APSplatValue, APSplatUndef;
10235 unsigned SplatBitSize;
10238 HasAnyUndefs, 0, !Subtarget.isLittleEndian()) ||
10250 bool IsLE = Subtarget.isLittleEndian();
10251 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
10252 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
10253 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
10255 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
10256 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
10257 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
10265 for (; SplatBitSize < 32; SplatBitSize <<= 1)
10266 SplatVal |= (SplatVal << SplatBitSize);
10269 PPCISD::XXSPLTI32DX,
DL, MVT::v2i64, DAG.
getBitcast(MVT::v2i64,
LHS),
10280 assert(
Op.getValueType() == MVT::v1i128 &&
10281 "Only set v1i128 as custom, other type shouldn't reach here!");
10286 if (SHLAmt % 8 == 0) {
10287 std::array<int, 16>
Mask;
10288 std::iota(
Mask.begin(),
Mask.end(), 0);
10289 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10318 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10323 V1 =
Op.getOperand(0);
10324 V2 =
Op.getOperand(1);
10326 EVT VT =
Op.getValueType();
10327 bool isLittleEndian = Subtarget.isLittleEndian();
10329 unsigned ShiftElts, InsertAtByte;
10335 bool IsPermutedLoad =
false;
10337 if (InputLoad && Subtarget.hasVSX() && V2.
isUndef() &&
10347 if (IsPermutedLoad) {
10348 assert((isLittleEndian || IsFourByte) &&
10349 "Unexpected size for permuted load on big endian target");
10350 SplatIdx += IsFourByte ? 2 : 1;
10351 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10352 "Splat of a value outside of the loaded memory");
10357 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10360 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10362 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10366 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10379 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10382 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10391 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10394 if (Subtarget.hasP9Vector() &&
10404 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv2, Conv2,
10406 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Shl,
10410 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Conv2,
10415 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
10417 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10418 return SplatInsertNode;
10421 if (Subtarget.hasP9Altivec()) {
10423 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10426 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10430 if (Subtarget.hasVSX() &&
10438 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv1, Conv2,
10443 if (Subtarget.hasVSX() &&
10451 SDValue PermDI = DAG.
getNode(PPCISD::XXPERMDI, dl, MVT::v2i64, Conv1, Conv2,
10456 if (Subtarget.hasP9Vector()) {
10476 if (Subtarget.hasVSX()) {
10489 SDValue Swap = DAG.
getNode(PPCISD::SWAP_NO_CHAIN, dl, MVT::v2f64, Conv);
10497 if (V2.isUndef()) {
10510 (Subtarget.hasP8Altivec() && (
10521 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10531 (Subtarget.hasP8Altivec() && (
10539 ArrayRef<int> PermMask = SVOp->
getMask();
10542 unsigned PFIndexes[4];
10543 bool isFourElementShuffle =
true;
10544 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10546 unsigned EltNo = 8;
10547 for (
unsigned j = 0;
j != 4; ++
j) {
10548 if (PermMask[i * 4 + j] < 0)
10551 unsigned ByteSource = PermMask[i * 4 +
j];
10552 if ((ByteSource & 3) != j) {
10553 isFourElementShuffle =
false;
10558 EltNo = ByteSource / 4;
10559 }
else if (EltNo != ByteSource / 4) {
10560 isFourElementShuffle =
false;
10564 PFIndexes[i] = EltNo;
10572 if (isFourElementShuffle) {
10574 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10575 PFIndexes[2] * 9 + PFIndexes[3];
10578 unsigned Cost = (PFEntry >> 30);
10598 if (V2.isUndef()) V2 = V1;
10600 return LowerVPERM(
Op, DAG, PermMask, VT, V1, V2);
10606 unsigned Opcode = PPCISD::VPERM;
10609 bool NeedSwap =
false;
10610 bool isLittleEndian = Subtarget.isLittleEndian();
10611 bool isPPC64 = Subtarget.isPPC64();
10613 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10615 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10616 "XXPERM instead\n");
10617 Opcode = PPCISD::XXPERM;
10625 NeedSwap = !NeedSwap;
10660 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10662 if (V1HasXXSWAPD) {
10665 else if (SrcElt < 16)
10668 if (V2HasXXSWAPD) {
10671 else if (SrcElt > 15)
10680 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10681 if (isLittleEndian)
10683 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10686 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10689 if (V1HasXXSWAPD) {
10693 if (V2HasXXSWAPD) {
10698 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10699 if (ValType != MVT::v2f64)
10705 ShufflesHandledWithVPERM++;
10709 if (Opcode == PPCISD::XXPERM) {
10710 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10712 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10715 dbgs() <<
"With the following permute control vector:\n";
10719 if (Opcode == PPCISD::XXPERM)
10720 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10724 if (isLittleEndian)
10730 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10742 switch (IntrinsicID) {
10746 case Intrinsic::ppc_altivec_vcmpbfp_p:
10750 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10754 case Intrinsic::ppc_altivec_vcmpequb_p:
10758 case Intrinsic::ppc_altivec_vcmpequh_p:
10762 case Intrinsic::ppc_altivec_vcmpequw_p:
10766 case Intrinsic::ppc_altivec_vcmpequd_p:
10767 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10773 case Intrinsic::ppc_altivec_vcmpneb_p:
10774 case Intrinsic::ppc_altivec_vcmpneh_p:
10775 case Intrinsic::ppc_altivec_vcmpnew_p:
10776 case Intrinsic::ppc_altivec_vcmpnezb_p:
10777 case Intrinsic::ppc_altivec_vcmpnezh_p:
10778 case Intrinsic::ppc_altivec_vcmpnezw_p:
10779 if (Subtarget.hasP9Altivec()) {
10780 switch (IntrinsicID) {
10783 case Intrinsic::ppc_altivec_vcmpneb_p:
10786 case Intrinsic::ppc_altivec_vcmpneh_p:
10789 case Intrinsic::ppc_altivec_vcmpnew_p:
10792 case Intrinsic::ppc_altivec_vcmpnezb_p:
10795 case Intrinsic::ppc_altivec_vcmpnezh_p:
10798 case Intrinsic::ppc_altivec_vcmpnezw_p:
10806 case Intrinsic::ppc_altivec_vcmpgefp_p:
10810 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10814 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10818 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10822 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10826 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10827 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10833 case Intrinsic::ppc_altivec_vcmpgtub_p:
10837 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10841 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10845 case Intrinsic::ppc_altivec_vcmpgtud_p:
10846 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10853 case Intrinsic::ppc_altivec_vcmpequq:
10854 case Intrinsic::ppc_altivec_vcmpgtsq:
10855 case Intrinsic::ppc_altivec_vcmpgtuq:
10856 if (!Subtarget.isISA3_1())
10858 switch (IntrinsicID) {
10861 case Intrinsic::ppc_altivec_vcmpequq:
10864 case Intrinsic::ppc_altivec_vcmpgtsq:
10867 case Intrinsic::ppc_altivec_vcmpgtuq:
10874 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10875 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10876 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10877 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10878 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10879 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10880 if (Subtarget.hasVSX()) {
10881 switch (IntrinsicID) {
10882 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10885 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10888 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10891 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10894 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10897 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10907 case Intrinsic::ppc_altivec_vcmpbfp:
10910 case Intrinsic::ppc_altivec_vcmpeqfp:
10913 case Intrinsic::ppc_altivec_vcmpequb:
10916 case Intrinsic::ppc_altivec_vcmpequh:
10919 case Intrinsic::ppc_altivec_vcmpequw:
10922 case Intrinsic::ppc_altivec_vcmpequd:
10923 if (Subtarget.hasP8Altivec())
10928 case Intrinsic::ppc_altivec_vcmpneb:
10929 case Intrinsic::ppc_altivec_vcmpneh:
10930 case Intrinsic::ppc_altivec_vcmpnew:
10931 case Intrinsic::ppc_altivec_vcmpnezb:
10932 case Intrinsic::ppc_altivec_vcmpnezh:
10933 case Intrinsic::ppc_altivec_vcmpnezw:
10934 if (Subtarget.hasP9Altivec())
10935 switch (IntrinsicID) {
10938 case Intrinsic::ppc_altivec_vcmpneb:
10941 case Intrinsic::ppc_altivec_vcmpneh:
10944 case Intrinsic::ppc_altivec_vcmpnew:
10947 case Intrinsic::ppc_altivec_vcmpnezb:
10950 case Intrinsic::ppc_altivec_vcmpnezh:
10953 case Intrinsic::ppc_altivec_vcmpnezw:
10960 case Intrinsic::ppc_altivec_vcmpgefp:
10963 case Intrinsic::ppc_altivec_vcmpgtfp:
10966 case Intrinsic::ppc_altivec_vcmpgtsb:
10969 case Intrinsic::ppc_altivec_vcmpgtsh:
10972 case Intrinsic::ppc_altivec_vcmpgtsw:
10975 case Intrinsic::ppc_altivec_vcmpgtsd:
10976 if (Subtarget.hasP8Altivec())
10981 case Intrinsic::ppc_altivec_vcmpgtub:
10984 case Intrinsic::ppc_altivec_vcmpgtuh:
10987 case Intrinsic::ppc_altivec_vcmpgtuw:
10990 case Intrinsic::ppc_altivec_vcmpgtud:
10991 if (Subtarget.hasP8Altivec())
10996 case Intrinsic::ppc_altivec_vcmpequq_p:
10997 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10998 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10999 if (!Subtarget.isISA3_1())
11001 switch (IntrinsicID) {
11004 case Intrinsic::ppc_altivec_vcmpequq_p:
11007 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11010 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11024 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
11028 switch (IntrinsicID) {
11029 case Intrinsic::thread_pointer:
11031 if (Subtarget.isPPC64())
11035 case Intrinsic::ppc_rldimi: {
11036 assert(Subtarget.isPPC64() &&
"rldimi is only available in 64-bit!");
11038 APInt
Mask =
Op.getConstantOperandAPInt(4);
11040 return Op.getOperand(2);
11041 if (
Mask.isAllOnes())
11043 uint64_t SH =
Op.getConstantOperandVal(3);
11044 unsigned MB = 0, ME = 0;
11048 if (ME < 63 - SH) {
11051 }
else if (ME > 63 - SH) {
11057 {Op.getOperand(2), Src,
11058 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
11059 DAG.getTargetConstant(MB, dl, MVT::i32)}),
11063 case Intrinsic::ppc_rlwimi: {
11064 APInt
Mask =
Op.getConstantOperandAPInt(4);
11066 return Op.getOperand(2);
11067 if (
Mask.isAllOnes())
11070 unsigned MB = 0, ME = 0;
11074 PPC::RLWIMI, dl, MVT::i32,
11075 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
11076 DAG.getTargetConstant(MB, dl, MVT::i32),
11077 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11081 case Intrinsic::ppc_rlwnm: {
11082 if (
Op.getConstantOperandVal(3) == 0)
11084 unsigned MB = 0, ME = 0;
11089 {Op.getOperand(1), Op.getOperand(2),
11090 DAG.getTargetConstant(MB, dl, MVT::i32),
11091 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11095 case Intrinsic::ppc_mma_disassemble_acc: {
11096 if (Subtarget.isISAFuture()) {
11097 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11108 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11109 Subtarget.isLittleEndian() ? Value2 :
Value,
11110 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11114 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11115 Subtarget.isLittleEndian() ? Value2 :
Value,
11116 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11120 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11121 Subtarget.isLittleEndian() ?
Value : Value2,
11122 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11126 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11127 Subtarget.isLittleEndian() ?
Value : Value2,
11128 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11135 case Intrinsic::ppc_vsx_disassemble_pair: {
11138 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
11140 WideVec = DAG.
getNode(PPCISD::XXMFACC, dl, MVT::v512i1, WideVec);
11143 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
11145 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8, WideVec,
11146 DAG.
getConstant(Subtarget.isLittleEndian() ? NumVecs - 1 - VecNo
11154 case Intrinsic::ppc_mma_build_dmr: {
11157 for (
int i = 1; i < 9; i += 2) {
11165 DAG.
getNode(PPCISD::PAIR_BUILD, dl, MVT::v256i1, {Hi, Lo}));
11172 case Intrinsic::ppc_mma_dmxxextfdmr512: {
11173 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr512 requires ISA Future");
11175 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11176 "Specify P of 0 or 1 for lower or upper 512 bytes");
11177 unsigned HiLo = Idx->getSExtValue();
11181 Opcode = PPC::DMXXEXTFDMR512;
11182 Subx = PPC::sub_wacc_lo;
11184 Opcode = PPC::DMXXEXTFDMR512_HI;
11185 Subx = PPC::sub_wacc_hi;
11188 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
11192 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11196 case Intrinsic::ppc_mma_dmxxextfdmr256: {
11197 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr256 requires ISA Future");
11199 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11200 "Specify a dmr row pair 0-3");
11201 unsigned IdxVal = Idx->getSExtValue();
11205 Subx = PPC::sub_dmrrowp0;
11208 Subx = PPC::sub_dmrrowp1;
11211 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11214 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11218 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v256i1,
11224 DAG.
getMachineNode(PPC::DMXXEXTFDMR256, dl, MVT::v256i1, {Subreg, P}),
11228 case Intrinsic::ppc_mma_dmxxinstdmr512: {
11229 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr512 requires ISA Future");
11231 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11232 "Specify P of 0 or 1 for lower or upper 512 bytes");
11233 unsigned HiLo = Idx->getSExtValue();
11237 Opcode = PPC::DMXXINSTDMR512;
11238 Subx = PPC::sub_wacc_lo;
11240 Opcode = PPC::DMXXINSTDMR512_HI;
11241 Subx = PPC::sub_wacc_hi;
11251 case Intrinsic::ppc_mma_dmxxinstdmr256: {
11252 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr256 requires ISA Future");
11254 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11255 "Specify a dmr row pair 0-3");
11256 unsigned IdxVal = Idx->getSExtValue();
11260 Subx = PPC::sub_dmrrowp0;
11263 Subx = PPC::sub_dmrrowp1;
11266 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11269 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11278 Op.getOperand(1), DMRRowp,
SubReg),
11282 case Intrinsic::ppc_mma_xxmfacc:
11283 case Intrinsic::ppc_mma_xxmtacc: {
11285 if (!Subtarget.isISAFuture())
11296 case Intrinsic::ppc_unpack_longdouble: {
11298 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11299 "Argument of long double unpack must be 0 or 1!");
11302 Idx->getValueType(0)));
11305 case Intrinsic::ppc_compare_exp_lt:
11306 case Intrinsic::ppc_compare_exp_gt:
11307 case Intrinsic::ppc_compare_exp_eq:
11308 case Intrinsic::ppc_compare_exp_uo: {
11310 switch (IntrinsicID) {
11311 case Intrinsic::ppc_compare_exp_lt:
11314 case Intrinsic::ppc_compare_exp_gt:
11317 case Intrinsic::ppc_compare_exp_eq:
11320 case Intrinsic::ppc_compare_exp_uo:
11326 PPC::SELECT_CC_I4, dl, MVT::i32,
11327 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
11328 Op.getOperand(1), Op.getOperand(2)),
11330 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11331 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
11334 case Intrinsic::ppc_test_data_class: {
11335 EVT OpVT =
Op.getOperand(1).getValueType();
11336 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
11337 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
11341 PPC::SELECT_CC_I4, dl, MVT::i32,
11342 {SDValue(DAG.getMachineNode(CmprOpc, dl, MVT::i32, Op.getOperand(2),
11345 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11346 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
11349 case Intrinsic::ppc_fnmsub: {
11350 EVT VT =
Op.getOperand(1).getValueType();
11351 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
11356 return DAG.
getNode(PPCISD::FNMSUB, dl, VT,
Op.getOperand(1),
11357 Op.getOperand(2),
Op.getOperand(3));
11359 case Intrinsic::ppc_convert_f128_to_ppcf128:
11360 case Intrinsic::ppc_convert_ppcf128_to_f128: {
11361 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
11362 ? RTLIB::CONVERT_PPCF128_F128
11363 : RTLIB::CONVERT_F128_PPCF128;
11365 std::pair<SDValue, SDValue>
Result =
11366 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
11370 case Intrinsic::ppc_maxfe:
11371 case Intrinsic::ppc_maxfl:
11372 case Intrinsic::ppc_maxfs:
11373 case Intrinsic::ppc_minfe:
11374 case Intrinsic::ppc_minfl:
11375 case Intrinsic::ppc_minfs: {
11376 EVT VT =
Op.getValueType();
11379 [VT](
const SDUse &Use) { return Use.getValueType() == VT; }) &&
11380 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
11383 if (IntrinsicID == Intrinsic::ppc_minfe ||
11384 IntrinsicID == Intrinsic::ppc_minfl ||
11385 IntrinsicID == Intrinsic::ppc_minfs)
11406 SDValue Tmp = DAG.
getNode(PPCISD::VCMP, dl,
Op.getOperand(2).getValueType(),
11407 Op.getOperand(1),
Op.getOperand(2),
11418 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11426 switch (
Op.getConstantOperandVal(1)) {
11431 Bitx = PPC::sub_eq;
11432 SetOp = PPCISD::SETBC;
11437 Bitx = PPC::sub_eq;
11438 SetOp = PPCISD::SETBCR;
11443 Bitx = PPC::sub_lt;
11444 SetOp = PPCISD::SETBC;
11449 Bitx = PPC::sub_lt;
11450 SetOp = PPCISD::SETBCR;
11455 if (Subtarget.isISA3_1()) {
11460 CR6Reg, SubRegIdx, GlueOp),
11462 return DAG.
getNode(SetOp, dl, MVT::i32, CRBit);
11490 switch (
Op.getConstantOperandVal(ArgStart)) {
11491 case Intrinsic::ppc_cfence: {
11492 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11493 SDValue Val =
Op.getOperand(ArgStart + 1);
11495 if (Ty == MVT::i128) {
11500 unsigned Opcode = Subtarget.isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11503 Opcode,
DL, MVT::Other,
11508 case Intrinsic::ppc_mma_disassemble_dmr: {
11510 Op.getOperand(ArgStart + 1), MachinePointerInfo());
11521 if (!Subtarget.isPPC64())
11529 int VectorIndex = 0;
11530 if (Subtarget.isLittleEndian())
11542 "Expecting an atomic compare-and-swap here.");
11545 EVT MemVT = AtomicNode->getMemoryVT();
11563 for (
int i = 0, e = AtomicNode->getNumOperands(); i < e; i++)
11564 Ops.push_back(AtomicNode->getOperand(i));
11566 MachineMemOperand *MMO = AtomicNode->getMemOperand();
11567 SDVTList Tys = DAG.
getVTList(MVT::i32, MVT::Other);
11569 (MemVT == MVT::i8) ? PPCISD::ATOMIC_CMP_SWAP_8 : PPCISD::ATOMIC_CMP_SWAP_16;
11576 EVT MemVT =
N->getMemoryVT();
11578 "Expect quadword atomic operations");
11580 unsigned Opc =
N->getOpcode();
11585 SDVTList Tys = DAG.
getVTList(MVT::i64, MVT::i64, MVT::Other);
11588 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11589 for (
int I = 1,
E =
N->getNumOperands();
I <
E; ++
I)
11590 Ops.push_back(
N->getOperand(
I));
11592 Ops, MemVT,
N->getMemOperand());
11599 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11606 SDVTList Tys = DAG.
getVTList(MVT::Other);
11609 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11615 Ops.push_back(ValLo);
11616 Ops.push_back(ValHi);
11617 Ops.push_back(
N->getOperand(2));
11619 N->getMemOperand());
11631 enum DataClassMask {
11633 DC_NEG_INF = 1 << 4,
11634 DC_POS_INF = 1 << 5,
11635 DC_NEG_ZERO = 1 << 2,
11636 DC_POS_ZERO = 1 << 3,
11637 DC_NEG_SUBNORM = 1,
11638 DC_POS_SUBNORM = 1 << 1,
11641 EVT VT =
Op.getValueType();
11643 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11644 : VT == MVT::f64 ? PPC::XSTSTDCDP
11655 return DAG.
getNOT(Dl, Rev, MVT::i1);
11662 TestOp, Dl, MVT::i32,
11664 DC_NEG_ZERO | DC_POS_ZERO |
11665 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11671 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11677 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11682 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11695 bool IsQuiet = Mask &
fcQNan;
11701 if (VT == MVT::f128) {
11705 QuietMask = 0x8000;
11706 }
else if (VT == MVT::f64) {
11707 if (Subtarget.isPPC64()) {
11718 QuietMask = 0x80000;
11719 }
else if (VT == MVT::f32) {
11721 QuietMask = 0x400000;
11737 unsigned NativeMask = 0;
11739 NativeMask |= DC_NAN;
11741 NativeMask |= DC_NEG_INF;
11743 NativeMask |= DC_POS_INF;
11745 NativeMask |= DC_NEG_ZERO;
11747 NativeMask |= DC_POS_ZERO;
11749 NativeMask |= DC_NEG_SUBNORM;
11751 NativeMask |= DC_POS_SUBNORM;
11754 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11756 TestOp, Dl, MVT::i32,
11765 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11767 uint64_t RHSC =
Op.getConstantOperandVal(1);
11770 if (
LHS.getValueType() == MVT::ppcf128) {
11794 bool Future = Subtarget.isISAFuture();
11797 "Mask predication not supported");
11800 unsigned IID = Future ? Intrinsic::ppc_vsx_lxvrl : Intrinsic::ppc_vsx_lxvl;
11801 unsigned EltBits =
Op->getValueType(0).getScalarType().getSizeInBits();
11805 SDVTList Tys = DAG.
getVTList(
Op->getValueType(0), MVT::Other);
11808 VPLD->getMemoryVT(), VPLD->getMemOperand());
11815 "Mask predication not supported");
11820 Op->getOperand(1).getValueType().getScalarType().getSizeInBits();
11821 bool Future = Subtarget.isISAFuture();
11822 unsigned IID = Future ? Intrinsic::ppc_vsx_stxvrl : Intrinsic::ppc_vsx_stxvl;
11825 VPST->getChain(), DAG.
getConstant(IID, dl, MVT::i32),
11828 SDVTList Tys = DAG.
getVTList(MVT::Other);
11831 VPST->getMemoryVT(), VPST->getMemOperand());
11842 unsigned EltSize =
Op.getValueType().getScalarSizeInBits();
11844 int64_t
IntVal =
Op.getConstantOperandVal(0);
11845 if (IntVal >= -16 && IntVal <= 15)
11851 if (Subtarget.hasLFIWAX() && Subtarget.hasVSX() &&
11856 MachineMemOperand *MMO =
11858 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
11861 PPCISD::LD_SPLAT, dl, DAG.
getVTList(MVT::v4i32, MVT::Other),
Ops,
11865 return Bits.getValue(0);
11881 !Subtarget.isLittleEndian() && ValVT.
isInteger() &&
11886 64 -
Op.getValueType().getScalarSizeInBits(), dl, ShiftAmountTy);
11893 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx,
11894 MachinePointerInfo());
11901 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx, MachinePointerInfo());
11907 "Should only be called for ISD::INSERT_VECTOR_ELT");
11911 EVT VT =
Op.getValueType();
11916 if (VT == MVT::v2f64 &&
C)
11919 if (Subtarget.hasP9Vector()) {
11928 if ((VT == MVT::v4f32) && (V2.
getValueType() == MVT::f32) &&
11934 BitcastLoad,
Op.getOperand(2));
11935 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
11939 if (Subtarget.isISA3_1()) {
11940 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.isPPC64())
11944 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
11945 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
11955 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
11958 unsigned InsertAtElement =
C->getZExtValue();
11959 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
11960 if (Subtarget.isLittleEndian()) {
11961 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
11963 return DAG.
getNode(PPCISD::VECINSERT, dl, VT, V1, Mtvsrz,
11975 EVT VT =
Op.getValueType();
11976 bool IsV1024i1 = VT == MVT::v1024i1;
11977 bool IsV2048i1 = VT == MVT::v2048i1;
11981 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
11983 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
11984 "Dense Math support required.");
11985 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
11994 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
11995 MachineMemOperand *NewMMO =
12003 DAG.
getVTList(MVT::v256i1, MVT::Other),
12004 LoadOps, MVT::v256i1, NewMMO);
12009 if (Subtarget.isLittleEndian()) {
12010 std::reverse(Loads.
begin(), Loads.
end());
12011 std::reverse(LoadChains.
begin(), LoadChains.
end());
12020 Loads[2], Loads[3]),
12036 Loads[4], Loads[5]),
12039 Loads[6], Loads[7]),
12041 const SDValue Dmr1Ops[] = {RC, Dmr1Lo, LoSub, Dmr1Hi, HiSub};
12043 DAG.
getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v1024i1, Dmr1Ops), 0);
12049 const SDValue DmrPOps[] = {DmrPRC,
Value, Dmr0Sub, Dmr1Value, Dmr1Sub};
12052 DAG.
getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v2048i1, DmrPOps), 0);
12065 Pairs[2], Pairs[3]),
12071 {RC, Lo, LoSub, Hi, HiSub}),
12081 EVT VT =
Op.getValueType();
12083 if (VT == MVT::v1024i1 || VT == MVT::v2048i1)
12084 return LowerDMFVectorLoad(
Op, DAG);
12086 if (VT != MVT::v256i1 && VT != MVT::v512i1)
12092 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
12093 "Type unsupported without MMA");
12094 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12095 "Type unsupported without paired vector support");
12100 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12102 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
12111 if (Subtarget.isLittleEndian()) {
12112 std::reverse(Loads.
begin(), Loads.
end());
12113 std::reverse(LoadChains.
begin(), LoadChains.
end());
12117 DAG.
getNode(VT == MVT::v512i1 ? PPCISD::ACC_BUILD : PPCISD::PAIR_BUILD,
12133 bool IsV1024i1 = VT == MVT::v1024i1;
12134 bool IsV2048i1 = VT == MVT::v2048i1;
12138 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12140 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12141 "Dense Math support required.");
12142 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12144 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12147 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12152 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12156 MachineSDNode *ExtNode =
12160 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes,
Hi);
12166 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12172 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12178 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12183 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12188 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12193 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12197 MachineSDNode *ExtNode =
12198 DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr0Lo);
12202 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr0Hi);
12205 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr1Lo);
12209 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr1Hi);
12214 if (Subtarget.isLittleEndian())
12215 std::reverse(Values.
begin(), Values.
end());
12217 SDVTList Tys = DAG.
getVTList(MVT::Other);
12219 StoreChain, DAG.
getConstant(Intrinsic::ppc_vsx_stxvp, dl, MVT::i32),
12223 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12224 MachineMemOperand *NewMMO =
12231 Ops[2] = Values[Idx];
12233 MVT::v256i1, NewMMO);
12249 EVT StoreVT =
Value.getValueType();
12251 if (StoreVT == MVT::v1024i1 || StoreVT == MVT::v2048i1)
12252 return LowerDMFVectorStore(
Op, DAG);
12254 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
12260 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
12261 "Type unsupported without MMA");
12262 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12263 "Type unsupported without paired vector support");
12266 unsigned NumVecs = 2;
12267 if (StoreVT == MVT::v512i1) {
12268 if (Subtarget.isISAFuture()) {
12269 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12271 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
12274 Value2 =
SDValue(ExtNode, 1);
12279 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12280 unsigned VecNum = Subtarget.isLittleEndian() ? NumVecs - 1 - Idx : Idx;
12282 if (Subtarget.isISAFuture()) {
12283 VecNum = Subtarget.isLittleEndian() ? 1 - (Idx % 2) : (Idx % 2);
12284 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
12285 Idx > 1 ? Value2 :
Value,
12288 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
Value,
12292 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
12306 if (
Op.getValueType() == MVT::v4i32) {
12323 LHS,
RHS, DAG, dl, MVT::v4i32);
12326 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
12331 }
else if (
Op.getValueType() == MVT::v16i8) {
12333 bool isLittleEndian = Subtarget.isLittleEndian();
12337 LHS,
RHS, DAG, dl, MVT::v8i16);
12342 LHS,
RHS, DAG, dl, MVT::v8i16);
12350 for (
unsigned i = 0; i != 8; ++i) {
12351 if (isLittleEndian) {
12353 Ops[i*2+1] = 2*i+16;
12356 Ops[i*2+1] = 2*i+1+16;
12359 if (isLittleEndian)
12369 bool IsStrict =
Op->isStrictFPOpcode();
12370 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
12371 !Subtarget.hasP9Vector())
12381 "Should only be called for ISD::FP_EXTEND");
12385 if (
Op.getValueType() != MVT::v2f64 ||
12386 Op.getOperand(0).getValueType() != MVT::v2f32)
12398 "Node should have 2 operands with second one being a constant!");
12410 int DWord = Idx >> 1;
12413 if (Subtarget.isLittleEndian())
12416 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64,
12430 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12432 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12433 LD->getMemoryVT(),
LD->getMemOperand());
12438 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewOp,
12443 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12445 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12446 LD->getMemoryVT(),
LD->getMemOperand());
12447 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewLd,
12458 if (STI.useCRBits())
12475 PPCISD::ADDE,
DL, DAG.
getVTList(SumType, MVT::i32), Zero, Zero, Flag);
12476 if (STI.useCRBits())
12484 SDNode *
N =
Op.getNode();
12485 EVT VT =
N->getValueType(0);
12486 EVT CarryType =
N->getValueType(1);
12487 unsigned Opc =
N->getOpcode();
12489 Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12491 N->getOperand(0),
N->getOperand(1));
12503 SDNode *
N =
Op.getNode();
12504 unsigned Opc =
N->getOpcode();
12505 EVT VT =
N->getValueType(0);
12506 EVT CarryType =
N->getValueType(1);
12507 SDValue CarryOp =
N->getOperand(2);
12509 Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12515 Op.getOperand(0),
Op.getOperand(1), CarryOp);
12529 EVT VT =
Op.getNode()->getValueType(0);
12555 EVT VT =
Op.getNode()->getValueType(0);
12584 EVT OpVT =
A.getValueType();
12585 EVT ResVT =
Op.getValueType();
12591 SDVTList VTs = DAG.
getVTList(OpVT, MVT::i32);
12609 switch (
Op.getOpcode()) {
12629 return LowerSSUBO(
Op, DAG);
12631 return LowerSADDO(
Op, DAG);
12643 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
12664 return LowerSET_ROUNDING(
Op, DAG);
12671 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
12672 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
12684 return LowerFP_ROUND(
Op, DAG);
12698 return LowerINTRINSIC_VOID(
Op, DAG);
12700 return LowerBSWAP(
Op, DAG);
12702 return LowerATOMIC_CMP_SWAP(
Op, DAG);
12704 return LowerATOMIC_LOAD_STORE(
Op, DAG);
12706 return LowerIS_FPCLASS(
Op, DAG);
12709 return LowerADDSUBO(
Op, DAG);
12712 return LowerADDSUBO_CARRY(
Op, DAG);
12714 return LowerUCMP(
Op, DAG);
12720 if (
Op->getFlags().hasNoFPExcept())
12724 return LowerVP_LOAD(
Op, DAG);
12725 case ISD::VP_STORE:
12726 return LowerVP_STORE(
Op, DAG);
12734 switch (
N->getOpcode()) {
12736 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
12753 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
12756 assert(
N->getValueType(0) == MVT::i1 &&
12757 "Unexpected result type for CTR decrement intrinsic");
12759 N->getValueType(0));
12769 switch (
N->getConstantOperandVal(0)) {
12770 case Intrinsic::ppc_pack_longdouble:
12772 N->getOperand(2),
N->getOperand(1)));
12774 case Intrinsic::ppc_maxfe:
12775 case Intrinsic::ppc_minfe:
12776 case Intrinsic::ppc_fnmsub:
12777 case Intrinsic::ppc_convert_f128_to_ppcf128:
12784 if (!Subtarget.isSVR4ABI() || Subtarget.isPPC64())
12787 EVT VT =
N->getValueType(0);
12789 if (VT == MVT::i64) {
12802 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
12806 Results.push_back(LoweredValue);
12807 if (
N->isStrictFPOpcode())
12812 if (!
N->getValueType(0).isVector())
12845 return Builder.CreateIntrinsic(Id, {});
12851 unsigned SZ = ValueTy->getPrimitiveSizeInBits();
12853 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
12854 "Only 8/16/32/64-bit atomic loads supported");
12860 IntID = Intrinsic::ppc_lbarx;
12861 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12864 IntID = Intrinsic::ppc_lharx;
12865 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12868 IntID = Intrinsic::ppc_lwarx;
12871 IntID = Intrinsic::ppc_ldarx;
12875 Builder.CreateIntrinsic(IntID, Addr,
nullptr,
"larx");
12877 return Builder.CreateTruncOrBitCast(
Call, ValueTy);
12888 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
12889 "Only 8/16/32/64-bit atomic loads supported");
12895 IntID = Intrinsic::ppc_stbcx;
12896 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12899 IntID = Intrinsic::ppc_sthcx;
12900 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12903 IntID = Intrinsic::ppc_stwcx;
12906 IntID = Intrinsic::ppc_stdcx;
12910 if (SZ == 8 || SZ == 16)
12911 Val = Builder.CreateZExt(Val, Builder.getInt32Ty());
12913 Value *
Call = Builder.CreateIntrinsic(IntID, {Addr, Val},
12915 return Builder.CreateXor(
Call, Builder.getInt32(1));
12938 return Builder.CreateIntrinsic(Intrinsic::ppc_cfence, {Inst->
getType()},
12948 unsigned AtomicSize,
12949 unsigned BinOpcode,
12950 unsigned CmpOpcode,
12951 unsigned CmpPred)
const {
12955 auto LoadMnemonic = PPC::LDARX;
12956 auto StoreMnemonic = PPC::STDCX;
12957 switch (AtomicSize) {
12961 LoadMnemonic = PPC::LBARX;
12962 StoreMnemonic = PPC::STBCX;
12963 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12966 LoadMnemonic = PPC::LHARX;
12967 StoreMnemonic = PPC::STHCX;
12968 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12971 LoadMnemonic = PPC::LWARX;
12972 StoreMnemonic = PPC::STWCX;
12975 LoadMnemonic = PPC::LDARX;
12976 StoreMnemonic = PPC::STDCX;
12992 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12994 F->insert(It, loopMBB);
12996 F->insert(It, loop2MBB);
12997 F->insert(It, exitMBB);
13003 Register TmpReg = (!BinOpcode) ? incr :
13004 RegInfo.createVirtualRegister( AtomicSize == 8 ? &PPC::G8RCRegClass
13005 : &PPC::GPRCRegClass);
13030 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
13035 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13037 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
13038 Register ExtReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13039 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
13069 switch(
MI.getOpcode()) {
13073 return TII->isSignExtended(
MI.getOperand(1).getReg(),
13074 &
MI.getMF()->getRegInfo());
13098 case PPC::EXTSB8_32_64:
13099 case PPC::EXTSB8_rec:
13100 case PPC::EXTSB_rec:
13103 case PPC::EXTSH8_32_64:
13104 case PPC::EXTSH8_rec:
13105 case PPC::EXTSH_rec:
13107 case PPC::EXTSWSLI:
13108 case PPC::EXTSWSLI_32_64:
13109 case PPC::EXTSWSLI_32_64_rec:
13110 case PPC::EXTSWSLI_rec:
13111 case PPC::EXTSW_32:
13112 case PPC::EXTSW_32_64:
13113 case PPC::EXTSW_32_64_rec:
13114 case PPC::EXTSW_rec:
13117 case PPC::SRAWI_rec:
13118 case PPC::SRAW_rec:
13127 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
13137 bool IsSignExtended =
13140 if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
13141 Register ValueReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13142 BuildMI(*BB,
MI, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
13143 .
addReg(
MI.getOperand(3).getReg());
13144 MI.getOperand(3).setReg(ValueReg);
13148 if (Subtarget.hasPartwordAtomics())
13156 bool is64bit = Subtarget.isPPC64();
13157 bool isLittleEndian = Subtarget.isLittleEndian();
13158 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13169 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13171 F->insert(It, loopMBB);
13173 F->insert(It, loop2MBB);
13174 F->insert(It, exitMBB);
13180 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13183 Register PtrReg = RegInfo.createVirtualRegister(RC);
13184 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
13186 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
13187 Register Incr2Reg = RegInfo.createVirtualRegister(GPRC);
13188 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
13189 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
13190 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
13191 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
13192 Register Tmp3Reg = RegInfo.createVirtualRegister(GPRC);
13193 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
13194 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
13195 Register SrwDestReg = RegInfo.createVirtualRegister(GPRC);
13198 (!BinOpcode) ? Incr2Reg : RegInfo.createVirtualRegister(GPRC);
13225 if (ptrA != ZeroReg) {
13226 Ptr1Reg = RegInfo.createVirtualRegister(RC);
13227 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13235 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13236 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
13239 .
addImm(is8bit ? 28 : 27);
13240 if (!isLittleEndian)
13241 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13243 .
addImm(is8bit ? 24 : 16);
13245 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13250 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13260 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13264 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13269 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13273 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
13276 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13283 Register SReg = RegInfo.createVirtualRegister(GPRC);
13284 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13288 unsigned ValueReg = SReg;
13289 unsigned CmpReg = Incr2Reg;
13290 if (CmpOpcode == PPC::CMPW) {
13291 ValueReg = RegInfo.createVirtualRegister(GPRC);
13292 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
13295 Register ValueSReg = RegInfo.createVirtualRegister(GPRC);
13296 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
13298 ValueReg = ValueSReg;
13330 .
addImm(is8bit ? 24 : 16)
13351 Register DstReg =
MI.getOperand(0).getReg();
13353 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
13354 Register mainDstReg =
MRI.createVirtualRegister(RC);
13355 Register restoreDstReg =
MRI.createVirtualRegister(RC);
13358 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13359 "Invalid Pointer Size!");
13407 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
13408 Register BufReg =
MI.getOperand(1).getReg();
13410 if (Subtarget.is64BitELFABI()) {
13423 BaseReg = Subtarget.isPPC64() ? PPC::X1 : PPC::R1;
13425 BaseReg = Subtarget.isPPC64() ? PPC::BP8 : PPC::BP;
13428 TII->get(Subtarget.isPPC64() ? PPC::STD : PPC::STW))
13451 TII->get(Subtarget.isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
13454 if (Subtarget.isPPC64()) {
13472 TII->get(PPC::PHI), DstReg)
13476 MI.eraseFromParent();
13490 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13491 "Invalid Pointer Size!");
13494 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13497 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
13498 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
13512 Register BufReg =
MI.getOperand(0).getReg();
13517 if (PVT == MVT::i64) {
13529 if (PVT == MVT::i64) {
13541 if (PVT == MVT::i64) {
13553 if (PVT == MVT::i64) {
13565 if (PVT == MVT::i64 && Subtarget.isSVR4ABI()) {
13575 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
13578 MI.eraseFromParent();
13594 "Unexpected stack alignment");
13598 unsigned StackProbeSize =
13601 StackProbeSize &= ~(StackAlign - 1);
13602 return StackProbeSize ? StackProbeSize : StackAlign;
13614 const bool isPPC64 = Subtarget.isPPC64();
13646 MF->
insert(MBBIter, TestMBB);
13647 MF->
insert(MBBIter, BlockMBB);
13648 MF->
insert(MBBIter, TailMBB);
13653 Register DstReg =
MI.getOperand(0).getReg();
13654 Register NegSizeReg =
MI.getOperand(1).getReg();
13656 Register FinalStackPtr =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13657 Register FramePointer =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13658 Register ActualNegSizeReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13664 if (!
MRI.hasOneNonDBGUse(NegSizeReg))
13666 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
13672 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
13673 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
13675 .
addDef(ActualNegSizeReg)
13677 .
add(
MI.getOperand(2))
13678 .
add(
MI.getOperand(3));
13684 .
addReg(ActualNegSizeReg);
13687 int64_t NegProbeSize = -(int64_t)ProbeSize;
13689 Register ScratchReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13691 Register TempReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13693 .
addImm(NegProbeSize >> 16);
13697 .
addImm(NegProbeSize & 0xFFFF);
13704 Register Div =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13706 .
addReg(ActualNegSizeReg)
13708 Register Mul =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13712 Register NegMod =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13715 .
addReg(ActualNegSizeReg);
13724 Register CmpResult =
MRI.createVirtualRegister(&PPC::CRRCRegClass);
13725 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
13750 MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13752 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
13753 MaxCallFrameSizeReg)
13754 .
add(
MI.getOperand(2))
13755 .
add(
MI.getOperand(3));
13756 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
13758 .
addReg(MaxCallFrameSizeReg);
13764 MBB->addSuccessor(TestMBB);
13767 MI.eraseFromParent();
13769 ++NumDynamicAllocaProbed;
13774 switch (
MI.getOpcode()) {
13775 case PPC::SELECT_CC_I4:
13776 case PPC::SELECT_CC_I8:
13777 case PPC::SELECT_CC_F4:
13778 case PPC::SELECT_CC_F8:
13779 case PPC::SELECT_CC_F16:
13780 case PPC::SELECT_CC_VRRC:
13781 case PPC::SELECT_CC_VSFRC:
13782 case PPC::SELECT_CC_VSSRC:
13783 case PPC::SELECT_CC_VSRC:
13784 case PPC::SELECT_CC_SPE4:
13785 case PPC::SELECT_CC_SPE:
13793 switch (
MI.getOpcode()) {
13794 case PPC::SELECT_I4:
13795 case PPC::SELECT_I8:
13796 case PPC::SELECT_F4:
13797 case PPC::SELECT_F8:
13798 case PPC::SELECT_F16:
13799 case PPC::SELECT_SPE:
13800 case PPC::SELECT_SPE4:
13801 case PPC::SELECT_VRRC:
13802 case PPC::SELECT_VSFRC:
13803 case PPC::SELECT_VSSRC:
13804 case PPC::SELECT_VSRC:
13814 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
13815 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
13816 if (Subtarget.is64BitELFABI() &&
13817 MI.getOpcode() == TargetOpcode::PATCHPOINT &&
13818 !Subtarget.isUsingPCRelativeCalls()) {
13830 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
13831 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
13833 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
13834 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
13848 if (Subtarget.hasISEL() &&
13849 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13850 MI.getOpcode() == PPC::SELECT_CC_I8 ||
13851 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
13853 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13854 MI.getOpcode() == PPC::SELECT_CC_I8)
13855 Cond.push_back(
MI.getOperand(4));
13858 Cond.push_back(
MI.getOperand(1));
13861 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
13862 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
13878 F->insert(It, copy0MBB);
13879 F->insert(It, sinkMBB);
13888 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
13903 .
addReg(
MI.getOperand(1).getReg())
13906 unsigned SelectPred =
MI.getOperand(4).getImm();
13909 .
addReg(
MI.getOperand(1).getReg())
13926 .
addReg(
MI.getOperand(3).getReg())
13928 .
addReg(
MI.getOperand(2).getReg())
13930 }
else if (
MI.getOpcode() == PPC::ReadTB) {
13946 F->insert(It, readMBB);
13947 F->insert(It, sinkMBB);
13958 Register ReadAgainReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13966 Register CmpReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13968 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
13978 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
13980 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
13982 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
13984 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
13987 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
13989 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
13991 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
13993 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
13996 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
13998 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
14000 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
14002 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
14005 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
14007 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
14009 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
14011 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
14014 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
14016 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
14018 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
14020 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
14023 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
14025 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
14027 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
14029 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
14032 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
14034 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
14036 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
14038 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
14041 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
14043 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
14045 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
14047 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
14050 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
14052 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
14054 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
14056 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
14059 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
14061 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
14063 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
14065 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
14068 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
14070 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
14072 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
14074 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
14076 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
14077 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
14078 (Subtarget.hasPartwordAtomics() &&
14079 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
14080 (Subtarget.hasPartwordAtomics() &&
14081 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
14082 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
14084 auto LoadMnemonic = PPC::LDARX;
14085 auto StoreMnemonic = PPC::STDCX;
14086 switch (
MI.getOpcode()) {
14089 case PPC::ATOMIC_CMP_SWAP_I8:
14090 LoadMnemonic = PPC::LBARX;
14091 StoreMnemonic = PPC::STBCX;
14092 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14094 case PPC::ATOMIC_CMP_SWAP_I16:
14095 LoadMnemonic = PPC::LHARX;
14096 StoreMnemonic = PPC::STHCX;
14097 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14099 case PPC::ATOMIC_CMP_SWAP_I32:
14100 LoadMnemonic = PPC::LWARX;
14101 StoreMnemonic = PPC::STWCX;
14103 case PPC::ATOMIC_CMP_SWAP_I64:
14104 LoadMnemonic = PPC::LDARX;
14105 StoreMnemonic = PPC::STDCX;
14112 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14113 Register oldval =
MI.getOperand(3).getReg();
14114 Register newval =
MI.getOperand(4).getReg();
14120 F->insert(It, loop1MBB);
14121 F->insert(It, loop2MBB);
14122 F->insert(It, exitMBB);
14143 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
14169 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
14170 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
14174 bool is64bit = Subtarget.isPPC64();
14175 bool isLittleEndian = Subtarget.isLittleEndian();
14176 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
14181 Register oldval =
MI.getOperand(3).getReg();
14182 Register newval =
MI.getOperand(4).getReg();
14188 F->insert(It, loop1MBB);
14189 F->insert(It, loop2MBB);
14190 F->insert(It, exitMBB);
14197 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
14200 Register PtrReg = RegInfo.createVirtualRegister(RC);
14201 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
14203 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
14204 Register NewVal2Reg = RegInfo.createVirtualRegister(GPRC);
14205 Register NewVal3Reg = RegInfo.createVirtualRegister(GPRC);
14206 Register OldVal2Reg = RegInfo.createVirtualRegister(GPRC);
14207 Register OldVal3Reg = RegInfo.createVirtualRegister(GPRC);
14208 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
14209 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
14210 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
14211 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
14212 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
14213 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
14215 Register TmpReg = RegInfo.createVirtualRegister(GPRC);
14216 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
14217 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14248 if (ptrA != ZeroReg) {
14249 Ptr1Reg = RegInfo.createVirtualRegister(RC);
14250 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
14259 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
14260 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
14263 .
addImm(is8bit ? 28 : 27);
14264 if (!isLittleEndian)
14265 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
14267 .
addImm(is8bit ? 24 : 16);
14269 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
14274 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
14279 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
14282 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
14289 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
14293 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
14296 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
14299 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
14304 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
14321 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
14345 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
14355 Register MFFSReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14370 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
14378 }
else if (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14379 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT ||
14380 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14381 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
14382 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14383 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
14386 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14387 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
14390 Register Dest = RegInfo.createVirtualRegister(
14391 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
14395 .
addReg(
MI.getOperand(1).getReg())
14398 MI.getOperand(0).getReg())
14399 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
14400 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
14403 Register CRReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14406 MI.getOperand(0).getReg())
14408 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
14410 unsigned Imm =
MI.getOperand(1).getImm();
14413 MI.getOperand(0).getReg())
14415 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
14417 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14420 if (
MRI.use_empty(OldFPSCRReg))
14421 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14423 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14434 unsigned Mode =
MI.getOperand(1).getImm();
14435 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
14439 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
14442 }
else if (
MI.getOpcode() == PPC::SETRND) {
14450 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
14451 if (Subtarget.hasDirectMove()) {
14452 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
14456 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
14459 if (RC == &PPC::F8RCRegClass) {
14461 assert((RegInfo.getRegClass(DestReg) == &PPC::G8RCRegClass) &&
14462 "Unsupported RegClass.");
14464 StoreOp = PPC::STFD;
14468 assert((RegInfo.getRegClass(SrcReg) == &PPC::G8RCRegClass) &&
14469 (RegInfo.getRegClass(DestReg) == &PPC::F8RCRegClass) &&
14470 "Unsupported RegClass.");
14503 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14506 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14518 Register OldFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14520 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
14522 Register ImDefReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14523 Register ExtSrcReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14528 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
14529 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
14534 Register NewFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14535 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
14541 Register NewFPSCRReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14542 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
14551 }
else if (
MI.getOpcode() == PPC::SETFLM) {
14555 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14556 if (
MRI.use_empty(OldFPSCRReg))
14557 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14559 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14562 Register NewFPSCRReg =
MI.getOperand(1).getReg();
14568 }
else if (
MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
14569 MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
14571 }
else if (
MI.getOpcode() == PPC::SPLIT_QUADWORD) {
14578 .
addUse(Src, 0, PPC::sub_gp8_x1);
14581 .
addUse(Src, 0, PPC::sub_gp8_x0);
14582 }
else if (
MI.getOpcode() == PPC::LQX_PSEUDO ||
14583 MI.getOpcode() == PPC::STQX_PSEUDO) {
14589 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
14595 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
14596 :
TII->get(PPC::STQ))
14600 }
else if (
MI.getOpcode() == PPC::LWAT_PSEUDO ||
14601 MI.getOpcode() == PPC::LDAT_PSEUDO) {
14603 Register DstReg =
MI.getOperand(0).getReg();
14604 Register PtrReg =
MI.getOperand(1).getReg();
14605 Register ValReg =
MI.getOperand(2).getReg();
14606 unsigned FC =
MI.getOperand(3).getImm();
14607 bool IsLwat =
MI.getOpcode() == PPC::LWAT_PSEUDO;
14608 Register Val64 =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
14610 BuildMI(*BB,
MI,
DL,
TII->get(TargetOpcode::SUBREG_TO_REG), Val64)
14617 Register G8rPair =
MRI.createVirtualRegister(&PPC::G8pRCRegClass);
14618 Register UndefG8r =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
14619 BuildMI(*BB,
MI,
DL,
TII->get(TargetOpcode::IMPLICIT_DEF), UndefG8r);
14622 .
addImm(PPC::sub_gp8_x0)
14624 .
addImm(PPC::sub_gp8_x1);
14626 Register PairResult =
MRI.createVirtualRegister(&PPC::G8pRCRegClass);
14627 BuildMI(*BB,
MI,
DL,
TII->get(IsLwat ? PPC::LWAT : PPC::LDAT), PairResult)
14631 Register Result64 =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
14633 .
addReg(PairResult, 0, PPC::sub_gp8_x0);
14636 .
addReg(Result64, 0, PPC::sub_32);
14644 MI.eraseFromParent();
14657 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
14660 return RefinementSteps;
14666 EVT VT =
Op.getValueType();
14669 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
14693PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
14696 EVT VT =
Op.getValueType();
14697 if (VT != MVT::f64 &&
14698 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
14701 return DAG.
getNode(PPCISD::FSQRT, SDLoc(
Op), VT,
Op);
14705 int Enabled,
int &RefinementSteps,
14706 bool &UseOneConstNR,
14707 bool Reciprocal)
const {
14709 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
14710 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
14711 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14712 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14718 UseOneConstNR = !Subtarget.needsTwoConstNR();
14719 return DAG.
getNode(PPCISD::FRSQRTE, SDLoc(Operand), VT, Operand);
14726 int &RefinementSteps)
const {
14728 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
14729 (VT == MVT::f64 && Subtarget.hasFRE()) ||
14730 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14731 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14734 return DAG.
getNode(PPCISD::FRE, SDLoc(Operand), VT, Operand);
14750 switch (Subtarget.getCPUDirective()) {
14777 unsigned Bytes,
int Dist,
14791 if (FS != BFS || FS != (
int)Bytes)
return false;
14796 int64_t Offset1 = 0, Offset2 = 0;
14799 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
14809 if (isGA1 && isGA2 && GV1 == GV2)
14810 return Offset1 == (Offset2 + Dist*Bytes);
14817 unsigned Bytes,
int Dist,
14820 EVT VT = LS->getMemoryVT();
14827 switch (
N->getConstantOperandVal(1)) {
14828 default:
return false;
14829 case Intrinsic::ppc_altivec_lvx:
14830 case Intrinsic::ppc_altivec_lvxl:
14831 case Intrinsic::ppc_vsx_lxvw4x:
14832 case Intrinsic::ppc_vsx_lxvw4x_be:
14835 case Intrinsic::ppc_vsx_lxvd2x:
14836 case Intrinsic::ppc_vsx_lxvd2x_be:
14839 case Intrinsic::ppc_altivec_lvebx:
14842 case Intrinsic::ppc_altivec_lvehx:
14845 case Intrinsic::ppc_altivec_lvewx:
14855 switch (
N->getConstantOperandVal(1)) {
14856 default:
return false;
14857 case Intrinsic::ppc_altivec_stvx:
14858 case Intrinsic::ppc_altivec_stvxl:
14859 case Intrinsic::ppc_vsx_stxvw4x:
14862 case Intrinsic::ppc_vsx_stxvd2x:
14865 case Intrinsic::ppc_vsx_stxvw4x_be:
14868 case Intrinsic::ppc_vsx_stxvd2x_be:
14871 case Intrinsic::ppc_altivec_stvebx:
14874 case Intrinsic::ppc_altivec_stvehx:
14877 case Intrinsic::ppc_altivec_stvewx:
14894 SDValue Chain = LD->getChain();
14895 EVT VT = LD->getMemoryVT();
14904 while (!Queue.empty()) {
14905 SDNode *ChainNext = Queue.pop_back_val();
14906 if (!Visited.
insert(ChainNext).second)
14913 if (!Visited.
count(ChainLD->getChain().getNode()))
14914 Queue.push_back(ChainLD->getChain().getNode());
14916 for (
const SDUse &O : ChainNext->
ops())
14917 if (!Visited.
count(O.getNode()))
14918 Queue.push_back(O.getNode());
14920 LoadRoots.
insert(ChainNext);
14931 for (
SDNode *
I : LoadRoots) {
14932 Queue.push_back(
I);
14934 while (!Queue.empty()) {
14935 SDNode *LoadRoot = Queue.pop_back_val();
14936 if (!Visited.
insert(LoadRoot).second)
14948 Queue.push_back(U);
14981 auto Final = Shifted;
14992 DAGCombinerInfo &DCI)
const {
14995 SelectionDAG &DAG = DCI.DAG;
15000 if (!DCI.isAfterLegalizeDAG())
15005 for (
const SDNode *U :
N->users())
15010 auto OpSize =
N->getOperand(0).getValueSizeInBits();
15014 if (OpSize <
Size) {
15032 DAGCombinerInfo &DCI)
const {
15033 SelectionDAG &DAG = DCI.DAG;
15036 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
15047 N->getValueType(0) != MVT::i1)
15050 if (
N->getOperand(0).getValueType() != MVT::i32 &&
15051 N->getOperand(0).getValueType() != MVT::i64)
15061 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
15072 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
15095 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15096 N->getOperand(0).getOpcode() !=
ISD::OR &&
15097 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15107 N->getOperand(1).getOpcode() !=
ISD::AND &&
15108 N->getOperand(1).getOpcode() !=
ISD::OR &&
15109 N->getOperand(1).getOpcode() !=
ISD::XOR &&
15120 SmallPtrSet<SDNode *, 16> Visited;
15122 for (
unsigned i = 0; i < 2; ++i) {
15126 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
15138 while (!BinOps.
empty()) {
15146 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15180 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15184 for (
const SDNode *User : Inputs[i].
getNode()->
users()) {
15185 if (User !=
N && !Visited.
count(User))
15194 if (
User->getOperand(0) == Inputs[i])
15197 if (
User->getOperand(0) == Inputs[i] ||
15198 User->getOperand(1) == Inputs[i])
15204 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15205 for (
const SDNode *User : PromOps[i].
getNode()->
users()) {
15206 if (User !=
N && !Visited.
count(User))
15215 if (
User->getOperand(0) == PromOps[i])
15218 if (
User->getOperand(0) == PromOps[i] ||
15219 User->getOperand(1) == PromOps[i])
15226 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15235 std::list<HandleSDNode> PromOpHandles;
15236 for (
auto &PromOp : PromOps)
15237 PromOpHandles.emplace_back(PromOp);
15244 while (!PromOpHandles.empty()) {
15245 SDValue PromOp = PromOpHandles.back().getValue();
15246 PromOpHandles.pop_back();
15255 PromOpHandles.emplace_front(PromOp);
15269 default:
C = 0;
break;
15282 PromOpHandles.emplace_front(PromOp);
15289 for (
unsigned i = 0; i < 2; ++i)
15299 return N->getOperand(0);
15307 DAGCombinerInfo &DCI)
const {
15308 SelectionDAG &DAG = DCI.DAG;
15325 if (
N->getValueType(0) != MVT::i32 &&
15326 N->getValueType(0) != MVT::i64)
15329 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
15330 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.isPPC64())))
15333 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15334 N->getOperand(0).getOpcode() !=
ISD::OR &&
15335 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15342 SmallPtrSet<SDNode *, 16> Visited;
15346 while (!BinOps.
empty()) {
15354 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15380 DenseMap<SDNode *, EVT> SelectTruncOp[2];
15385 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15390 if (User !=
N && !Visited.
count(User))
15396 if (
User->getOperand(0) == Inputs[i])
15397 SelectTruncOp[0].
insert(std::make_pair(User,
15398 User->getOperand(0).getValueType()));
15400 if (
User->getOperand(0) == Inputs[i])
15401 SelectTruncOp[0].
insert(std::make_pair(User,
15402 User->getOperand(0).getValueType()));
15403 if (
User->getOperand(1) == Inputs[i])
15404 SelectTruncOp[1].
insert(std::make_pair(User,
15405 User->getOperand(1).getValueType()));
15410 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15412 if (User !=
N && !Visited.
count(User))
15418 if (
User->getOperand(0) == PromOps[i])
15419 SelectTruncOp[0].
insert(std::make_pair(User,
15420 User->getOperand(0).getValueType()));
15422 if (
User->getOperand(0) == PromOps[i])
15423 SelectTruncOp[0].
insert(std::make_pair(User,
15424 User->getOperand(0).getValueType()));
15425 if (
User->getOperand(1) == PromOps[i])
15426 SelectTruncOp[1].
insert(std::make_pair(User,
15427 User->getOperand(1).getValueType()));
15432 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
15433 bool ReallyNeedsExt =
false;
15437 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15442 Inputs[i].getOperand(0).getValueSizeInBits();
15443 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
15448 OpBits-PromBits))) ||
15451 (OpBits-(PromBits-1)))) {
15452 ReallyNeedsExt =
true;
15460 std::list<HandleSDNode> PromOpHandles;
15461 for (
auto &PromOp : PromOps)
15462 PromOpHandles.emplace_back(PromOp);
15466 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15473 SDValue InSrc = Inputs[i].getOperand(0);
15491 while (!PromOpHandles.empty()) {
15493 PromOpHandles.pop_back();
15497 default:
C = 0;
break;
15510 PromOpHandles.emplace_front(PromOp);
15520 (SelectTruncOp[1].count(PromOp.
getNode()) &&
15522 PromOpHandles.emplace_front(PromOp);
15530 for (
unsigned i = 0; i < 2; ++i) {
15548 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
15549 if (SI0 != SelectTruncOp[0].
end())
15551 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
15552 if (SI1 != SelectTruncOp[1].
end())
15561 if (!ReallyNeedsExt)
15562 return N->getOperand(0);
15569 N->getValueSizeInBits(0), PromBits),
15570 dl,
N->getValueType(0)));
15573 "Invalid extension type");
15576 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
15586 auto isValidForConvert = [](
SDValue &Operand) {
15605 if (LoadNode->isVolatile())
15626 return (isValidForConvert(
LHS) && isValidForConvert(
RHS));
15636 "CC mus be ISD::SETNE or ISD::SETEQ");
15638 auto getV16i8Load = [&](
const SDValue &Operand) {
15645 return DAG.
getLoad(MVT::v16i8,
DL, LoadNode->getChain(),
15646 LoadNode->getBasePtr(), LoadNode->getMemOperand());
15685 SDValue LHSVec = getV16i8Load(
N->getOperand(0));
15686 SDValue RHSVec = getV16i8Load(
N->getOperand(1));
15689 DAG.
getConstant(Intrinsic::ppc_altivec_vcmpequb_p,
DL, MVT::i32);
15692 IntrID, CRSel, LHSVec, RHSVec);
15695 return DAG.
getSetCC(
DL,
N->getValueType(0), PredResult,
15713 auto IsAndWithOne = [](
SDValue &V) {
15724 auto IsCompareWithZero = [](
SDValue &V) {
15731 return (IsAndWithOne(
LHS) && IsCompareWithZero(
RHS)) ||
15732 (IsAndWithOne(
RHS) && IsCompareWithZero(
LHS));
15749 auto MakeXor1 = [&](
SDValue V) {
15750 EVT VT = V.getValueType();
15757 return MakeXor1(
LHS);
15760 return MakeXor1(
RHS);
15766 DAGCombinerInfo &DCI)
const {
15768 "Should be called with a SETCC node");
15790 SelectionDAG &DAG = DCI.DAG;
15791 EVT VT =
N->getValueType(0);
15792 EVT OpVT =
LHS.getValueType();
15814 return DAGCombineTruncBoolExt(
N, DCI);
15821 Op.getValueType() == MVT::f64;
15833combineElementTruncationToVectorTruncation(
SDNode *
N,
15834 DAGCombinerInfo &DCI)
const {
15836 "Should be called with a BUILD_VECTOR node");
15838 SelectionDAG &DAG = DCI.DAG;
15841 SDValue FirstInput =
N->getOperand(0);
15843 "The input operand must be an fp-to-int conversion.");
15848 if (FirstConversion == PPCISD::FCTIDZ ||
15849 FirstConversion == PPCISD::FCTIDUZ ||
15850 FirstConversion == PPCISD::FCTIWZ ||
15851 FirstConversion == PPCISD::FCTIWUZ) {
15852 bool IsSplat =
true;
15853 bool Is32Bit = FirstConversion == PPCISD::FCTIWZ ||
15854 FirstConversion == PPCISD::FCTIWUZ;
15857 EVT TargetVT =
N->getValueType(0);
15858 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
15859 SDValue NextOp =
N->getOperand(i);
15860 if (NextOp.
getOpcode() != PPCISD::MFVSR)
15863 if (NextConversion != FirstConversion)
15871 if (
N->getOperand(i) != FirstInput)
15882 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
15883 SDValue In =
N->getOperand(i).getOperand(0);
15893 Ops.push_back(Trunc);
15896 Ops.push_back(
In.isUndef() ? DAG.
getUNDEF(SrcVT) :
In.getOperand(0));
15900 if (FirstConversion == PPCISD::FCTIDZ ||
15901 FirstConversion == PPCISD::FCTIWZ)
15906 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
15908 return DAG.
getNode(Opcode, dl, TargetVT, BV);
15926 static const APInt BasePattern =
APInt(128, 0x8000000000000000ULL) << 64;
15930 if (FullVal == BasePattern)
15931 return std::make_tuple(Uim,
uint8_t{0});
15934 if (FullVal ==
APInt(128, 1))
15935 return std::make_tuple(Uim,
uint8_t{127});
15937 return std::nullopt;
15957 "Expected a BuildVectorSDNode in combineBVLoadsSpecialValue");
15961 EVT VT =
Op.getValueType();
15962 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
15976 for (
const SDValue &Operand :
Op.getNode()->op_values()) {
15986 for (
unsigned Index = 0;
Index < NumElems; ++
Index) {
15990 uint64_t ElemValue =
C->getZExtValue();
15994 ElemValue &= ((1ULL << ElemBits) - 1);
15998 (IsLittleEndian) ? (Index * ElemBits) : (128 - (
Index + 1) * ElemBits);
16001 APInt ElemAPInt(128, ElemValue);
16002 ElemAPInt <<= BitPos;
16005 FullVal |= ElemAPInt;
16012 const auto &[Uim, ShiftAmount] = *UIMOpt;
16016 if (ShiftAmount == 0) {
16021 <<
"combineBVLoadsSpecialValue: Instruction Emitted ";
16022 LxvkqInstr.
dump());
16026 assert(ShiftAmount == 127 &&
"Unexpected lxvkq shift amount value");
16038 DAG.
getMachineNode(PPC::VSRQ, Dl, VT, ShiftAmountVec, ShiftAmountVec),
16041 <<
"\n combineBVLoadsSpecialValue: Instruction Emitted ";
16057 "Should be called with a BUILD_VECTOR node");
16062 if (!
N->getValueType(0).getVectorElementType().isByteSized())
16065 bool InputsAreConsecutiveLoads =
true;
16066 bool InputsAreReverseConsecutive =
true;
16067 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
16068 SDValue FirstInput =
N->getOperand(0);
16069 bool IsRoundOfExtLoad =
false;
16079 N->getNumOperands() == 1)
16082 if (!IsRoundOfExtLoad)
16087 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
16089 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
16092 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
16098 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
16109 InputsAreConsecutiveLoads =
false;
16111 InputsAreReverseConsecutive =
false;
16114 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
16119 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
16120 "The loads cannot be both consecutive and reverse consecutive.");
16124 if (InputsAreConsecutiveLoads) {
16125 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
16129 ReturnSDVal = WideLoad;
16130 }
else if (InputsAreReverseConsecutive) {
16132 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
16137 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
16145 for (
auto *LD : InputLoads)
16147 return ReturnSDVal;
16158 unsigned NumElems =
Input.getValueType().getVectorNumElements();
16164 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16166 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
16168 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
16169 CorrectElems = CorrectElems >> 8;
16170 Elems = Elems >> 8;
16177 EVT VT =
N->getValueType(0);
16181 Input.getValueType().getVectorElementType(),
16215 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
16241 Elems = Elems << 8;
16250 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16251 if (!isSExtOfVecExtract(
N->getOperand(i))) {
16258 int TgtElemArrayIdx;
16259 int InputSize =
Input.getValueType().getScalarSizeInBits();
16260 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
16261 if (InputSize + OutputSize == 40)
16262 TgtElemArrayIdx = 0;
16263 else if (InputSize + OutputSize == 72)
16264 TgtElemArrayIdx = 1;
16265 else if (InputSize + OutputSize == 48)
16266 TgtElemArrayIdx = 2;
16267 else if (InputSize + OutputSize == 80)
16268 TgtElemArrayIdx = 3;
16269 else if (InputSize + OutputSize == 96)
16270 TgtElemArrayIdx = 4;
16274 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
16276 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
16277 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
16278 if (Elems != CorrectElems) {
16294 if (
N->getValueType(0) != MVT::v1i128)
16297 SDValue Operand =
N->getOperand(0);
16304 EVT MemoryType = LD->getMemoryVT();
16308 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
16309 MemoryType == MVT::i32 || MemoryType == MVT::i64;
16312 if (!ValidLDType ||
16318 LD->getChain(), LD->getBasePtr(),
16322 DAG.
getVTList(MVT::v1i128, MVT::Other),
16323 LoadOps, MemoryType, LD->getMemOperand());
16327 DAGCombinerInfo &DCI)
const {
16329 "Should be called with a BUILD_VECTOR node");
16331 SelectionDAG &DAG = DCI.DAG;
16334 if (!Subtarget.hasVSX())
16341 if (FirstInput.
getOpcode() == PPCISD::MFVSR) {
16342 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
16357 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
16366 if (Subtarget.isISA3_1()) {
16372 if (
N->getValueType(0) != MVT::v2f64)
16383 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
16394 if (!Ext1Op || !Ext2Op)
16403 if (FirstElem == 0 && SecondElem == 1)
16404 SubvecIdx = Subtarget.isLittleEndian() ? 1 : 0;
16405 else if (FirstElem == 2 && SecondElem == 3)
16406 SubvecIdx = Subtarget.isLittleEndian() ? 0 : 1;
16412 PPCISD::SINT_VEC_TO_FP : PPCISD::UINT_VEC_TO_FP;
16413 return DAG.
getNode(NodeType, dl, MVT::v2f64,
16418 DAGCombinerInfo &DCI)
const {
16421 "Need an int -> FP conversion node here");
16426 SelectionDAG &DAG = DCI.DAG;
16432 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
16434 if (!
Op.getOperand(0).getValueType().isSimple())
16436 if (
Op.getOperand(0).getValueType().getSimpleVT() <= MVT(MVT::i1) ||
16437 Op.getOperand(0).getValueType().getSimpleVT() > MVT(MVT::i64))
16440 SDValue FirstOperand(
Op.getOperand(0));
16441 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
16442 (FirstOperand.getValueType() == MVT::i8 ||
16443 FirstOperand.getValueType() == MVT::i16);
16444 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
16446 bool DstDouble =
Op.getValueType() == MVT::f64;
16447 unsigned ConvOp =
Signed ?
16448 (DstDouble ? PPCISD::FCFID : PPCISD::FCFIDS) :
16449 (DstDouble ? PPCISD::FCFIDU : PPCISD::FCFIDUS);
16454 SDValue Ops[] = { LDN->getChain(), LDN->getBasePtr(), WidthConst };
16457 Ops, MVT::i8, LDN->getMemOperand());
16462 SDValue ExtOps[] = { Ld, WidthConst };
16464 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
16466 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
16474 if (
Op.getOperand(0).getValueType() == MVT::i32)
16478 "UINT_TO_FP is supported only with FPCVT");
16482 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16487 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16494 Subtarget.hasFPCVT()) ||
16496 SDValue Src =
Op.getOperand(0).getOperand(0);
16497 if (Src.getValueType() == MVT::f32) {
16499 DCI.AddToWorklist(Src.getNode());
16500 }
else if (Src.getValueType() != MVT::f64) {
16512 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
16515 DCI.AddToWorklist(
FP.getNode());
16539 switch (
N->getOpcode()) {
16544 Chain = LD->getChain();
16545 Base = LD->getBasePtr();
16546 MMO = LD->getMemOperand();
16565 MVT VecTy =
N->getValueType(0).getSimpleVT();
16573 Chain = Load.getValue(1);
16575 PPCISD::XXSWAPD, dl, DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Load);
16579 if (VecTy != MVT::v2f64) {
16606 switch (
N->getOpcode()) {
16611 Chain = ST->getChain();
16612 Base = ST->getBasePtr();
16613 MMO = ST->getMemOperand();
16633 SDValue Src =
N->getOperand(SrcOpnd);
16634 MVT VecTy = Src.getValueType().getSimpleVT();
16637 if (VecTy != MVT::v2f64) {
16643 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
16649 StoreOps, VecTy, MMO);
16656 DAGCombinerInfo &DCI)
const {
16659 unsigned Opcode =
N->getOperand(1).getOpcode();
16661 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
16665 &&
"Not a FP_TO_INT Instruction!");
16667 SDValue Val =
N->getOperand(1).getOperand(Strict ? 1 : 0);
16668 EVT Op1VT =
N->getOperand(1).getValueType();
16671 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
16675 bool ValidTypeForStoreFltAsInt =
16676 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.isPPC64()) ||
16677 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
16680 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
16683 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
16691 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
16706 bool PrevElemFromFirstVec = Mask[0] < NumElts;
16707 for (
int i = 1, e = Mask.size(); i < e; i++) {
16708 if (PrevElemFromFirstVec && Mask[i] < NumElts)
16710 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
16712 PrevElemFromFirstVec = !PrevElemFromFirstVec;
16723 for (
int i = 0, e =
Op.getNumOperands(); i < e; i++) {
16724 FirstOp =
Op.getOperand(i);
16730 for (
int i = 1, e =
Op.getNumOperands(); i < e; i++)
16731 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
16741 Op =
Op.getOperand(0);
16757 int RHSFirstElt,
int RHSLastElt,
int HalfVec,
unsigned LHSNumValidElts,
16758 unsigned RHSNumValidElts,
const PPCSubtarget &Subtarget) {
16760 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - LHSNumValidElts;
16762 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - RHSNumValidElts;
16763 for (
int I = 0,
E = ShuffV.
size();
I <
E; ++
I) {
16764 int Idx = ShuffV[
I];
16765 if (Idx >= LHSFirstElt && Idx <= LHSLastElt)
16766 ShuffV[
I] += LHSEltFixup;
16767 else if (Idx >= RHSFirstElt && Idx <= RHSLastElt)
16768 ShuffV[
I] += RHSEltFixup;
16779 SDLoc dl(OrigSToV);
16782 "Expecting a SCALAR_TO_VECTOR here");
16795 "Cannot produce a permuted scalar_to_vector for one element vector");
16797 unsigned ResultInElt = NumElts / 2;
16803 return DAG.
getNode(PPCISD::SCALAR_TO_VECTOR_PERMUTED, dl, VT,
16808 int HalfVec,
int LHSLastElementDefined,
16809 int RHSLastElementDefined) {
16810 for (
int Index : ShuffV) {
16814 if ((LHSLastElementDefined >= 0) && (Index < HalfVec) &&
16815 (Index > LHSLastElementDefined))
16818 if ((RHSLastElementDefined >= 0) &&
16819 (Index > HalfVec + RHSLastElementDefined))
16826 int ScalarSize,
uint64_t ShuffleEltWidth,
unsigned &NumValidElts,
16827 int FirstElt,
int &LastElt,
SDValue VecShuffOperand,
SDValue SToVNode,
16843 LastElt = (
uint64_t)ScalarSize > ShuffleEltWidth
16844 ? ScalarSize / ShuffleEltWidth - 1 + FirstElt
16847 if (SToVPermuted.
getValueType() != VecShuffOperandType)
16848 SToVPermuted = DAG.
getBitcast(VecShuffOperandType, SToVPermuted);
16849 return SToVPermuted;
16869 int NumElts =
LHS.getValueType().getVectorNumElements();
16872 bool IsLittleEndian = Subtarget.isLittleEndian();
16879 if (!Subtarget.hasDirectMove())
16899 SmallVector<int, 16> ShuffV(Mask);
16902 if (SToVLHS || SToVRHS) {
16905 int ShuffleNumElts = ShuffV.
size();
16906 int HalfVec = ShuffleNumElts / 2;
16912 unsigned LHSNumValidElts = HalfVec;
16913 unsigned RHSNumValidElts = HalfVec;
16918 int LHSFirstElt = 0;
16919 int RHSFirstElt = ShuffleNumElts;
16920 int LHSLastElt = -1;
16921 int RHSLastElt = -1;
16929 int LHSScalarSize = 0;
16930 int RHSScalarSize = 0;
16933 if (!IsLittleEndian && LHSScalarSize >= 64)
16938 if (!IsLittleEndian && RHSScalarSize >= 64)
16941 if (LHSScalarSize != 0)
16943 LHSScalarSize, ShuffleEltWidth, LHSNumValidElts, LHSFirstElt,
16944 LHSLastElt,
LHS, SToVLHS, DAG, Subtarget);
16945 if (RHSScalarSize != 0)
16947 RHSScalarSize, ShuffleEltWidth, RHSNumValidElts, RHSFirstElt,
16948 RHSLastElt,
RHS, SToVRHS, DAG, Subtarget);
16959 ShuffV, LHSFirstElt, LHSLastElt, RHSFirstElt, RHSLastElt, HalfVec,
16960 LHSNumValidElts, RHSNumValidElts, Subtarget);
16986 if (IsLittleEndian) {
16989 if (Mask[0] < NumElts)
16990 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
16994 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
16999 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17003 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
17008 if (Mask[0] < NumElts)
17009 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17013 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
17018 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17022 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
17032 if (IsLittleEndian)
17041 DAGCombinerInfo &DCI)
const {
17043 "Not a reverse memop pattern!");
17045 auto IsElementReverse = [](
const ShuffleVectorSDNode *SVN) ->
bool {
17048 auto I =
Mask.rbegin();
17049 auto E =
Mask.rend();
17051 for (;
I !=
E; ++
I) {
17059 SelectionDAG &DAG = DCI.DAG;
17062 if (!
isTypeLegal(VT) || !Subtarget.isLittleEndian() || !Subtarget.hasVSX())
17068 if (!Subtarget.hasP9Vector())
17071 if(!IsElementReverse(SVN))
17078 for (SDUse &Use : LSBase->
uses())
17079 if (
Use.getResNo() == 0 &&
17086 PPCISD::LOAD_VEC_BE, dl, DAG.
getVTList(VT, MVT::Other), LoadOps,
17101 PPCISD::STORE_VEC_BE, dl, DAG.
getVTList(MVT::Other), StoreOps,
17110 if (IntrinsicID == Intrinsic::ppc_stdcx)
17112 else if (IntrinsicID == Intrinsic::ppc_stwcx)
17114 else if (IntrinsicID == Intrinsic::ppc_sthcx)
17116 else if (IntrinsicID == Intrinsic::ppc_stbcx)
17125 if (
N->getOpcode() == PPCISD::ADDC &&
N->hasAnyUseOfValue(1)) {
17129 if (
LHS->getOpcode() == PPCISD::ADDE &&
17142 switch (
N->getOpcode()) {
17145 return combineADD(
N, DCI);
17171 return combineSHL(
N, DCI);
17173 return combineSRA(
N, DCI);
17175 return combineSRL(
N, DCI);
17177 return combineMUL(
N, DCI);
17179 case PPCISD::FNMSUB:
17180 return combineFMALike(
N, DCI);
17183 return N->getOperand(0);
17187 return N->getOperand(0);
17193 return N->getOperand(0);
17199 return DAGCombineExtBoolTrunc(
N, DCI);
17201 return combineTRUNCATE(
N, DCI);
17203 if (
SDValue CSCC = combineSetCC(
N, DCI))
17207 return DAGCombineTruncBoolExt(
N, DCI);
17210 return combineFPToIntToFP(
N, DCI);
17219 EVT Op1VT =
N->getOperand(1).getValueType();
17220 unsigned Opcode =
N->getOperand(1).getOpcode();
17224 SDValue Val = combineStoreFPToInt(
N, DCI);
17238 N->getOperand(1).getNode()->hasOneUse() &&
17239 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
17240 (Subtarget.hasLDBRX() && Subtarget.isPPC64() && Op1VT == MVT::i64))) {
17248 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
17255 if (Op1VT.
bitsGT(mVT)) {
17260 if (Op1VT == MVT::i64)
17265 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
17285 ST->getBasePtr(), ST->getOffset(), MemVT,
17286 ST->getMemOperand(), ST->getAddressingMode(),
17290 return ST->isUnindexed()
17299 if (Subtarget.needsSwapsForVSXMemOps() &&
17300 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
17301 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
17308 EVT VT = LD->getValueType(0);
17314 if (Subtarget.needsSwapsForVSXMemOps() &&
17315 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
17316 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
17327 auto ReplaceTwoFloatLoad = [&]() {
17328 if (VT != MVT::i64)
17343 if (!LD->hasNUsesOfValue(2, 0))
17346 auto UI = LD->user_begin();
17347 while (UI.getUse().getResNo() != 0) ++UI;
17349 while (UI.getUse().getResNo() != 0) ++UI;
17350 SDNode *RightShift = *UI;
17358 if (RightShift->getOpcode() !=
ISD::SRL ||
17360 RightShift->getConstantOperandVal(1) != 32 ||
17361 !RightShift->hasOneUse())
17364 SDNode *Trunc2 = *RightShift->user_begin();
17374 Bitcast->getValueType(0) != MVT::f32)
17380 if (Subtarget.isLittleEndian())
17386 SDValue BasePtr = LD->getBasePtr();
17387 if (LD->isIndexed()) {
17389 "Non-pre-inc AM on PPC?");
17397 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
17398 LD->getPointerInfo(), LD->getAlign(),
17399 MMOFlags, LD->getAAInfo());
17405 LD->getPointerInfo().getWithOffset(4),
17408 if (LD->isIndexed()) {
17422 if (ReplaceTwoFloatLoad())
17425 EVT MemVT = LD->getMemoryVT();
17428 if (LD->isUnindexed() && VT.
isVector() &&
17431 !Subtarget.hasP8Vector() &&
17432 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
17433 VT == MVT::v4f32))) &&
17434 LD->getAlign() < ABIAlignment) {
17436 SDValue Chain = LD->getChain();
17437 SDValue Ptr = LD->getBasePtr();
17438 bool isLittleEndian = Subtarget.isLittleEndian();
17465 MVT PermCntlTy, PermTy, LDTy;
17466 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
17467 : Intrinsic::ppc_altivec_lvsl;
17468 IntrLD = Intrinsic::ppc_altivec_lvx;
17469 IntrPerm = Intrinsic::ppc_altivec_vperm;
17470 PermCntlTy = MVT::v16i8;
17471 PermTy = MVT::v4i32;
17490 SDValue BaseLoadOps[] = { Chain, LDXIntID, Ptr };
17494 BaseLoadOps, LDTy, BaseMMO);
17503 int IncValue = IncOffset;
17520 SDValue ExtraLoadOps[] = { Chain, LDXIntID, Ptr };
17524 ExtraLoadOps, LDTy, ExtraMMO);
17535 if (isLittleEndian)
17537 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
17540 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
17543 Perm = Subtarget.hasAltivec()
17558 bool isLittleEndian = Subtarget.isLittleEndian();
17559 unsigned IID =
N->getConstantOperandVal(0);
17560 Intrinsic::ID Intr = (isLittleEndian ? Intrinsic::ppc_altivec_lvsr
17561 : Intrinsic::ppc_altivec_lvsl);
17562 if (IID == Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
17569 .zext(
Add.getScalarValueSizeInBits()))) {
17570 SDNode *BasePtr =
Add->getOperand(0).getNode();
17571 for (
SDNode *U : BasePtr->users()) {
17573 U->getConstantOperandVal(0) == IID) {
17584 SDNode *BasePtr =
Add->getOperand(0).getNode();
17585 for (
SDNode *U : BasePtr->users()) {
17588 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
17594 V->getConstantOperandVal(0) == IID) {
17606 (IID == Intrinsic::ppc_altivec_vmaxsw ||
17607 IID == Intrinsic::ppc_altivec_vmaxsh ||
17608 IID == Intrinsic::ppc_altivec_vmaxsb)) {
17639 switch (
N->getConstantOperandVal(1)) {
17642 case Intrinsic::ppc_altivec_vsum4sbs:
17643 case Intrinsic::ppc_altivec_vsum4shs:
17644 case Intrinsic::ppc_altivec_vsum4ubs: {
17651 APInt APSplatBits, APSplatUndef;
17652 unsigned SplatBitSize;
17655 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
17656 !Subtarget.isLittleEndian());
17658 if (BVNIsConstantSplat && APSplatBits == 0)
17663 case Intrinsic::ppc_vsx_lxvw4x:
17664 case Intrinsic::ppc_vsx_lxvd2x:
17667 if (Subtarget.needsSwapsForVSXMemOps())
17675 if (Subtarget.needsSwapsForVSXMemOps()) {
17676 switch (
N->getConstantOperandVal(1)) {
17679 case Intrinsic::ppc_vsx_stxvw4x:
17680 case Intrinsic::ppc_vsx_stxvd2x:
17689 bool Is64BitBswapOn64BitTgt =
17690 Subtarget.isPPC64() &&
N->getValueType(0) == MVT::i64;
17692 N->getOperand(0).hasOneUse();
17693 if (IsSingleUseNormalLd &&
17694 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
17695 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
17706 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
17707 MVT::i64 : MVT::i32, MVT::Other),
17708 Ops, LD->getMemoryVT(), LD->getMemOperand());
17712 if (
N->getValueType(0) == MVT::i16)
17729 !IsSingleUseNormalLd)
17734 if (!LD->isSimple())
17736 SDValue BasePtr = LD->getBasePtr();
17738 LD->getPointerInfo(), LD->getAlign());
17743 LD->getMemOperand(), 4, 4);
17747 if (Subtarget.isLittleEndian())
17753 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
17762 if (!
N->getOperand(0).hasOneUse() &&
17763 !
N->getOperand(1).hasOneUse() &&
17764 !
N->getOperand(2).hasOneUse()) {
17767 SDNode *VCMPrecNode =
nullptr;
17769 SDNode *LHSN =
N->getOperand(0).getNode();
17771 if (
User->getOpcode() == PPCISD::VCMP_rec &&
17775 VCMPrecNode =
User;
17787 SDNode *FlagUser =
nullptr;
17789 FlagUser ==
nullptr; ++UI) {
17790 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
17803 return SDValue(VCMPrecNode, 0);
17814 SDValue LHS =
N->getOperand(2), RHS =
N->getOperand(3);
17825 auto RHSAPInt = RHS->getAsAPIntVal();
17826 if (!RHSAPInt.isIntN(64))
17829 unsigned Val = RHSAPInt.getZExtValue();
17830 auto isImpossibleCompare = [&]() {
17833 if (Val != 0 && Val != 1) {
17835 return N->getOperand(0);
17838 N->getOperand(0),
N->getOperand(4));
17843 unsigned StoreWidth = 0;
17846 if (
SDValue Impossible = isImpossibleCompare())
17858 SDValue Ops[] = {LHS.getOperand(0), LHS.getOperand(2), LHS.getOperand(3),
17862 PPCISD::STORE_COND, dl,
17864 MemNode->getMemoryVT(), MemNode->getMemOperand());
17868 if (
N->getOperand(0) == LHS.getValue(1))
17879 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other, InChain,
17881 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
17887 assert(isDot &&
"Can't compare against a vector result!");
17889 if (
SDValue Impossible = isImpossibleCompare())
17892 bool BranchOnWhenPredTrue = (CC ==
ISD::SETEQ) ^ (Val == 0);
17899 EVT VTs[] = { LHS.getOperand(2).getValueType(), MVT::Glue };
17904 switch (LHS.getConstantOperandVal(1)) {
17920 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other,
N->getOperand(0),
17923 N->getOperand(4), CompNode.
getValue(1));
17928 return DAGCombineBuildVector(
N, DCI);
17941 EVT VT =
N->getValueType(0);
17942 if (VT == MVT::i64 && !Subtarget.isPPC64())
17944 if ((VT != MVT::i32 && VT != MVT::i64) ||
17952 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
17972 const APInt &DemandedElts,
17974 unsigned Depth)
const {
17976 switch (
Op.getOpcode()) {
17978 case PPCISD::LBRX: {
17981 Known.
Zero = 0xFFFF0000;
17984 case PPCISD::ADDE: {
17985 if (
Op.getResNo() == 0) {
17990 Known.
Zero = ~1ULL;
17995 switch (
Op.getConstantOperandVal(0)) {
17997 case Intrinsic::ppc_altivec_vcmpbfp_p:
17998 case Intrinsic::ppc_altivec_vcmpeqfp_p:
17999 case Intrinsic::ppc_altivec_vcmpequb_p:
18000 case Intrinsic::ppc_altivec_vcmpequh_p:
18001 case Intrinsic::ppc_altivec_vcmpequw_p:
18002 case Intrinsic::ppc_altivec_vcmpequd_p:
18003 case Intrinsic::ppc_altivec_vcmpequq_p:
18004 case Intrinsic::ppc_altivec_vcmpgefp_p:
18005 case Intrinsic::ppc_altivec_vcmpgtfp_p:
18006 case Intrinsic::ppc_altivec_vcmpgtsb_p:
18007 case Intrinsic::ppc_altivec_vcmpgtsh_p:
18008 case Intrinsic::ppc_altivec_vcmpgtsw_p:
18009 case Intrinsic::ppc_altivec_vcmpgtsd_p:
18010 case Intrinsic::ppc_altivec_vcmpgtsq_p:
18011 case Intrinsic::ppc_altivec_vcmpgtub_p:
18012 case Intrinsic::ppc_altivec_vcmpgtuh_p:
18013 case Intrinsic::ppc_altivec_vcmpgtuw_p:
18014 case Intrinsic::ppc_altivec_vcmpgtud_p:
18015 case Intrinsic::ppc_altivec_vcmpgtuq_p:
18022 switch (
Op.getConstantOperandVal(1)) {
18025 case Intrinsic::ppc_load2r:
18027 Known.
Zero = 0xFFFF0000;
18036 switch (Subtarget.getCPUDirective()) {
18058 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
18067 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
18069 LoopSize +=
TII->getInstSizeInBytes(J);
18074 if (LoopSize > 16 && LoopSize <= 32)
18088 if (Constraint.
size() == 1) {
18089 switch (Constraint[0]) {
18107 }
else if (Constraint ==
"wc") {
18109 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
18110 Constraint ==
"wf" || Constraint ==
"ws" ||
18111 Constraint ==
"wi" || Constraint ==
"ww") {
18124 Value *CallOperandVal =
info.CallOperandVal;
18127 if (!CallOperandVal)
18134 else if ((
StringRef(constraint) ==
"wa" ||
18146 switch (*constraint) {
18176std::pair<unsigned, const TargetRegisterClass *>
18180 if (Constraint.
size() == 1) {
18182 switch (Constraint[0]) {
18184 if (VT == MVT::i64 && Subtarget.isPPC64())
18185 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
18186 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
18188 if (VT == MVT::i64 && Subtarget.isPPC64())
18189 return std::make_pair(0U, &PPC::G8RCRegClass);
18190 return std::make_pair(0U, &PPC::GPRCRegClass);
18196 if (Subtarget.hasSPE()) {
18197 if (VT == MVT::f32 || VT == MVT::i32)
18198 return std::make_pair(0U, &PPC::GPRCRegClass);
18199 if (VT == MVT::f64 || VT == MVT::i64)
18200 return std::make_pair(0U, &PPC::SPERCRegClass);
18202 if (VT == MVT::f32 || VT == MVT::i32)
18203 return std::make_pair(0U, &PPC::F4RCRegClass);
18204 if (VT == MVT::f64 || VT == MVT::i64)
18205 return std::make_pair(0U, &PPC::F8RCRegClass);
18209 if (Subtarget.hasAltivec() && VT.
isVector())
18210 return std::make_pair(0U, &PPC::VRRCRegClass);
18211 else if (Subtarget.hasVSX())
18213 return std::make_pair(0U, &PPC::VFRCRegClass);
18216 return std::make_pair(0U, &PPC::CRRCRegClass);
18218 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
18220 return std::make_pair(0U, &PPC::CRBITRCRegClass);
18221 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
18222 Constraint ==
"wf" || Constraint ==
"wi") &&
18223 Subtarget.hasVSX()) {
18227 return std::make_pair(0U, &PPC::VSRCRegClass);
18228 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18229 return std::make_pair(0U, &PPC::VSSRCRegClass);
18230 return std::make_pair(0U, &PPC::VSFRCRegClass);
18231 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
18232 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18233 return std::make_pair(0U, &PPC::VSSRCRegClass);
18235 return std::make_pair(0U, &PPC::VSFRCRegClass);
18236 }
else if (Constraint ==
"lr") {
18237 if (VT == MVT::i64)
18238 return std::make_pair(0U, &PPC::LR8RCRegClass);
18240 return std::make_pair(0U, &PPC::LRRCRegClass);
18245 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
18249 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
18250 int VSNum = atoi(Constraint.
data() + 3);
18251 assert(VSNum >= 0 && VSNum <= 63 &&
18252 "Attempted to access a vsr out of range");
18254 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
18255 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
18260 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
18261 int RegNum = atoi(Constraint.
data() + 2);
18262 if (RegNum > 31 || RegNum < 0)
18264 if (VT == MVT::f32 || VT == MVT::i32)
18265 return Subtarget.hasSPE()
18266 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
18267 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
18268 if (VT == MVT::f64 || VT == MVT::i64)
18269 return Subtarget.hasSPE()
18270 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
18271 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
18275 std::pair<unsigned, const TargetRegisterClass *> R =
18284 if (R.first && VT == MVT::i64 && Subtarget.isPPC64() &&
18285 PPC::GPRCRegClass.contains(R.first))
18286 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
18287 PPC::sub_32, &PPC::G8RCRegClass),
18288 &PPC::G8RCRegClass);
18291 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
18292 R.first = PPC::CR0;
18293 R.second = &PPC::CRRCRegClass;
18297 if (Subtarget.isAIXABI() && !TM.getAIXExtendedAltivecABI()) {
18298 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
18299 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
18300 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
18301 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
18302 "default AIX AltiVec ABI and cannot be used\n";
18312 std::vector<SDValue> &
Ops,
18317 if (Constraint.
size() > 1)
18320 char Letter = Constraint[0];
18335 EVT TCVT = MVT::i64;
18376 if (Result.getNode()) {
18377 Ops.push_back(Result);
18388 if (
I.getNumOperands() <= 1)
18392 auto IntrinsicID =
Ops[1].getNode()->getAsZExtVal();
18393 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
18394 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
18397 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
18413 if (Ty->isVectorTy() && AM.
BaseOffs != 0 && !Subtarget.hasP9Vector())
18425 switch (AM.
Scale) {
18453 unsigned Depth =
Op.getConstantOperandVal(0);
18477 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
18485 unsigned Depth =
Op.getConstantOperandVal(0);
18492 bool isPPC64 = PtrVT == MVT::i64;
18498 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
18500 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
18506 FrameAddr, MachinePointerInfo());
18510#define GET_REGISTER_MATCHER
18511#include "PPCGenAsmMatcher.inc"
18515 bool IsPPC64 = Subtarget.isPPC64();
18527 if ((IsPPC64 && Reg == PPC::R2) || Reg == PPC::R0)
18533 Reg = Reg.id() - PPC::R0 + PPC::X0;
18540 if (Subtarget.is32BitELFABI())
18545 if (Subtarget.isAIXABI())
18559 return Subtarget.isGVIndirectSymbol(
G->getGlobal());
18575 case Intrinsic::ppc_atomicrmw_xchg_i128:
18576 case Intrinsic::ppc_atomicrmw_add_i128:
18577 case Intrinsic::ppc_atomicrmw_sub_i128:
18578 case Intrinsic::ppc_atomicrmw_nand_i128:
18579 case Intrinsic::ppc_atomicrmw_and_i128:
18580 case Intrinsic::ppc_atomicrmw_or_i128:
18581 case Intrinsic::ppc_atomicrmw_xor_i128:
18582 case Intrinsic::ppc_cmpxchg_i128:
18584 Info.memVT = MVT::i128;
18585 Info.ptrVal =
I.getArgOperand(0);
18587 Info.align =
Align(16);
18591 case Intrinsic::ppc_atomic_load_i128:
18593 Info.memVT = MVT::i128;
18594 Info.ptrVal =
I.getArgOperand(0);
18596 Info.align =
Align(16);
18599 case Intrinsic::ppc_atomic_store_i128:
18601 Info.memVT = MVT::i128;
18602 Info.ptrVal =
I.getArgOperand(2);
18604 Info.align =
Align(16);
18607 case Intrinsic::ppc_altivec_lvx:
18608 case Intrinsic::ppc_altivec_lvxl:
18609 case Intrinsic::ppc_altivec_lvebx:
18610 case Intrinsic::ppc_altivec_lvehx:
18611 case Intrinsic::ppc_altivec_lvewx:
18612 case Intrinsic::ppc_vsx_lxvd2x:
18613 case Intrinsic::ppc_vsx_lxvw4x:
18614 case Intrinsic::ppc_vsx_lxvd2x_be:
18615 case Intrinsic::ppc_vsx_lxvw4x_be:
18616 case Intrinsic::ppc_vsx_lxvl:
18617 case Intrinsic::ppc_vsx_lxvll: {
18620 case Intrinsic::ppc_altivec_lvebx:
18623 case Intrinsic::ppc_altivec_lvehx:
18626 case Intrinsic::ppc_altivec_lvewx:
18629 case Intrinsic::ppc_vsx_lxvd2x:
18630 case Intrinsic::ppc_vsx_lxvd2x_be:
18640 Info.ptrVal =
I.getArgOperand(0);
18643 Info.align =
Align(1);
18647 case Intrinsic::ppc_altivec_stvx:
18648 case Intrinsic::ppc_altivec_stvxl:
18649 case Intrinsic::ppc_altivec_stvebx:
18650 case Intrinsic::ppc_altivec_stvehx:
18651 case Intrinsic::ppc_altivec_stvewx:
18652 case Intrinsic::ppc_vsx_stxvd2x:
18653 case Intrinsic::ppc_vsx_stxvw4x:
18654 case Intrinsic::ppc_vsx_stxvd2x_be:
18655 case Intrinsic::ppc_vsx_stxvw4x_be:
18656 case Intrinsic::ppc_vsx_stxvl:
18657 case Intrinsic::ppc_vsx_stxvll: {
18660 case Intrinsic::ppc_altivec_stvebx:
18663 case Intrinsic::ppc_altivec_stvehx:
18666 case Intrinsic::ppc_altivec_stvewx:
18669 case Intrinsic::ppc_vsx_stxvd2x:
18670 case Intrinsic::ppc_vsx_stxvd2x_be:
18680 Info.ptrVal =
I.getArgOperand(1);
18683 Info.align =
Align(1);
18687 case Intrinsic::ppc_stdcx:
18688 case Intrinsic::ppc_stwcx:
18689 case Intrinsic::ppc_sthcx:
18690 case Intrinsic::ppc_stbcx: {
18692 auto Alignment =
Align(8);
18694 case Intrinsic::ppc_stdcx:
18697 case Intrinsic::ppc_stwcx:
18699 Alignment =
Align(4);
18701 case Intrinsic::ppc_sthcx:
18703 Alignment =
Align(2);
18705 case Intrinsic::ppc_stbcx:
18707 Alignment =
Align(1);
18712 Info.ptrVal =
I.getArgOperand(0);
18714 Info.align = Alignment;
18729 const AttributeList &FuncAttributes)
const {
18733 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
18734 if (
Op.isMemset() && Subtarget.hasVSX()) {
18739 if (TailSize > 2 && TailSize <= 4) {
18744 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
18749 if (Subtarget.isPPC64()) {
18760 assert(Ty->isIntegerTy());
18762 unsigned BitSize = Ty->getPrimitiveSizeInBits();
18763 return !(BitSize == 0 || BitSize > 64);
18771 return NumBits1 == 64 && NumBits2 == 32;
18779 return NumBits1 == 64 && NumBits2 == 32;
18786 EVT MemVT = LD->getMemoryVT();
18787 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
18788 (Subtarget.isPPC64() && MemVT == MVT::i32)) &&
18804 "invalid fpext types");
18806 if (DestVT == MVT::f128)
18821 unsigned *
Fast)
const {
18835 !Subtarget.allowsUnalignedFPAccess())
18839 if (Subtarget.hasVSX()) {
18840 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
18841 VT != MVT::v4f32 && VT != MVT::v4i32)
18848 if (VT == MVT::ppcf128)
18863 if (!ConstNode->getAPIntValue().isSignedIntN(64))
18871 int64_t Imm = ConstNode->getSExtValue();
18892 if (Subtarget.hasSPE() || Subtarget.useSoftFloat())
18894 switch (Ty->getScalarType()->getTypeID()) {
18899 return Subtarget.hasP9Vector();
18907 if (!
I->hasOneUse())
18911 assert(
User &&
"A single use instruction with no uses.");
18913 switch (
I->getOpcode()) {
18914 case Instruction::FMul: {
18916 if (
User->getOpcode() != Instruction::FSub &&
18917 User->getOpcode() != Instruction::FAdd)
18924 bool AllowContract =
I->getFastMathFlags().allowContract() &&
18925 User->getFastMathFlags().allowContract();
18931 case Instruction::Load: {
18944 if (
User->getOpcode() != Instruction::Store)
18964 static const MCPhysReg ScratchRegs[] = {
18965 PPC::X12, PPC::LR8, PPC::CTR8, 0
18968 return ScratchRegs;
18972 const Constant *PersonalityFn)
const {
18973 return Subtarget.isPPC64() ? PPC::X3 : PPC::R3;
18977 const Constant *PersonalityFn)
const {
18978 return Subtarget.isPPC64() ? PPC::X4 : PPC::R4;
18983 EVT VT ,
unsigned DefinedValues)
const {
18984 if (VT == MVT::v2i64)
18985 return Subtarget.hasDirectMove();
18987 if (Subtarget.hasVSX())
19014 return PPCISD::FNMSUB;
19015 case PPCISD::FNMSUB:
19021 bool LegalOps,
bool OptForSize,
19023 unsigned Depth)
const {
19027 unsigned Opc =
Op.getOpcode();
19028 EVT VT =
Op.getValueType();
19032 case PPCISD::FNMSUB:
19053 if (Flags.hasNoSignedZeros() ||
Options.NoSignedZerosFPMath) {
19057 N0Cost,
Depth + 1);
19061 N1Cost,
Depth + 1);
19063 if (NegN0 && N0Cost <= N1Cost) {
19064 Cost = std::min(N0Cost, N2Cost);
19066 }
else if (NegN1) {
19067 Cost = std::min(N1Cost, N2Cost);
19087 if (M.getStackProtectorGuard() ==
"tls" || Subtarget.isTargetLinux())
19093 bool ForCodeSize)
const {
19094 if (!VT.
isSimple() || !Subtarget.hasVSX())
19104 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
19109 APSInt IntResult(16,
false);
19114 if (IsExact && IntResult <= 15 && IntResult >= -16)
19116 return Imm.isZero();
19119 return Imm.isPosZero();
19131 unsigned Opcode =
N->getOpcode();
19151 if (Mask->getZExtValue() == OpSizeInBits - 1)
19158 DAGCombinerInfo &DCI)
const {
19159 EVT VT =
N->getValueType(0);
19162 unsigned Opc =
N->getOpcode();
19164 "Unexpected opcode.");
19171 if (EltTy != MVT::i64 && EltTy != MVT::i32)
19175 uint64_t SplatBits = 0;
19176 bool AddSplatCase =
false;
19180 AddSplatCase =
true;
19184 if (!AddSplatCase) {
19188 unsigned SplatBitSize;
19190 APInt APSplatBits, APSplatUndef;
19192 bool BVNIsConstantSplat =
19194 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
19195 if (!BVNIsConstantSplat || SplatBitSize != EltBits)
19206 if (SplatBits == (EltBits - 1)) {
19210 NewOpc = PPCISD::SHL;
19213 NewOpc = PPCISD::SRL;
19216 NewOpc = PPCISD::SRA;
19220 return DCI.DAG.getNode(NewOpc,
DL, VT, N0, SplatOnes);
19228 if (EltTy != MVT::i64 || SplatBits != 1)
19231 return DCI.DAG.getNode(
ISD::ADD, SDLoc(
N), VT, N0, N0);
19234SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19238 if (
N->getValueType(0).isVector())
19239 return combineVectorShift(
N, DCI);
19243 if (!Subtarget.isISA3_0() || !Subtarget.isPPC64() ||
19246 N->getValueType(0) != MVT::i64)
19261 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
19267SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19271 if (
N->getValueType(0).isVector())
19272 return combineVectorShift(
N, DCI);
19277SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19281 if (
N->getValueType(0).isVector())
19282 return combineVectorShift(
N, DCI);
19293 if (!Subtarget.isPPC64())
19299 auto isZextOfCompareWithConstant = [](
SDValue Op) {
19301 Op.getValueType() != MVT::i64)
19305 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
19306 Cmp.getOperand(0).getValueType() != MVT::i64)
19310 int64_t NegConstant = 0 -
Constant->getSExtValue();
19319 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
19320 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
19323 if (LHSHasPattern && !RHSHasPattern)
19325 else if (!LHSHasPattern && !RHSHasPattern)
19329 EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
19332 SDValue Z = Cmp.getOperand(0);
19334 int64_t NegConstant = 0 -
Constant->getSExtValue();
19347 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
19365 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
19395 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
19398 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
19406 if (!GSDN || !ConstNode)
19434 EVT VT =
N->getValueType(0);
19435 if (!Subtarget.hasVSX())
19439 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
19451 unsigned NumOfEles =
RHS.getNumOperands();
19452 for (
unsigned i = 0; i < NumOfEles; ++i) {
19454 if (!CN || CN->getSExtValue() != 1)
19469SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19491 DAGCombinerInfo &DCI)
const {
19493 if (Subtarget.useCRBits()) {
19495 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
19496 return CRTruncValue;
19503 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
19506 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
19516 EltToExtract = EltToExtract ? 0 : 1;
19526 return DCI.DAG.getNode(
19528 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
19533SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19534 SelectionDAG &DAG = DCI.DAG;
19537 if (!ConstOpOrElement)
19545 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne, EVT VT) ->
bool {
19546 switch (this->Subtarget.getCPUDirective()) {
19569 return IsAddOne && IsNeg ? VT.
isVector() :
true;
19573 EVT VT =
N->getValueType(0);
19578 APInt MulAmtAbs = MulAmt.
abs();
19580 if ((MulAmtAbs - 1).isPowerOf2()) {
19584 if (!IsProfitable(IsNeg,
true, VT))
19597 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
19601 if (!IsProfitable(IsNeg,
false, VT))
19622 DAGCombinerInfo &DCI)
const {
19626 SDNodeFlags
Flags =
N->getFlags();
19627 EVT VT =
N->getValueType(0);
19628 SelectionDAG &DAG = DCI.DAG;
19630 unsigned Opc =
N->getOpcode();
19632 bool LegalOps = !DCI.isBeforeLegalizeOps();
19640 if (!
Flags.hasNoSignedZeros() && !
Options.NoSignedZerosFPMath)
19656bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
19658 if (!Subtarget.is64BitELFABI())
19668 if (!TM.Options.GuaranteedTailCallOpt &&
DisableSCO)
19673 if (!Callee ||
Callee->isVarArg())
19686bool PPCTargetLowering::
19687isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
19692 if (CI->getBitWidth() > 64)
19694 int64_t ConstVal = CI->getZExtValue();
19696 (
isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
19705PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
19711 if ((Flags & FlagSet) == FlagSet)
19714 if ((Flags & FlagSet) == FlagSet)
19717 if ((Flags & FlagSet) == FlagSet)
19720 if ((Flags & FlagSet) == FlagSet)
19741 if ((FrameIndexAlign % 4) != 0)
19742 FlagSet &=
~PPC::MOF_RPlusSImm16Mult4;
19743 if ((FrameIndexAlign % 16) != 0)
19744 FlagSet &=
~PPC::MOF_RPlusSImm16Mult16;
19748 if ((FrameIndexAlign % 4) == 0)
19750 if ((FrameIndexAlign % 16) == 0)
19763 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
19764 if ((Imm & 0x3) == 0)
19766 if ((Imm & 0xf) == 0)
19772 const APInt &ConstImm = CN->getAPIntValue();
19791 const APInt &ConstImm = CN->getAPIntValue();
19801 }
else if (
RHS.getOpcode() == PPCISD::Lo && !
RHS.getConstantOperandVal(1))
19812 return (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR ||
19821unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
19826 if (!Subtarget.hasP9Vector())
19831 if (Subtarget.hasPrefixInstrs())
19834 if (Subtarget.hasSPE())
19843 unsigned ParentOp = Parent->
getOpcode();
19847 if ((
ID == Intrinsic::ppc_vsx_lxvp) || (
ID == Intrinsic::ppc_vsx_stxvp)) {
19848 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
19860 if (LSB->isIndexed())
19866 assert(MN &&
"Parent should be a MemSDNode!");
19871 "Not expecting scalar integers larger than 16 bytes!");
19874 else if (
Size == 32)
19881 else if (
Size == 256) {
19882 assert(Subtarget.pairedVectorMemops() &&
19883 "256-bit vectors are only available when paired vector memops is "
19891 else if (MemVT == MVT::f128 || MemVT.
isVector())
19922 FlagSet &= ~PPC::MOF_NoExt;
19927 bool IsNonP1034BitConst =
19931 IsNonP1034BitConst)
19944 int16_t ForceXFormImm = 0;
19947 Disp =
N.getOperand(0);
19948 Base =
N.getOperand(1);
19959 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
19960 Disp =
N.getOperand(0);
19961 Base =
N.getOperand(1);
19966 Disp = DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
19975 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
19981 if (PartVT == MVT::f64 &&
19982 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
19991SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
19995 EVT RetVT =
Op.getValueType();
20002 EVT ArgVT =
N.getValueType();
20006 Entry.IsZExt = !Entry.IsSExt;
20007 Args.push_back(Entry);
20015 (RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
20028SDValue PPCTargetLowering::lowerLibCallBasedOnType(
20029 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
20031 if (
Op.getValueType() == MVT::f32)
20032 return lowerToLibCall(LibCallFloatName,
Op, DAG);
20034 if (
Op.getValueType() == MVT::f64)
20035 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
20040bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
20041 SDNodeFlags
Flags =
Op.getNode()->getFlags();
20042 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
20046bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
20047 return Op.getNode()->getFlags().hasApproximateFuncs();
20050bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
20054SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
20055 const char *LibCallFloatName,
20056 const char *LibCallDoubleNameFinite,
20057 const char *LibCallFloatNameFinite,
20060 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
20063 if (!isLowringToMASSFiniteSafe(
Op))
20064 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
20067 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
20068 LibCallDoubleNameFinite,
Op, DAG);
20072 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
20073 "__xl_powf_finite",
Op, DAG);
20077 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
20078 "__xl_sinf_finite",
Op, DAG);
20082 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
20083 "__xl_cosf_finite",
Op, DAG);
20087 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
20088 "__xl_logf_finite",
Op, DAG);
20092 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
20093 "__xl_log10f_finite",
Op, DAG);
20097 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
20098 "__xl_expf_finite",
Op, DAG);
20123 unsigned Flags = computeMOFlags(Parent,
N, DAG);
20134 assert(Subtarget.isUsingPCRelativeCalls() &&
20135 "Must be using PC-Relative calls when a valid PC-Relative node is "
20165 Disp =
N.getOperand(1).getOperand(0);
20170 Base =
N.getOperand(0);
20178 EVT CNType = CN->getValueType(0);
20179 uint64_t CNImm = CN->getZExtValue();
20190 if ((CNType == MVT::i32 ||
isInt<32>(CNImm)) &&
20192 int32_t Addr = (int32_t)CNImm;
20197 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
20213 unsigned Opcode =
N.getOpcode();
20221 Base =
N.getOperand(0);
20240 Base = FI ?
N :
N.getOperand(1);
20241 Disp = FI ? DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20252 bool IsVarArg)
const {
20262 return Subtarget.isPPC64() && Subtarget.hasQuadwordAtomics();
20298 return Intrinsic::ppc_atomicrmw_xchg_i128;
20300 return Intrinsic::ppc_atomicrmw_add_i128;
20302 return Intrinsic::ppc_atomicrmw_sub_i128;
20304 return Intrinsic::ppc_atomicrmw_and_i128;
20306 return Intrinsic::ppc_atomicrmw_or_i128;
20308 return Intrinsic::ppc_atomicrmw_xor_i128;
20310 return Intrinsic::ppc_atomicrmw_nand_i128;
20318 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
20320 assert(ValTy->getPrimitiveSizeInBits() == 128);
20322 Value *IncrLo = Builder.CreateTrunc(Incr, Int64Ty,
"incr_lo");
20324 Builder.CreateTrunc(Builder.CreateLShr(Incr, 64), Int64Ty,
"incr_hi");
20325 Value *LoHi = Builder.CreateIntrinsic(
20327 {AlignedAddr, IncrLo, IncrHi});
20328 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
20329 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
20330 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
20331 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
20332 return Builder.CreateOr(
20333 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
20340 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
20342 assert(ValTy->getPrimitiveSizeInBits() == 128);
20346 Value *CmpLo = Builder.CreateTrunc(CmpVal, Int64Ty,
"cmp_lo");
20348 Builder.CreateTrunc(Builder.CreateLShr(CmpVal, 64), Int64Ty,
"cmp_hi");
20349 Value *NewLo = Builder.CreateTrunc(NewVal, Int64Ty,
"new_lo");
20351 Builder.CreateTrunc(Builder.CreateLShr(NewVal, 64), Int64Ty,
"new_hi");
20354 Builder.CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
20356 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
20357 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
20358 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
20359 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
20360 return Builder.CreateOr(
20361 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
20365 return Subtarget.useCRBits();
unsigned const MachineRegisterInfo * MRI
static MCRegister MatchRegisterName(StringRef Name)
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall, std::optional< CallLowering::PtrAuthInfo > &PAI, MachineRegisterInfo &MRI)
static SDValue GeneratePerfectShuffle(unsigned ID, SDValue V1, SDValue V2, unsigned PFEntry, SDValue LHS, SDValue RHS, SelectionDAG &DAG, const SDLoc &DL)
GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit the specified operations t...
static bool isSignExtended(SDValue N, SelectionDAG &DAG)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
static std::pair< Register, unsigned > getBaseWithConstantOffset(MachineRegisterInfo &MRI, Register Reg)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
static bool isLoad(int Opcode)
static bool isFloatingPointZero(SDValue Op)
isFloatingPointZero - Return true if this is +0.0.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
Atomic ordering constants.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Analysis containing CSE Info
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
const HexagonInstrInfo * TII
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, ISD::ArgFlagsTy Flags, SelectionDAG &DAG, const SDLoc &dl)
CreateCopyOfByValArgument - Make a copy of an aggregate at address specified by "Src" to address "Dst...
Module.h This file contains the declarations for the Module class.
This defines the Use class.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
static int getEstimateRefinementSteps(EVT VT, const LoongArchSubtarget &Subtarget)
static bool isSplat(Value *V)
Return true if V is a splat of a value (which is used when multiplying a matrix with a scalar).
Machine Check Debug Module
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static bool isConstantOrUndef(const SDValue Op)
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
cl::opt< bool > ANDIGlueBug("expose-ppc-andi-glue-bug", cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden)
static SDValue getCanonicalConstSplat(uint64_t Val, unsigned SplatSize, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
getCanonicalConstSplat - Build a canonical splat immediate of Val with an element size of SplatSize.
static bool IsSelectCC(MachineInstr &MI)
static 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 SDValue combineADDToMAT_PCREL_ADDR(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setAlignFlagsForFI(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Set alignment flags based on whether or not the Frame Index is aligned.
static bool isTOCSaveRestoreRequired(const PPCSubtarget &Subtarget)
static void updateForAIXShLibTLSModelOpt(TLSModel::Model &Model, SelectionDAG &DAG, const TargetMachine &TM)
updateForAIXShLibTLSModelOpt - Helper to initialize TLS model opt settings, and then apply the update...
static bool provablyDisjointOr(SelectionDAG &DAG, const SDValue &N)
Used when computing address flags for selecting loads and stores.
static bool callsShareTOCBase(const Function *Caller, const GlobalValue *CalleeGV, const TargetMachine &TM)
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 canConvertToVcmpequb(SDValue &LHS, SDValue &RHS)
static bool isPCRelNode(SDValue N)
static void LowerMemOpCallTo(SelectionDAG &DAG, MachineFunction &MF, SDValue Chain, SDValue Arg, SDValue PtrOff, int SPDiff, unsigned ArgOffset, bool isPPC64, bool isTailCall, bool isVector, SmallVectorImpl< SDValue > &MemOpChains, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments, const SDLoc &dl)
LowerMemOpCallTo - Store the argument to the stack or remember it in case of tail calls.
static cl::opt< unsigned > PPCGatherAllAliasesMaxDepth("ppc-gather-alias-max-depth", cl::init(18), cl::Hidden, cl::desc("max depth when checking alias info in GatherAllAliases()"))
static bool areCallingConvEligibleForTCO_64SVR4(CallingConv::ID CallerCC, CallingConv::ID CalleeCC)
static const MCPhysReg FPR[]
FPR - The set of FP registers that should be allocated for arguments on Darwin and AIX.
static SDNode * isBLACompatibleAddress(SDValue Op, SelectionDAG &DAG)
isCallCompatibleAddress - Return the immediate to use if the specified 32-bit value is representable ...
static Align CalculateStackSlotAlignment(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotAlignment - Calculates the alignment of this argument on the stack.
static bool IsSelect(MachineInstr &MI)
static 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 transformCallee(const SDValue &Callee, SelectionDAG &DAG, const SDLoc &dl, const PPCSubtarget &Subtarget)
static unsigned EnsureStackAlignment(const PPCFrameLowering *Lowering, unsigned NumBytes)
EnsureStackAlignment - Round stack frame size up from NumBytes to ensure minimum alignment required f...
static SDValue stripModuloOnShift(const TargetLowering &TLI, SDNode *N, SelectionDAG &DAG)
static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth)
static bool hasSameArgumentList(const Function *CallerFn, const CallBase &CB)
static bool isFPExtLoad(SDValue Op)
static SDValue BuildIntrinsicOp(unsigned IID, SDValue Op, SelectionDAG &DAG, const SDLoc &dl, EVT DestVT=MVT::Other)
BuildIntrinsicOp - Return a unary operator intrinsic node with the specified intrinsic ID.
static bool isConsecutiveLSLoc(SDValue Loc, EVT VT, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static void StoreTailCallArgumentsToStackSlot(SelectionDAG &DAG, SDValue Chain, const SmallVectorImpl< TailCallArgumentInfo > &TailCallArgs, SmallVectorImpl< SDValue > &MemOpChains, const SDLoc &dl)
StoreTailCallArgumentsToStackSlot - Stores arguments to their stack slot.
static 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 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 Instruction * callIntrinsic(IRBuilderBase &Builder, Intrinsic::ID Id)
static void prepareIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, const SDLoc &dl)
static SDValue LowerLabelRef(SDValue HiPart, SDValue LoPart, bool isPIC, SelectionDAG &DAG)
static SDValue isScalarToVec(SDValue Op)
static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl)
static cl::opt< bool > DisablePerfectShuffle("ppc-disable-perfect-shuffle", cl::desc("disable vector permute decomposition"), cl::init(true), cl::Hidden)
bool isValidMtVsrBmi(APInt &BitMask, BuildVectorSDNode &BVN, bool IsLittleEndian)
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 SDValue combineBVZEXTLOAD(SDNode *N, SelectionDAG &DAG)
static SDValue truncateScalarIntegerArg(ISD::ArgFlagsTy Flags, EVT ValVT, SelectionDAG &DAG, SDValue ArgValue, MVT LocVT, const SDLoc &dl)
static void computeFlagsForAddressComputation(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Given a node, compute flags that are used for address computation when selecting load and store instr...
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 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")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
This file describes how to lower LLVM code to machine code.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
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
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 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.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
An instruction that atomically checks whether a specified value is in a memory location,...
Value * getNewValOperand()
an instruction that atomically reads a memory location, combines it with another value,...
BinOp
This enumeration lists the possible modifications atomicrmw can make.
@ 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 BranchProbability getOne()
static 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].
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.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
TypeSize getValue() const
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
Wrapper class representing physical registers. Should be passed by value.
MCSymbolXCOFF * getQualNameSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
@ INVALID_SIMPLE_VALUE_TYPE
uint64_t getScalarSizeInBits() const
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
void setCallFrameSize(unsigned N)
Set the call frame size on entry to this basic block.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
LLVM_ABI int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setHasTailCall(bool V=true)
void setReturnAddressIsTaken(bool s)
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool hasVAStart() const
Returns true if the function calls the llvm.va_start intrinsic.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
MCSymbol * getPICBaseSymbol() const
getPICBaseSymbol - Return a function-local symbol to represent the PIC base.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
@ EK_LabelDifference32
EK_LabelDifference32 - Each entry is the address of the block minus the address of the jump table.
A description of a memory reference used in the backend.
LocationSize getSize() const
Return the size in bytes of the memory reference.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
MachineOperand class - Representation of each machine instruction operand.
static MachineOperand CreateImm(int64_t Val)
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI Register getLiveInVirtReg(MCRegister PReg) const
getLiveInVirtReg - If PReg is a live-in physical register, return the corresponding live-in virtual r...
This SDNode is used for target intrinsics that touch memory and need an associated MachineMemOperand.
This is an abstract virtual class for memory operations.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getBasePtr() const
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
uint64_t getReturnSaveOffset() const
getReturnSaveOffset - Return the previous frame offset to save the return address.
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
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 getTgtMemIntrinsic(IntrinsicInfo &Info, 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...
bool isTruncateFree(Type *Ty1, Type *Ty2) const override
isTruncateFree - Return true if it's free to truncate a value of type Ty1 to type Ty2.
Value * emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI, Value *AlignedAddr, Value *Incr, Value *Mask, Value *ShiftAmt, AtomicOrdering Ord) const override
Perform a masked atomicrmw using a target-specific intrinsic.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
bool isFPExtFree(EVT DestVT, EVT SrcVT) const override
Return true if an fpext operation is free (for instance, because single-precision floating-point numb...
PPC::AddrMode SelectForceXFormMode(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
SelectForceXFormMode - Given the specified address, force it to be represented as an indexed [r+r] op...
Instruction * emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
bool hasInlineStackProbe(const MachineFunction &MF) const override
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
bool supportsTailCallFor(const CallBase *CB) const
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
MachineBasicBlock * emitProbedAlloca(MachineInstr &MI, MachineBasicBlock *MBB) const
bool isZExtFree(SDValue Val, EVT VT2) const override
Return true if zero-extending the specific node Val to type VT2 is free (either because it's implicit...
MachineBasicBlock * EmitPartwordAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, bool is8bit, unsigned Opcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const override
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
bool SelectAddressRegImm(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign EncodingAlignment) const
SelectAddressRegImm - Returns true if the address N can be represented by a base register plus a sign...
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...
TargetLowering::AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
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...
MachineBasicBlock * EmitAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned AtomicSize, unsigned BinOpcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, SmallVectorImpl< SDNode * > &Created) const override
Targets may override this function to provide custom SDIV lowering for power-of-2 denominators.
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.
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...
unsigned getJumpTableEncoding() const override
Return the entry encoding for a jump table in the current function.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
isLegalAddressingMode - Return true if the addressing mode represented by AM is legal for this target...
bool preferIncOfAddToSubOfNot(EVT VT) const override
These two forms are equivalent: sub y, (xor x, -1) add (add x, 1), y The variant with two add's is IR...
bool shouldConvertConstantLoadToIntImm(const APInt &Imm, Type *Ty) const override
Returns true if it is beneficial to convert a load of a constant to just the constant itself.
const MCPhysReg * getScratchRegisters(CallingConv::ID CC) const override
Returns a 0 terminated array of registers that can be safely used as scratch registers.
bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const override
getPreIndexedAddressParts - returns true by value, base pointer and offset pointer and addressing mod...
bool isProfitableToHoist(Instruction *I) const override
isProfitableToHoist - Check if it is profitable to hoist instruction I to its dominator block.
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
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
PPCTargetLowering(const PPCTargetMachine &TM, const PPCSubtarget &STI)
TargetLowering::AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
bool 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...
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const override
Is unaligned memory access allowed for the given type, and is it fast relative to software emulation.
bool shouldExpandBuildVectorWithShuffles(EVT VT, unsigned DefinedValues) const override
bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
Similar to the 16-bit case but for instructions that take a 34-bit displacement field (prefixed loads...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
bool isJumpTableRelative() const override
Register getExceptionPointerRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
PPC::AddrMode SelectOptimalAddrMode(const SDNode *Parent, SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign Align) const
SelectOptimalAddrMode - Based on a node N and it's Parent (a MemSDNode), compute the address flags of...
bool SelectAddressPCRel(SDValue N, SDValue &Base) const
SelectAddressPCRel - Represent the specified address as pc relative to be represented as [pc+imm].
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the ISD::SETCC ValueType
bool SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressEVXRegReg - Given the specified addressed, check to see if it can be more efficiently re...
bool isLegalICmpImmediate(int64_t Imm) const override
isLegalICmpImmediate - Return true if the specified immediate is legal icmp immediate,...
bool isAccessedAsGotIndirect(SDValue N) const
Align getPrefLoopAlignment(MachineLoop *ML) const override
Return the preferred loop alignment.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo) const override
createFastISel - This method returns a target-specific FastISel object, or null if the target does no...
bool shouldInlineQuadwordAtomics() const
Instruction * emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Inserts in the IR a target-specific intrinsic specifying a fence.
bool isLegalAddImmediate(int64_t Imm) const override
isLegalAddImmediate - Return true if the specified immediate is legal add immediate,...
Common code between 32-bit and 64-bit PowerPC targets.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
This class provides iterator support for SDUse operands that use a specific SDNode.
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
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.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getOpcode() const
unsigned getNumOperands() const
static SectionKind getMetadata()
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
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 AAMDNodes &AAInfo=AAMDNodes())
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...
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
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 getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
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.
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
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).
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 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 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 getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
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 getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
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 ...
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 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
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
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...
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.
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 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...
virtual AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
unsigned GatherAllAliasesMaxDepth
Depth that GatherAllAliases should continue looking for chain dependencies when trying to find a more...
NegatibleCost
Enum that specifies when a float negation is beneficial.
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 getSqrtInputTest(SDValue Operand, SelectionDAG &DAG, const DenormalMode &Mode) const
Return a target-dependent comparison result if the input operand is suitable for use with a square ro...
virtual SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const
Returns relocation base for the given PIC jumptable.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
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 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 NoInfsFPMath
NoInfsFPMath - This flag is enabled when the -enable-no-infs-fp-math flag is specified on the command...
unsigned PPCGenScalarMASSEntries
Enables scalar MASS conversions.
unsigned NoNaNsFPMath
NoNaNsFPMath - This flag is enabled when the -enable-no-nans-fp-math flag is specified on the command...
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
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.
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ BSWAP
Byte Swap and Counting operators.
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, 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.
@ 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,...
@ 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 * > Tys={})
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.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo)
bool isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for a VRGH* instruction with the ...
bool isVPKUDUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUDUMShuffleMask - Return true if this is the shuffle mask for a VPKUDUM instruction.
bool isVMRGEOShuffleMask(ShuffleVectorSDNode *N, bool CheckEven, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGEOShuffleMask - Return true if this is a shuffle mask suitable for a VMRGEW or VMRGOW instructi...
bool isXXBRQShuffleMask(ShuffleVectorSDNode *N)
isXXBRQShuffleMask - Return true if this is a shuffle mask suitable for a XXBRQ instruction.
bool isXXBRWShuffleMask(ShuffleVectorSDNode *N)
isXXBRWShuffleMask - Return true if this is a shuffle mask suitable for a XXBRW instruction.
bool isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXPERMDIShuffleMask - Return true if this is a shuffle mask suitable for a XXPERMDI instruction.
bool isXXBRHShuffleMask(ShuffleVectorSDNode *N)
isXXBRHShuffleMask - Return true if this is a shuffle mask suitable for a XXBRH instruction.
unsigned getSplatIdxForPPCMnemonics(SDNode *N, unsigned EltSize, SelectionDAG &DAG)
getSplatIdxForPPCMnemonics - Return the splat index as a value that is appropriate for PPC mnemonics ...
bool isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXSLDWIShuffleMask - Return true if this is a shuffle mask suitable for a XXSLDWI instruction.
int isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift amount, otherwise return -1.
bool isVMRGLShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for a VRGL* instruction with the ...
bool isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, unsigned &InsertAtByte, bool &Swap, bool IsLE)
isXXINSERTWMask - Return true if this VECTOR_SHUFFLE can be handled by the XXINSERTW instruction intr...
bool isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize)
isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand specifies a splat of a singl...
bool isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a VPKUWUM instruction.
bool isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a VPKUHUM instruction.
@ Define
Register definition.
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
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
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.
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,...
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)
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 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 raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
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...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
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.
static const unsigned PerfectShuffleTable[6561+1]
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This is used by foldLoadsRecursive() to capture a Root Load node which is of type or(load,...
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 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.
void resetAll()
Resets the known state of all bits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
This class contains a discriminated union of information about pointers in memory operands,...
static 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.