69#include "llvm/IR/IntrinsicsPowerPC.h"
103#define DEBUG_TYPE "ppc-lowering"
108 "ppc-p10-store-forward",
113 "ppc-preinc",
cl::desc(
"enable preincrement load/store generation on PPC"),
118 cl::desc(
"Set the node scheduling preference to ILP on PPC"),
122 "ppc-unaligned",
cl::desc(
"enable unaligned load/store generation on PPC"),
130 "ppc-innermost-loop-align32",
139 cl::desc(
"enable vector permute decomposition"),
143 "ppc-auto-paired-vec-st",
144 cl::desc(
"enable automatically generated 32byte paired vector stores"),
149 cl::desc(
"Set minimum number of entries to use a jump table on PPC"));
153 cl::desc(
"Set minimum of largest number of comparisons to use bit test for "
158 cl::desc(
"max depth when checking alias info in GatherAllAliases()"));
162 cl::desc(
"Set inclusive limit count of TLS local-dynamic access(es) in a "
163 "function to use initial-exec"));
168 "Number of shuffles lowered to a VPERM or XXPERM");
169STATISTIC(NumDynamicAllocaProbed,
"Number of dynamic stack allocation probed");
176 unsigned OpIdx,
bool IsByte,
194 initializeAddrModeMap();
197 bool isPPC64 = Subtarget.isPPC64();
199 const MVT RegVT = Subtarget.getScalarIntVT();
207 if (!Subtarget.hasEFPU2())
224 if (!Subtarget.hasP10Vector()) {
250 if (Subtarget.isISA3_0()) {
283 if (!Subtarget.hasSPE()) {
290 if (Subtarget.useCRBits()) {
293 if (isPPC64 || Subtarget.hasFPCVT()) {
359 if (Subtarget.isISA3_0()) {
394 if (!Subtarget.hasSPE()) {
399 if (Subtarget.hasVSX()) {
404 if (Subtarget.hasFSQRT()) {
409 if (Subtarget.hasFPRND()) {
450 if (Subtarget.hasSPE()) {
460 if (Subtarget.hasSPE())
464 if (!Subtarget.hasFSQRT() && !(Subtarget.hasFRSQRTE() && Subtarget.hasFRE()))
467 if (!Subtarget.hasFSQRT() &&
468 !(Subtarget.hasFRSQRTES() && Subtarget.hasFRES()))
471 if (Subtarget.hasFCPSGN()) {
479 if (Subtarget.hasFPRND()) {
493 if (Subtarget.isISA3_1()) {
499 ((Subtarget.hasP8Vector()) && isPPC64) ?
Custom
504 if (Subtarget.isISA3_0()) {
524 if (!Subtarget.useCRBits()) {
537 if (!Subtarget.useCRBits())
540 if (Subtarget.hasFPU()) {
551 if (!Subtarget.useCRBits())
556 if (Subtarget.hasSPE()) {
588 if (Subtarget.hasDirectMove() && isPPC64) {
652 if (Subtarget.is64BitELFABI()) {
663 }
else if (Subtarget.is32BitELFABI()) {
671 if (Subtarget.is32BitELFABI())
687 if (Subtarget.isISA3_0() && isPPC64) {
715 if (Subtarget.hasSPE()) {
737 if (Subtarget.has64BitSupport()) {
752 if (Subtarget.hasLFIWAX() || isPPC64) {
758 if (Subtarget.hasSPE()) {
768 if (Subtarget.hasFPCVT()) {
769 if (Subtarget.has64BitSupport()) {
790 if (Subtarget.use64BitRegs()) {
808 if (Subtarget.has64BitSupport()) {
815 if (Subtarget.hasVSX()) {
828 if (Subtarget.hasAltivec()) {
829 for (
MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
846 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
859 if (Subtarget.hasVSX()) {
868 if (Subtarget.hasP8Altivec() && (VT.SimpleTy != MVT::v1i128)) {
878 if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
952 if (!Subtarget.hasP8Vector()) {
994 if (Subtarget.hasAltivec())
995 for (
auto VT : {MVT::v4i32, MVT::v8i16, MVT::v16i8})
998 if (Subtarget.hasP8Altivec())
1009 if (Subtarget.hasVSX()) {
1015 if (Subtarget.hasP8Altivec())
1020 if (Subtarget.isISA3_1()) {
1066 if (Subtarget.hasVSX()) {
1069 if (Subtarget.hasP8Vector()) {
1073 if (Subtarget.hasDirectMove() && isPPC64) {
1122 if (Subtarget.hasP8Vector())
1131 if (Subtarget.hasP8Altivec()) {
1158 if (Subtarget.isISA3_1())
1261 if (Subtarget.hasP8Altivec()) {
1266 if (Subtarget.hasP9Vector()) {
1271 if (Subtarget.useCRBits()) {
1331 }
else if (Subtarget.hasVSX()) {
1356 for (
MVT VT : {MVT::f32, MVT::f64}) {
1375 if (Subtarget.hasP9Altivec()) {
1376 if (Subtarget.isISA3_1()) {
1399 if (Subtarget.hasP10Vector()) {
1414 if (Subtarget.pairedVectorMemops()) {
1419 if (Subtarget.hasMMA()) {
1420 if (Subtarget.isISAFuture()) {
1436 if (Subtarget.has64BitSupport())
1439 if (Subtarget.isISA3_1())
1457 if (Subtarget.hasAltivec()) {
1475 if (Subtarget.hasFPCVT())
1478 if (Subtarget.useCRBits())
1487 if (Subtarget.useCRBits()) {
1491 if (Subtarget.hasP8Vector())
1496 if (Subtarget.useCRBits()) {
1512 auto CPUDirective = Subtarget.getCPUDirective();
1513 switch (CPUDirective) {
1536 if (Subtarget.enableMachineScheduler())
1610void PPCTargetLowering::initializeAddrModeMap() {
1661 if (MaxAlign == MaxMaxAlign)
1664 if (MaxMaxAlign >= 32 &&
1665 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1666 MaxAlign =
Align(32);
1667 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1669 MaxAlign =
Align(16);
1673 if (EltAlign > MaxAlign)
1674 MaxAlign = EltAlign;
1676 for (
auto *EltTy : STy->elements()) {
1679 if (EltAlign > MaxAlign)
1680 MaxAlign = EltAlign;
1681 if (MaxAlign == MaxMaxAlign)
1694 if (Subtarget.hasAltivec())
1700 return Subtarget.useSoftFloat();
1704 return Subtarget.hasSPE();
1712 Type *VectorTy,
unsigned ElemSizeInBits,
unsigned &Index)
const {
1713 if (!Subtarget.isPPC64() || !Subtarget.hasVSX())
1717 if (VTy->getScalarType()->isIntegerTy()) {
1719 if (ElemSizeInBits == 32) {
1720 Index = Subtarget.isLittleEndian() ? 2 : 1;
1723 if (ElemSizeInBits == 64) {
1724 Index = Subtarget.isLittleEndian() ? 1 : 0;
1735 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1752 return CFP->getValueAPF().isZero();
1757 return CFP->getValueAPF().isZero();
1765 return Op < 0 ||
Op == Val;
1777 if (ShuffleKind == 0) {
1780 for (
unsigned i = 0; i != 16; ++i)
1783 }
else if (ShuffleKind == 2) {
1786 for (
unsigned i = 0; i != 16; ++i)
1789 }
else if (ShuffleKind == 1) {
1790 unsigned j = IsLE ? 0 : 1;
1791 for (
unsigned i = 0; i != 8; ++i)
1808 if (ShuffleKind == 0) {
1811 for (
unsigned i = 0; i != 16; i += 2)
1815 }
else if (ShuffleKind == 2) {
1818 for (
unsigned i = 0; i != 16; i += 2)
1822 }
else if (ShuffleKind == 1) {
1823 unsigned j = IsLE ? 0 : 2;
1824 for (
unsigned i = 0; i != 8; i += 2)
1849 if (ShuffleKind == 0) {
1852 for (
unsigned i = 0; i != 16; i += 4)
1858 }
else if (ShuffleKind == 2) {
1861 for (
unsigned i = 0; i != 16; i += 4)
1867 }
else if (ShuffleKind == 1) {
1868 unsigned j = IsLE ? 0 : 4;
1869 for (
unsigned i = 0; i != 8; i += 4)
1886 unsigned LHSStart,
unsigned RHSStart) {
1887 if (
N->getValueType(0) != MVT::v16i8)
1889 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
1890 "Unsupported merge size!");
1892 for (
unsigned i = 0; i != 8/UnitSize; ++i)
1893 for (
unsigned j = 0; j != UnitSize; ++j) {
1895 LHSStart+j+i*UnitSize) ||
1897 RHSStart+j+i*UnitSize))
1912 if (ShuffleKind == 1)
1914 else if (ShuffleKind == 2)
1919 if (ShuffleKind == 1)
1921 else if (ShuffleKind == 0)
1937 if (ShuffleKind == 1)
1939 else if (ShuffleKind == 2)
1944 if (ShuffleKind == 1)
1946 else if (ShuffleKind == 0)
1996 unsigned RHSStartValue) {
1997 if (
N->getValueType(0) != MVT::v16i8)
2000 for (
unsigned i = 0; i < 2; ++i)
2001 for (
unsigned j = 0; j < 4; ++j)
2003 i*RHSStartValue+j+IndexOffset) ||
2005 i*RHSStartValue+j+IndexOffset+8))
2027 unsigned indexOffset = CheckEven ? 4 : 0;
2028 if (ShuffleKind == 1)
2030 else if (ShuffleKind == 2)
2036 unsigned indexOffset = CheckEven ? 0 : 4;
2037 if (ShuffleKind == 1)
2039 else if (ShuffleKind == 0)
2055 if (
N->getValueType(0) != MVT::v16i8)
2062 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2065 if (i == 16)
return -1;
2070 if (ShiftAmt < i)
return -1;
2075 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2077 for (++i; i != 16; ++i)
2080 }
else if (ShuffleKind == 1) {
2082 for (++i; i != 16; ++i)
2089 ShiftAmt = 16 - ShiftAmt;
2098 EVT VT =
N->getValueType(0);
2099 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2100 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2103 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2107 if (
N->getMaskElt(0) % EltSize != 0)
2112 unsigned ElementBase =
N->getMaskElt(0);
2115 if (ElementBase >= 16)
2120 for (
unsigned i = 1; i != EltSize; ++i)
2121 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2124 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2126 if (
N->getMaskElt(i) < 0) {
2127 for (
unsigned j = 1; j != EltSize; ++j)
2128 if (
N->getMaskElt(i + j) >= 0)
2131 for (
unsigned j = 0; j != EltSize; ++j)
2132 if (
N->getMaskElt(i + j) !=
N->getMaskElt(j))
2149 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2150 "Unexpected element width.");
2151 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2153 unsigned NumOfElem = 16 / Width;
2154 unsigned MaskVal[16];
2155 for (
unsigned i = 0; i < NumOfElem; ++i) {
2156 MaskVal[0] =
N->getMaskElt(i * Width);
2157 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2159 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2163 for (
unsigned int j = 1; j < Width; ++j) {
2164 MaskVal[j] =
N->getMaskElt(i * Width + j);
2165 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2175 unsigned &InsertAtByte,
bool &
Swap,
bool IsLE) {
2180 unsigned M0 =
N->getMaskElt(0) / 4;
2181 unsigned M1 =
N->getMaskElt(4) / 4;
2182 unsigned M2 =
N->getMaskElt(8) / 4;
2183 unsigned M3 =
N->getMaskElt(12) / 4;
2184 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2185 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2190 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2191 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2192 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2193 InsertAtByte = IsLE ? 12 : 0;
2198 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2199 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2200 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2201 InsertAtByte = IsLE ? 8 : 4;
2206 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2207 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2208 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2209 InsertAtByte = IsLE ? 4 : 8;
2214 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2215 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2216 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2217 InsertAtByte = IsLE ? 0 : 12;
2224 if (
N->getOperand(1).isUndef()) {
2227 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2228 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2229 InsertAtByte = IsLE ? 12 : 0;
2232 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2233 InsertAtByte = IsLE ? 8 : 4;
2236 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2237 InsertAtByte = IsLE ? 4 : 8;
2240 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2241 InsertAtByte = IsLE ? 0 : 12;
2250 bool &
Swap,
bool IsLE) {
2251 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2257 unsigned M0 =
N->getMaskElt(0) / 4;
2258 unsigned M1 =
N->getMaskElt(4) / 4;
2259 unsigned M2 =
N->getMaskElt(8) / 4;
2260 unsigned M3 =
N->getMaskElt(12) / 4;
2264 if (
N->getOperand(1).isUndef()) {
2265 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2266 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2269 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2275 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2279 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2284 ShiftElts = (8 -
M0) % 8;
2285 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2290 ShiftElts = (4 -
M0) % 4;
2295 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2300 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2312 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2317 for (
int i = 0; i < 16; i += Width)
2318 if (
N->getMaskElt(i) != i + Width - 1)
2349 bool &
Swap,
bool IsLE) {
2350 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2356 unsigned M0 =
N->getMaskElt(0) / 8;
2357 unsigned M1 =
N->getMaskElt(8) / 8;
2358 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2362 if (
N->getOperand(1).isUndef()) {
2363 if ((
M0 |
M1) < 2) {
2364 DM = IsLE ? (((
~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2372 if (
M0 > 1 &&
M1 < 2) {
2382 DM = (((
~M1) & 1) << 1) + ((~
M0) & 1);
2387 }
else if (
M0 > 1 &&
M1 < 2) {
2395 DM = (
M0 << 1) + (
M1 & 1);
2410 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2415 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2431 unsigned EltSize = 16/
N->getNumOperands();
2432 if (EltSize < ByteSize) {
2433 unsigned Multiple = ByteSize/EltSize;
2435 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2438 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2439 if (
N->getOperand(i).isUndef())
continue;
2443 if (!UniquedVals[i&(Multiple-1)].
getNode())
2444 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2445 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2455 bool LeadingZero =
true;
2456 bool LeadingOnes =
true;
2457 for (
unsigned i = 0; i != Multiple-1; ++i) {
2458 if (!UniquedVals[i].
getNode())
continue;
2465 if (!UniquedVals[Multiple-1].
getNode())
2472 if (!UniquedVals[Multiple-1].
getNode())
2483 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2484 if (
N->getOperand(i).isUndef())
continue;
2486 OpVal =
N->getOperand(i);
2487 else if (OpVal !=
N->getOperand(i))
2493 unsigned ValSizeInBytes = EltSize;
2496 Value = CN->getZExtValue();
2498 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2505 if (ValSizeInBytes < ByteSize)
return SDValue();
2516 if (MaskVal == 0)
return SDValue();
2536 Imm = (int16_t)
N->getAsZExtVal();
2537 if (
N->getValueType(0) == MVT::i32)
2538 return Imm == (int32_t)
N->getAsZExtVal();
2540 return Imm == (int64_t)
N->getAsZExtVal();
2558 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2566 for (
SDNode *U :
N->users()) {
2568 if (Memop->getMemoryVT() == MVT::f64) {
2569 Base =
N.getOperand(0);
2570 Index =
N.getOperand(1);
2613 (!EncodingAlignment ||
isAligned(*EncodingAlignment,
Imm)))
2615 if (
N.getOperand(1).getOpcode() == PPCISD::Lo)
2618 Base =
N.getOperand(0);
2619 Index =
N.getOperand(1);
2621 }
else if (
N.getOpcode() ==
ISD::OR) {
2623 (!EncodingAlignment ||
isAligned(*EncodingAlignment,
Imm)))
2635 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2636 Base =
N.getOperand(0);
2637 Index =
N.getOperand(1);
2707 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2713 Base =
N.getOperand(0);
2716 }
else if (
N.getOperand(1).getOpcode() == PPCISD::Lo) {
2718 assert(!
N.getOperand(1).getConstantOperandVal(1) &&
2719 "Cannot handle constant offsets yet!");
2720 Disp =
N.getOperand(1).getOperand(0);
2725 Base =
N.getOperand(0);
2728 }
else if (
N.getOpcode() ==
ISD::OR) {
2731 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2745 Base =
N.getOperand(0);
2758 (!EncodingAlignment ||
isAligned(*EncodingAlignment,
Imm))) {
2761 CN->getValueType(0));
2766 if ((CN->getValueType(0) == MVT::i32 ||
2767 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2768 (!EncodingAlignment ||
2769 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2770 int Addr = (int)CN->getZExtValue();
2777 unsigned Opc = CN->getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2798 if (
N.getValueType() != MVT::i64)
2811 Base =
N.getOperand(0);
2827 Base =
N.getOperand(0);
2860 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2861 Base =
N.getOperand(0);
2862 Index =
N.getOperand(1);
2884 if (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR)
2905 EVT MemVT = LD->getMemoryVT();
2912 if (!ST.hasP8Vector())
2917 if (!ST.hasP9Vector())
2929 if (
Use.getResNo() == 0 &&
2931 Use.
getUser()->getOpcode() != PPCISD::SCALAR_TO_VECTOR_PERMUTED)
2952 Ptr = LD->getBasePtr();
2953 VT = LD->getMemoryVT();
2954 Alignment = LD->getAlign();
2956 Ptr = ST->getBasePtr();
2957 VT = ST->getMemoryVT();
2958 Alignment = ST->getAlign();
2997 if (VT != MVT::i64) {
3002 if (Alignment <
Align(4))
3012 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
3029 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3071 EVT VT = Subtarget.getScalarIntVT();
3073 : Subtarget.isAIXABI()
3078 PPCISD::TOC_ENTRY, dl, DAG.
getVTList(VT, MVT::Other),
Ops, VT,
3085 EVT PtrVT =
Op.getValueType();
3091 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3092 if (Subtarget.isUsingPCRelativeCalls()) {
3097 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, ConstPool);
3101 return getTOCEntry(DAG, SDLoc(CP), GA);
3104 unsigned MOHiFlag, MOLoFlag;
3108 if (IsPIC && Subtarget.isSVR4ABI()) {
3111 return getTOCEntry(DAG, SDLoc(CP), GA);
3134 if (Subtarget.isPPC64() || Subtarget.isAIXABI())
3141 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3158 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3171 EVT PtrVT =
Op.getValueType();
3175 if (
Subtarget.isUsingPCRelativeCalls()) {
3189 return getTOCEntry(DAG,
SDLoc(JT), GA);
3192 unsigned MOHiFlag, MOLoFlag;
3196 if (IsPIC && Subtarget.isSVR4ABI()) {
3199 return getTOCEntry(DAG, SDLoc(GA), GA);
3209 EVT PtrVT =
Op.getValueType();
3214 if (Subtarget.isUsingPCRelativeCalls()) {
3225 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3228 return getTOCEntry(DAG, SDLoc(BASDN), GA);
3237 unsigned MOHiFlag, MOLoFlag;
3247 if (Subtarget.isAIXABI())
3248 return LowerGlobalTLSAddressAIX(
Op, DAG);
3250 return LowerGlobalTLSAddressLinux(
Op, DAG);
3272 if (
I.getOpcode() == Instruction::Call)
3274 if (
Function *CF = CI->getCalledFunction())
3275 if (CF->isDeclaration() &&
3276 CF->getIntrinsicID() == Intrinsic::threadlocal_address)
3284 unsigned TLSGVCnt = TLSGV.
size();
3294 <<
" function is using the TLS-IE model for TLS-LD access.\n");
3307 const GlobalValue *GV = GA->
getGlobal();
3309 bool Is64Bit = Subtarget.isPPC64();
3313 if (Subtarget.hasAIXShLibTLSModelOpt())
3323 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3324 bool HasAIXSmallTLSGlobalAttr =
false;
3327 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3331 if (GVar->hasAttribute(
"aix-small-tls"))
3332 HasAIXSmallTLSGlobalAttr =
true;
3351 if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) &&
3352 IsTLSLocalExecModel) {
3357 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA, TLSReg);
3367 TLSReg = DAG.
getNode(PPCISD::GET_TPOINTER, dl, PtrVT);
3372 if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr)
3374 "currently only supported on AIX (64-bit mode).");
3376 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, VariableOffset);
3380 bool HasAIXSmallLocalDynamicTLS = Subtarget.hasAIXSmallLocalDynamicTLS();
3384 if (!Is64Bit && HasAIXSmallLocalDynamicTLS)
3386 "currently only supported on AIX (64-bit mode).");
3394 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3397 GlobalVariable *TLSGV =
3401 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3404 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3406 DAG.
getNode(PPCISD::TLSLD_AIX, dl, PtrVT, ModuleHandleTOC);
3415 if (HasAIXSmallLocalDynamicTLS) {
3420 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA,
3424 return DAG.
getNode(
ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
3437 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3438 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3439 return DAG.
getNode(PPCISD::TLSGD_AIX, dl, PtrVT, VariableOffset,
3454 const GlobalValue *GV = GA->
getGlobal();
3456 bool is64bit = Subtarget.isPPC64();
3464 if (Subtarget.isUsingPCRelativeCalls()) {
3469 DAG.
getNode(PPCISD::TLS_LOCAL_EXEC_MAT_ADDR, dl, PtrVT, TGA);
3470 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, MatAddr);
3481 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, TGALo,
Hi);
3485 bool IsPCRel = Subtarget.isUsingPCRelativeCalls();
3492 SDValue MatPCRel = DAG.
getNode(PPCISD::MAT_PCREL_ADDR, dl, PtrVT, TGA);
3494 MachinePointerInfo());
3501 DAG.
getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl, PtrVT, GOTReg, TGA);
3503 if (!TM.isPositionIndependent())
3504 GOTPtr = DAG.
getNode(PPCISD::PPC32_GOT, dl, PtrVT);
3510 TPOffset = DAG.
getNode(PPCISD::LD_GOT_TPREL_L, dl, PtrVT, TGA, GOTPtr);
3516 if (Subtarget.isUsingPCRelativeCalls()) {
3519 return DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3527 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSGD_HA, dl, PtrVT,
3535 return DAG.
getNode(PPCISD::ADDI_TLSGD_L_ADDR, dl, PtrVT,
3540 if (Subtarget.isUsingPCRelativeCalls()) {
3544 DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3545 return DAG.
getNode(PPCISD::PADDI_DTPREL, dl, PtrVT, MatPCRel, TGA);
3553 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSLD_HA, dl, PtrVT,
3562 PtrVT, GOTPtr, TGA, TGA);
3564 PtrVT, TLSAddr, TGA);
3565 return DAG.
getNode(PPCISD::ADDI_DTPREL_L, dl, PtrVT, DtvOffsetHi, TGA);
3573 EVT PtrVT =
Op.getValueType();
3576 const GlobalValue *GV = GSDN->
getGlobal();
3580 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3581 if (Subtarget.isUsingPCRelativeCalls()) {
3588 MachinePointerInfo());
3593 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, GA);
3598 return getTOCEntry(DAG,
DL, GA);
3601 unsigned MOHiFlag, MOLoFlag;
3605 if (IsPIC && Subtarget.isSVR4ABI()) {
3609 return getTOCEntry(DAG,
DL, GA);
3621 bool IsStrict =
Op->isStrictFPOpcode();
3622 const SDNodeFlags
Flags =
Op.getNode()->getFlags();
3627 EVT LHSVT =
LHS.getValueType();
3631 if (LHSVT == MVT::f128 ||
3632 (Subtarget.hasSPE() && (LHSVT == MVT::f32 || LHSVT == MVT::f64) &&
3633 (!
Flags.hasNoNaNs() || !
Flags.hasNoInfs()))) {
3634 assert(!Subtarget.hasP9Vector() &&
3635 "SETCC for f128 is already legal under Power9!");
3644 }
else if (LHSVT == MVT::f32 || LHSVT == MVT::f64) {
3648 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3650 if (
Op.getValueType() == MVT::v2i64) {
3653 if (
LHS.getValueType() == MVT::v2i64) {
3661 int ShuffV[] = {1, 0, 3, 2};
3666 dl, MVT::v4i32, Shuff, SetCC32));
3683 if (
C->isAllOnes() ||
C->isZero())
3693 EVT VT =
Op.getValueType();
3701 const SDNodeFlags
Flags =
Op->getFlags();
3707 EVT LHSVT =
LHS.getValueType();
3710 if ((LHSVT == MVT::f32 || LHSVT == MVT::f64) &&
Flags.hasNoNaNs() &&
3728 SDNode *
Node =
Op.getNode();
3729 EVT VT =
Node->getValueType(0);
3736 assert(!Subtarget.isPPC64() &&
"LowerVAARG is PPC32 only");
3740 VAListPtr, MachinePointerInfo(SV), MVT::i8);
3743 if (VT == MVT::i64) {
3762 FprPtr, MachinePointerInfo(SV), MVT::i8);
3773 DAG.
getLoad(MVT::i32, dl, InChain, OverflowAreaPtr, MachinePointerInfo());
3774 InChain = OverflowArea.
getValue(1);
3777 DAG.
getLoad(MVT::i32, dl, InChain, RegSaveAreaPtr, MachinePointerInfo());
3807 MachinePointerInfo(SV), MVT::i8);
3820 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3821 MachinePointerInfo(), MVT::i32);
3823 return DAG.
getLoad(VT, dl, InChain, Result, MachinePointerInfo());
3827 assert(!Subtarget.isPPC64() &&
"LowerVACOPY is PPC32 only");
3833 Align(8),
false,
true,
nullptr, std::nullopt,
3834 MachinePointerInfo(), MachinePointerInfo());
3839 return Op.getOperand(0);
3844 PPCFunctionInfo &MFI = *MF.
getInfo<PPCFunctionInfo>();
3848 "Expecting Inline ASM node.");
3858 if (
Op.getOperand(
NumOps - 1).getValueType() == MVT::Glue)
3863 const InlineAsm::Flag
Flags(
Op.getConstantOperandVal(i));
3864 unsigned NumVals =
Flags.getNumOperandRegisters();
3867 switch (
Flags.getKind()) {
3878 for (; NumVals; --NumVals, ++i) {
3880 if (
Reg != PPC::LR &&
Reg != PPC::LR8)
3903 if (Subtarget.isAIXABI()) {
3908 MaybeAlign PointerAlign(PointerSize);
3909 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
3912 : MachineMemOperand::MONone;
3919 const Value *TrampolineAddr =
3929 DAG.
getLoad(PtrVT, dl, Chain, FPtr, MachinePointerInfo(Func, 0),
3930 PointerAlign, MMOFlags);
3932 OutChains[0] = DAG.
getStore(EPLoadChain, dl, LoadEntryPoint, Trmp,
3933 MachinePointerInfo(TrampolineAddr, 0));
3937 SDValue TOCFromDescriptorPtr =
3939 SDValue TOCReg = DAG.
getLoad(PtrVT, dl, Chain, TOCFromDescriptorPtr,
3940 MachinePointerInfo(Func, TOCPointerOffset),
3941 PointerAlign, MMOFlags);
3942 SDValue TrampolineTOCPointer =
3946 DAG.
getStore(TOCLoadChain, dl, TOCReg, TrampolineTOCPointer,
3947 MachinePointerInfo(TrampolineAddr, TOCPointerOffset));
3953 DAG.
getStore(Chain, dl, Nest, EnvPointer,
3954 MachinePointerInfo(TrampolineAddr, EnvPointerOffset));
3961 bool isPPC64 = (PtrVT == MVT::i64);
3968 DAG.
getConstant(isPPC64 ? 48 : 40, dl, Subtarget.getScalarIntVT()),
3974 TargetLowering::CallLoweringInfo CLI(DAG);
3975 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3979 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
3980 return CallResult.second;
3985 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
3990 if (Subtarget.isPPC64() || Subtarget.isAIXABI()) {
3995 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
3996 MachinePointerInfo(SV));
4030 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
4033 uint64_t StackOffset = PtrVT.getSizeInBits()/8 - 1;
4044 MachinePointerInfo(SV), MVT::i8);
4052 MachinePointerInfo(SV, nextOffset), MVT::i8);
4053 nextOffset += StackOffset;
4054 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
4057 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
4058 MachinePointerInfo(SV, nextOffset));
4059 nextOffset += FrameOffset;
4060 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
4063 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
4064 MachinePointerInfo(SV, nextOffset));
4069static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
4070 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
4071 PPC::F11, PPC::F12, PPC::F13};
4076 unsigned PtrByteSize) {
4078 if (Flags.isByVal())
4079 ArgSize = Flags.getByValSize();
4083 if (!Flags.isInConsecutiveRegs())
4084 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4093 unsigned PtrByteSize) {
4094 Align Alignment(PtrByteSize);
4097 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4098 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4099 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4100 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4101 Alignment =
Align(16);
4104 if (Flags.isByVal()) {
4105 auto BVAlign = Flags.getNonZeroByValAlign();
4106 if (BVAlign > PtrByteSize) {
4107 if (BVAlign.value() % PtrByteSize != 0)
4109 "ByVal alignment is not a multiple of the pointer size");
4111 Alignment = BVAlign;
4116 if (Flags.isInConsecutiveRegs()) {
4120 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4134 unsigned PtrByteSize,
unsigned LinkageSize,
4135 unsigned ParamAreaSize,
unsigned &ArgOffset,
4136 unsigned &AvailableFPRs,
4137 unsigned &AvailableVRs) {
4138 bool UseMemory =
false;
4143 ArgOffset =
alignTo(ArgOffset, Alignment);
4146 if (ArgOffset >= LinkageSize + ParamAreaSize)
4151 if (Flags.isInConsecutiveRegsLast())
4152 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4155 if (ArgOffset > LinkageSize + ParamAreaSize)
4160 if (!Flags.isByVal()) {
4161 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4162 if (AvailableFPRs > 0) {
4166 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4167 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4168 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4169 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4170 if (AvailableVRs > 0) {
4182 unsigned NumBytes) {
4186SDValue PPCTargetLowering::LowerFormalArguments(
4190 if (Subtarget.isAIXABI())
4191 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4193 if (Subtarget.is64BitELFABI())
4194 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4196 assert(Subtarget.is32BitELFABI());
4197 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4201SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4237 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4243 const Align PtrAlign(4);
4251 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4252 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4255 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4256 CCValAssign &VA = ArgLocs[i];
4268 RC = &PPC::GPRCRegClass;
4271 if (Subtarget.hasP8Vector())
4272 RC = &PPC::VSSRCRegClass;
4273 else if (Subtarget.hasSPE())
4274 RC = &PPC::GPRCRegClass;
4276 RC = &PPC::F4RCRegClass;
4279 if (Subtarget.hasVSX())
4280 RC = &PPC::VSFRCRegClass;
4281 else if (Subtarget.hasSPE())
4283 RC = &PPC::GPRCRegClass;
4285 RC = &PPC::F8RCRegClass;
4294 RC = &PPC::VRRCRegClass;
4301 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4302 assert(i + 1 < e &&
"No second half of double precision argument");
4307 if (!Subtarget.isLittleEndian())
4309 ArgValue = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64, ArgValueLo,
4314 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4315 if (ValVT == MVT::i1)
4330 ArgOffset += ArgSize - ObjSize;
4348 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4353 unsigned MinReservedArea = CCByValInfo.getStackSize();
4354 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4370 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4371 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4373 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4376 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4379 unsigned NumFPArgRegs = std::size(FPArgRegs);
4388 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4389 NumFPArgRegs * MVT(MVT::f64).getSizeInBits()/8;
4392 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4405 VReg = MF.
addLiveIn(GPArgReg, &PPC::GPRCRegClass);
4420 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4424 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4437 if (!MemOps.
empty())
4448 const SDLoc &dl)
const {
4452 else if (
Flags.isZExt())
4459SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4465 bool isELFv2ABI = Subtarget.isELFv2ABI();
4466 bool isLittleEndian = Subtarget.isLittleEndian();
4469 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4472 "fastcc not supported on varargs functions");
4478 unsigned PtrByteSize = 8;
4479 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4482 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4483 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4486 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4487 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4490 const unsigned Num_GPR_Regs = std::size(GPR);
4492 const unsigned Num_VR_Regs = std::size(VR);
4500 bool HasParameterArea = !isELFv2ABI || isVarArg;
4501 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4502 unsigned NumBytes = LinkageSize;
4503 unsigned AvailableFPRs = Num_FPR_Regs;
4504 unsigned AvailableVRs = Num_VR_Regs;
4505 for (
const ISD::InputArg &In : Ins) {
4506 if (
In.Flags.isNest())
4510 LinkageSize, ParamAreaSize, NumBytes,
4511 AvailableFPRs, AvailableVRs))
4512 HasParameterArea =
true;
4519 unsigned ArgOffset = LinkageSize;
4520 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4523 unsigned CurArgIdx = 0;
4524 for (
unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) {
4526 bool needsLoad =
false;
4527 EVT ObjectVT = Ins[ArgNo].VT;
4528 EVT OrigVT = Ins[ArgNo].ArgVT;
4530 unsigned ArgSize = ObjSize;
4531 ISD::ArgFlagsTy
Flags = Ins[ArgNo].Flags;
4532 if (Ins[ArgNo].isOrigArg()) {
4533 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4534 CurArgIdx = Ins[ArgNo].getOrigArgIndex();
4539 unsigned CurArgOffset;
4541 auto ComputeArgOffset = [&]() {
4545 ArgOffset =
alignTo(ArgOffset, Alignment);
4546 CurArgOffset = ArgOffset;
4553 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4554 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4559 if (
Flags.isByVal()) {
4560 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4566 ObjSize =
Flags.getByValSize();
4567 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4589 if (HasParameterArea ||
4590 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4597 if (ObjSize < PtrByteSize) {
4601 if (!isLittleEndian) {
4607 if (GPR_idx != Num_GPR_Regs) {
4614 MachinePointerInfo(&*FuncArg), ObjType);
4619 ArgOffset += PtrByteSize;
4628 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4629 if (GPR_idx == Num_GPR_Regs)
4640 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4644 MachinePointerInfo(&*FuncArg, j), ObjType);
4648 ArgOffset += ArgSize;
4657 if (
Flags.isNest()) {
4662 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4663 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4671 if (GPR_idx != Num_GPR_Regs) {
4676 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4679 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4685 ArgSize = PtrByteSize;
4696 if (FPR_idx != Num_FPR_Regs) {
4699 if (ObjectVT == MVT::f32)
4701 Subtarget.hasP8Vector()
4702 ? &PPC::VSSRCRegClass
4703 : &PPC::F4RCRegClass);
4706 ? &PPC::VSFRCRegClass
4707 : &PPC::F8RCRegClass);
4722 if (ObjectVT == MVT::f32) {
4723 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4741 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4742 ArgOffset += ArgSize;
4743 if (
Flags.isInConsecutiveRegsLast())
4744 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4758 if (VR_idx != Num_VR_Regs) {
4775 if (ObjSize < ArgSize && !isLittleEndian)
4776 CurArgOffset += ArgSize - ObjSize;
4779 ArgVal = DAG.
getLoad(ObjectVT, dl, Chain, FIN, MachinePointerInfo());
4786 unsigned MinReservedArea;
4787 if (HasParameterArea)
4788 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4790 MinReservedArea = LinkageSize;
4807 int Depth = ArgOffset;
4816 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4817 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4829 if (!MemOps.
empty())
4838 unsigned ParamSize) {
4840 if (!isTailCall)
return 0;
4844 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4846 if (SPDiff < FI->getTailCallSPDelta())
4862 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4921 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
4924 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4936 const unsigned PtrByteSize = 8;
4937 const unsigned LinkageSize =
Subtarget.getFrameLowering()->getLinkageSize();
4940 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4941 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4944 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4945 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4948 const unsigned NumGPRs = std::size(GPR);
4949 const unsigned NumFPRs = 13;
4950 const unsigned NumVRs = std::size(VR);
4951 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4953 unsigned NumBytes = LinkageSize;
4954 unsigned AvailableFPRs = NumFPRs;
4955 unsigned AvailableVRs = NumVRs;
4958 if (Param.Flags.isNest())
continue;
4961 LinkageSize, ParamAreaSize, NumBytes,
4962 AvailableFPRs, AvailableVRs))
4973 auto CalleeArgEnd = CB.
arg_end();
4976 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
4977 const Value* CalleeArg = *CalleeArgIter;
4978 const Value* CallerArg = &(*CallerArgIter);
4979 if (CalleeArg == CallerArg)
5005 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
5015bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
5020 bool isCalleeExternalSymbol)
const {
5027 if (isVarArg)
return false;
5034 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5070 if (!Subtarget.isUsingPCRelativeCalls() &&
5075 if (!Subtarget.isUsingPCRelativeCalls() &&
5104bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5117 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5138 if (!
C)
return nullptr;
5140 int Addr =
C->getZExtValue();
5141 if ((Addr & 3) != 0 ||
5147 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5154struct TailCallArgumentInfo {
5159 TailCallArgumentInfo() =
default;
5169 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5170 SDValue Arg = TailCallArgs[i].Arg;
5171 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5172 int FI = TailCallArgs[i].FrameIdx;
5175 Chain, dl, Arg, FIN,
5184 int SPDiff,
const SDLoc &dl) {
5190 int SlotSize =
Subtarget.isPPC64() ? 8 : 4;
5191 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5193 NewRetAddrLoc,
true);
5196 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5206 int SPDiff,
unsigned ArgOffset,
5208 int Offset = ArgOffset + SPDiff;
5211 EVT VT = IsPPC64 ? MVT::i64 : MVT::i32;
5213 TailCallArgumentInfo Info;
5215 Info.FrameIdxOp = FIN;
5223SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5228 LROpOut = getReturnAddrFrameIndex(DAG);
5229 LROpOut = DAG.
getLoad(Subtarget.getScalarIntVT(), dl, Chain, LROpOut,
5230 MachinePointerInfo());
5246 Align Alignment = Flags.getNonZeroByValAlign();
5248 Chain, dl, Dst, Src, SizeNode, Alignment, Alignment,
false,
false,
5256 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5280 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5290 if (!MemOpChains2.
empty())
5314SDValue PPCTargetLowering::LowerCallResult(
5322 CCRetInfo.AnalyzeCallResult(
5328 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5329 CCValAssign &VA = RVLocs[i];
5334 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5344 if (!Subtarget.isLittleEndian())
5346 Val = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64,
Lo,
Hi);
5412 bool IsStrictFPCall =
false) {
5414 return PPCISD::TC_RETURN;
5416 unsigned RetOpc = 0;
5428 RetOpc = PPCISD::BL_LOAD_TOC;
5432 }
else if (
Subtarget.isUsingPCRelativeCalls()) {
5433 assert(
Subtarget.is64BitELFABI() &&
"PC Relative is only on ELF ABI.");
5434 RetOpc = PPCISD::CALL_NOTOC;
5449 RetOpc = PPCISD::CALL;
5450 if (IsStrictFPCall) {
5454 case PPCISD::BCTRL_LOAD_TOC:
5455 RetOpc = PPCISD::BCTRL_LOAD_TOC_RM;
5458 RetOpc = PPCISD::BCTRL_RM;
5460 case PPCISD::BL_LOAD_TOC:
5461 RetOpc = PPCISD::BL_LOAD_TOC_RM;
5463 case PPCISD::CALL_NOTOC:
5464 RetOpc = PPCISD::CALL_NOTOC_RM;
5467 RetOpc = PPCISD::CALL_RM;
5469 case PPCISD::CALL_NOP:
5470 RetOpc = PPCISD::CALL_NOP_RM;
5484 auto isLocalCallee = [&]() {
5497 Subtarget.is32BitELFABI() && !isLocalCallee() &&
5500 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5516 return getAIXFuncEntryPointSymbolSDNode(GV);
5523 const char *SymName = S->getSymbol();
5530 return getAIXFuncEntryPointSymbolSDNode(
F);
5536 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5544 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5551 assert(Callee.getNode() &&
"What no callee?");
5557 "Expected a CALLSEQ_STARTSDNode.");
5574 SDValue MTCTROps[] = {Chain, Callee, Glue};
5575 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5576 Chain = DAG.
getNode(PPCISD::MTCTR, dl, ReturnTypes,
5616 auto MMOFlags =
Subtarget.hasInvariantFunctionDescriptors()
5628 const unsigned TOCAnchorOffset =
Subtarget.descriptorTOCAnchorOffset();
5629 const unsigned EnvPtrOffset =
Subtarget.descriptorEnvironmentPointerOffset();
5635 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5636 Alignment, MMOFlags);
5643 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5650 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5662 "Nest parameter is not supported on AIX.");
5677 const SDLoc &dl,
bool hasNest,
5687 Chain = MoveToPhysicalReg.
getValue(0);
5688 Glue = MoveToPhysicalReg.
getValue(1);
5695 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5698 const bool IsPPC64 =
Subtarget.isPPC64();
5703 Ops.push_back(Chain);
5707 Ops.push_back(Callee);
5708 else if (
Subtarget.usePointerGlueHelper()) {
5709 Ops.push_back(Callee);
5729 unsigned TOCSaveOffset =
Subtarget.getFrameLowering()->getTOCSaveOffset();
5732 Ops.push_back(AddTOC);
5743 Ops.push_back(DAG.
getRegister(IsPPC64 ? PPC::CTR8 : PPC::CTR, RegVT));
5752 for (
const auto &[
Reg,
N] : RegsToPass)
5770 assert(Mask &&
"Missing call preserved mask for calling convention");
5775 Ops.push_back(Glue);
5778SDValue PPCTargetLowering::FinishCall(
5785 if ((Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls()) ||
5786 Subtarget.isAIXABI())
5793 if (!CFlags.IsIndirect)
5795 else if (Subtarget.usesFunctionDescriptors()) {
5796 if (Subtarget.usePointerGlueHelper()) {
5798 CFlags.HasNest, Subtarget);
5804 dl, CFlags.HasNest, Subtarget);
5816 if (CFlags.IsTailCall) {
5824 (CFlags.IsIndirect && Subtarget.isUsingPCRelativeCalls())) &&
5825 "Expecting a global address, external symbol, absolute value, "
5826 "register or an indirect tail call when PC Relative calls are "
5829 assert(CallOpc == PPCISD::TC_RETURN &&
5830 "Unexpected call opcode for a tail call.");
5837 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5838 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes,
Ops);
5850 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5853 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5873 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5874 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5878bool PPCTargetLowering::isEligibleForTCO(
5883 bool isCalleeExternalSymbol)
const {
5888 return IsEligibleForTailCallOptimization_64SVR4(
5889 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5890 isCalleeExternalSymbol);
5892 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5920 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5935 "Callee should be an llvm::Function object.");
5938 <<
"\nTCO callee: ");
5945 "site marked musttail");
5952 Callee = LowerGlobalAddress(Callee, DAG);
5955 CallConv, isTailCall, isVarArg, isPatchPoint,
5958 Subtarget.is64BitELFABI() &&
5962 if (Subtarget.isAIXABI())
5963 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5966 assert(Subtarget.isSVR4ABI());
5967 if (Subtarget.isPPC64())
5968 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5970 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5974SDValue PPCTargetLowering::LowerCall_32SVR4(
5985 const bool IsVarArg = CFlags.IsVarArg;
5986 const bool IsTailCall = CFlags.IsTailCall;
5992 const Align PtrAlign(4);
6003 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
6011 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.
getContext());
6014 CCInfo.AllocateStack(Subtarget.getFrameLowering()->getLinkageSize(),
6021 unsigned NumArgs = Outs.
size();
6023 for (
unsigned i = 0; i != NumArgs; ++i) {
6024 MVT ArgVT = Outs[i].VT;
6025 ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
6030 Outs[i].OrigTy, CCInfo);
6033 ArgFlags, Outs[i].OrigTy, CCInfo);
6038 errs() <<
"Call operand #" << i <<
" has unhandled type "
6051 CCState CCByValInfo(CallConv, IsVarArg, MF, ByValArgLocs, *DAG.
getContext());
6054 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
6061 unsigned NumBytes = CCByValInfo.getStackSize();
6075 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6086 bool seenFloatArg =
false;
6091 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
6093 ++i, ++RealArgIdx) {
6094 CCValAssign &VA = ArgLocs[i];
6095 SDValue Arg = OutVals[RealArgIdx];
6096 ISD::ArgFlagsTy
Flags = Outs[RealArgIdx].Flags;
6098 if (
Flags.isByVal()) {
6103 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
6104 CCValAssign &ByValVA = ByValArgLocs[
j++];
6126 Chain = CallSeqStart = NewCallSeqStart;
6145 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6146 bool IsLE = Subtarget.isLittleEndian();
6147 SDValue SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6150 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6152 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6167 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()));
6176 if (!MemOpChains.
empty())
6182 for (
const auto &[
Reg,
N] : RegsToPass) {
6190 SDVTList VTs = DAG.
getVTList(MVT::Other, MVT::Glue);
6193 Chain = DAG.
getNode(seenFloatArg ? PPCISD::CR6SET : PPCISD::CR6UNSET, dl,
6203 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6204 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6209SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6221 return NewCallSeqStart;
6224SDValue PPCTargetLowering::LowerCall_64SVR4(
6231 bool isELFv2ABI = Subtarget.isELFv2ABI();
6232 bool isLittleEndian = Subtarget.isLittleEndian();
6234 bool IsSibCall =
false;
6238 unsigned PtrByteSize = 8;
6251 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
6253 assert(!(IsFastCall && CFlags.IsVarArg) &&
6254 "fastcc not supported on varargs functions");
6260 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
6261 unsigned NumBytes = LinkageSize;
6262 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6265 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6266 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6269 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6270 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6273 const unsigned NumGPRs = std::size(GPR);
6275 const unsigned NumVRs = std::size(VR);
6281 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6282 if (!HasParameterArea) {
6283 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6284 unsigned AvailableFPRs = NumFPRs;
6285 unsigned AvailableVRs = NumVRs;
6286 unsigned NumBytesTmp = NumBytes;
6287 for (
unsigned i = 0; i !=
NumOps; ++i) {
6288 if (Outs[i].
Flags.isNest())
continue;
6290 PtrByteSize, LinkageSize, ParamAreaSize,
6291 NumBytesTmp, AvailableFPRs, AvailableVRs))
6292 HasParameterArea =
true;
6298 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6303 HasParameterArea =
false;
6306 for (
unsigned i = 0; i !=
NumOps; ++i) {
6307 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6308 EVT ArgVT = Outs[i].VT;
6309 EVT OrigVT = Outs[i].ArgVT;
6315 if (
Flags.isByVal()) {
6316 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6317 if (NumGPRsUsed > NumGPRs)
6318 HasParameterArea =
true;
6325 if (++NumGPRsUsed <= NumGPRs)
6335 if (++NumVRsUsed <= NumVRs)
6339 if (++NumVRsUsed <= NumVRs)
6344 if (++NumFPRsUsed <= NumFPRs)
6348 HasParameterArea =
true;
6355 NumBytes =
alignTo(NumBytes, Alignement);
6358 if (
Flags.isInConsecutiveRegsLast())
6359 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6362 unsigned NumBytesActuallyUsed = NumBytes;
6372 if (HasParameterArea)
6373 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6375 NumBytes = LinkageSize;
6390 if (CFlags.IsTailCall)
6402 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6413 unsigned ArgOffset = LinkageSize;
6419 for (
unsigned i = 0; i !=
NumOps; ++i) {
6421 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6422 EVT ArgVT = Outs[i].VT;
6423 EVT OrigVT = Outs[i].ArgVT;
6432 auto ComputePtrOff = [&]() {
6436 ArgOffset =
alignTo(ArgOffset, Alignment);
6447 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6448 GPR_idx = std::min(GPR_idx, NumGPRs);
6455 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6461 if (
Flags.isByVal()) {
6479 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6480 if (GPR_idx != NumGPRs) {
6482 MachinePointerInfo(), VT);
6486 ArgOffset += PtrByteSize;
6491 if (GPR_idx == NumGPRs &&
Size < 8) {
6493 if (!isLittleEndian) {
6498 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6501 ArgOffset += PtrByteSize;
6510 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6511 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6516 if (
Size < 8 && GPR_idx != NumGPRs) {
6526 if (!isLittleEndian) {
6530 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6536 DAG.
getLoad(PtrVT, dl, Chain, PtrOff, MachinePointerInfo());
6541 ArgOffset += PtrByteSize;
6547 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6550 if (GPR_idx != NumGPRs) {
6551 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6554 MachinePointerInfo(), ObjType);
6558 ArgOffset += PtrByteSize;
6560 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6572 if (
Flags.isNest()) {
6574 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6581 if (GPR_idx != NumGPRs) {
6582 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6587 assert(HasParameterArea &&
6588 "Parameter area must exist to pass an argument in memory.");
6590 true, CFlags.IsTailCall,
false, MemOpChains,
6591 TailCallArguments, dl);
6593 ArgOffset += PtrByteSize;
6596 ArgOffset += PtrByteSize;
6609 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6610 bool NeededLoad =
false;
6613 if (FPR_idx != NumFPRs)
6614 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6617 if (!NeedGPROrStack)
6619 else if (GPR_idx != NumGPRs && !IsFastCall) {
6633 }
else if (!
Flags.isInConsecutiveRegs()) {
6639 }
else if (ArgOffset % PtrByteSize != 0) {
6643 if (!isLittleEndian)
6648 }
else if (
Flags.isInConsecutiveRegsLast()) {
6651 if (!isLittleEndian)
6661 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6669 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6674 assert(HasParameterArea &&
6675 "Parameter area must exist to pass an argument in memory.");
6677 true, CFlags.IsTailCall,
false, MemOpChains,
6678 TailCallArguments, dl);
6685 if (!IsFastCall || NeededLoad) {
6687 Flags.isInConsecutiveRegs()) ? 4 : 8;
6688 if (
Flags.isInConsecutiveRegsLast())
6689 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6709 if (CFlags.IsVarArg) {
6710 assert(HasParameterArea &&
6711 "Parameter area must exist if we have a varargs call.");
6715 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
6717 if (VR_idx != NumVRs) {
6719 DAG.
getLoad(MVT::v4f32, dl,
Store, PtrOff, MachinePointerInfo());
6724 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6725 if (GPR_idx == NumGPRs)
6730 DAG.
getLoad(PtrVT, dl,
Store, Ix, MachinePointerInfo());
6738 if (VR_idx != NumVRs) {
6739 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6744 assert(HasParameterArea &&
6745 "Parameter area must exist to pass an argument in memory.");
6747 true, CFlags.IsTailCall,
true, MemOpChains,
6748 TailCallArguments, dl);
6759 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6760 "mismatch in size of parameter area");
6761 (void)NumBytesActuallyUsed;
6763 if (!MemOpChains.
empty())
6769 if (CFlags.IsIndirect) {
6773 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6778 unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
6788 if (isELFv2ABI && !CFlags.IsPatchPoint)
6789 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6795 for (
const auto &[
Reg,
N] : RegsToPass) {
6800 if (CFlags.IsTailCall && !IsSibCall)
6804 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6805 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6812 "Required alignment greater than stack alignment.");
6832 return RequiredAlign <= 8;
6837 return RequiredAlign <= 4;
6845 State.getMachineFunction().getSubtarget());
6846 const bool IsPPC64 =
Subtarget.isPPC64();
6847 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6848 const Align PtrAlign(PtrSize);
6849 const Align StackAlign(16);
6852 if (ValVT == MVT::f128)
6856 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6857 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6859 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6860 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6863 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6864 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6865 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6870 MCRegister EnvReg = State.AllocateReg(IsPPC64 ? PPC::X11 : PPC::R11);
6879 if (ByValAlign > StackAlign)
6881 "16 are not supported.");
6884 const Align ObjAlign = ByValAlign > PtrAlign ? ByValAlign : PtrAlign;
6888 if (ByValSize == 0) {
6890 State.getStackSize(), RegVT, LocInfo));
6895 unsigned NextReg = State.getFirstUnallocated(GPRs);
6896 while (NextReg != GPRs.
size() &&
6901 State.AllocateStack(PtrSize, PtrAlign);
6902 assert(
Reg &&
"Alocating register unexpectedly failed.");
6904 NextReg = State.getFirstUnallocated(GPRs);
6907 const unsigned StackSize =
alignTo(ByValSize, ObjAlign);
6908 unsigned Offset = State.AllocateStack(StackSize, ObjAlign);
6928 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6932 const unsigned Offset = State.AllocateStack(PtrSize, PtrAlign);
6951 State.AllocateStack(IsPPC64 ? 8 : StoreSize,
Align(4));
6957 for (
unsigned I = 0;
I < StoreSize;
I += PtrSize) {
6959 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
6960 if (State.isVarArg()) {
6992 const unsigned VecSize = 16;
6993 const Align VecAlign(VecSize);
6995 if (!State.isVarArg()) {
6998 if (
MCRegister VReg = State.AllocateReg(VR)) {
7005 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7010 unsigned NextRegIndex = State.getFirstUnallocated(GPRs);
7013 while (NextRegIndex != GPRs.
size() &&
7017 State.AllocateStack(PtrSize, PtrAlign);
7018 assert(
Reg &&
"Allocating register unexpectedly failed.");
7020 NextRegIndex = State.getFirstUnallocated(GPRs);
7028 if (
MCRegister VReg = State.AllocateReg(VR)) {
7031 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
7032 State.AllocateReg(GPRs);
7033 State.AllocateStack(VecSize, VecAlign);
7037 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7043 if (NextRegIndex == GPRs.
size()) {
7044 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7052 if (GPRs[NextRegIndex] == PPC::R9) {
7053 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7057 const MCRegister FirstReg = State.AllocateReg(PPC::R9);
7058 const MCRegister SecondReg = State.AllocateReg(PPC::R10);
7059 assert(FirstReg && SecondReg &&
7060 "Allocating R9 or R10 unexpectedly failed.");
7071 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7074 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
7076 assert(
Reg &&
"Failed to allocated register for vararg vector argument");
7091 assert((IsPPC64 || SVT != MVT::i64) &&
7092 "i64 should have been split for 32-bit codegen.");
7100 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7102 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
7104 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
7112 return &PPC::VRRCRegClass;
7125 else if (Flags.isZExt())
7137 "Reg must be a valid argument register!");
7138 return LASize + 4 * (
Reg - PPC::R3);
7143 "Reg must be a valid argument register!");
7144 return LASize + 8 * (
Reg - PPC::X3);
7190SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7197 "Unexpected calling convention!");
7205 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7207 const bool IsPPC64 = Subtarget.isPPC64();
7208 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7214 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
7215 CCState CCInfo(CallConv, isVarArg, MF, ArgLocs, *DAG.
getContext());
7219 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7220 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7221 uint64_t SaveStackPos = CCInfo.getStackSize();
7223 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7228 CCValAssign &VA = ArgLocs[
I++];
7233 EVT ArgVT = Ins[VA.
getValNo()].ArgVT;
7234 bool ArgSignExt = Ins[VA.
getValNo()].Flags.isSExt();
7246 LocVT.
SimpleTy, IsPPC64, Subtarget.hasP8Vector(), Subtarget.hasVSX());
7248 MVT SaveVT = RegClass == &PPC::G8RCRegClass ? MVT::i64 : LocVT;
7254 MachinePointerInfo(),
Align(PtrByteSize));
7260 unsigned StoreSize =
7262 SaveStackPos =
alignTo(SaveStackPos + StoreSize, PtrByteSize);
7265 auto HandleMemLoc = [&]() {
7268 assert((ValSize <= LocSize) &&
7269 "Object size is larger than size of MemLoc");
7272 if (LocSize > ValSize)
7273 CurArgOffset += LocSize - ValSize;
7275 const bool IsImmutable =
7281 DAG.
getLoad(ValVT, dl, Chain, FIN, MachinePointerInfo());
7315 assert(isVarArg &&
"Only use custom memloc for vararg.");
7318 const unsigned OriginalValNo = VA.
getValNo();
7319 (void)OriginalValNo;
7321 auto HandleCustomVecRegLoc = [&]() {
7322 assert(
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7323 "Missing custom RegLoc.");
7326 "Unexpected Val type for custom RegLoc.");
7328 "ValNo mismatch between custom MemLoc and RegLoc.");
7332 Subtarget.hasVSX()));
7339 HandleCustomVecRegLoc();
7340 HandleCustomVecRegLoc();
7344 if (
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7346 "Only 2 custom RegLocs expected for 64-bit codegen.");
7347 HandleCustomVecRegLoc();
7348 HandleCustomVecRegLoc();
7392 const unsigned Size =
7404 if (
Flags.isByVal()) {
7408 const PPCFrameLowering *FL = Subtarget.getFrameLowering();
7410 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7419 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7421 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7434 CopyFrom.
getValue(1), dl, CopyFrom,
7444 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7447 "RegLocs should be for ByVal argument.");
7449 const CCValAssign RL = ArgLocs[
I++];
7454 if (
Offset != StackSize) {
7456 "Expected MemLoc for remaining bytes.");
7457 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7471 Subtarget.hasVSX()));
7488 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7490 unsigned CallerReservedArea = std::max<unsigned>(
7491 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7497 CallerReservedArea =
7502 int VAListIndex = 0;
7506 if (CCInfo.getStackSize() < (LinkageSize + MinParameterSaveArea)) {
7507 unsigned FixedStackSize =
7508 LinkageSize + MinParameterSaveArea - CCInfo.getStackSize();
7524 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7525 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7527 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7528 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7529 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7535 GPRIndex = (CCInfo.getStackSize() - LinkageSize) / PtrByteSize,
7537 GPRIndex < NumGPArgRegs; ++GPRIndex,
Offset += PtrByteSize) {
7540 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7541 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7544 MachinePointerInfo MPI =
7554 if (!MemOps.
empty())
7560SDValue PPCTargetLowering::LowerCall_AIX(
7573 "Unexpected calling convention!");
7575 if (CFlags.IsPatchPoint)
7578 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7582 CCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7589 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7590 const bool IsPPC64 = Subtarget.isPPC64();
7592 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7593 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7594 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7602 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7603 const unsigned NumBytes = std::max<unsigned>(
7604 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7620 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E;) {
7621 const unsigned ValNo = ArgLocs[
I].getValNo();
7623 ISD::ArgFlagsTy
Flags = Outs[ValNo].Flags;
7625 if (
Flags.isByVal()) {
7626 const unsigned ByValSize =
Flags.getByValSize();
7634 auto GetLoad = [&](EVT VT,
unsigned LoadOffset) {
7640 MachinePointerInfo(), VT);
7643 unsigned LoadOffset = 0;
7646 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7649 LoadOffset += PtrByteSize;
7650 const CCValAssign &ByValVA = ArgLocs[
I++];
7652 "Unexpected location for pass-by-value argument.");
7656 if (LoadOffset == ByValSize)
7660 assert(ArgLocs[
I].getValNo() == ValNo &&
7661 "Expected additional location for by-value argument.");
7663 if (ArgLocs[
I].isMemLoc()) {
7664 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7665 const CCValAssign &ByValVA = ArgLocs[
I++];
7666 ISD::ArgFlagsTy MemcpyFlags =
Flags;
7669 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7675 CallSeqStart, MemcpyFlags, DAG, dl);
7684 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7685 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7686 "Unexpected register residue for by-value argument.");
7688 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7692 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7702 "Unexpected load emitted during handling of pass-by-value "
7710 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7715 const CCValAssign &ByValVA = ArgLocs[
I++];
7720 CCValAssign &VA = ArgLocs[
I++];
7745 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7751 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
7753 const unsigned OriginalValNo = VA.
getValNo();
7755 unsigned LoadOffset = 0;
7756 auto HandleCustomVecRegLoc = [&]() {
7757 assert(
I !=
E &&
"Unexpected end of CCvalAssigns.");
7758 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7759 "Expected custom RegLoc.");
7760 CCValAssign RegVA = ArgLocs[
I++];
7762 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7768 LoadOffset += PtrByteSize;
7774 HandleCustomVecRegLoc();
7775 HandleCustomVecRegLoc();
7777 if (
I !=
E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7778 ArgLocs[
I].getValNo() == OriginalValNo) {
7780 "Only 2 custom RegLocs expected for 64-bit codegen.");
7781 HandleCustomVecRegLoc();
7782 HandleCustomVecRegLoc();
7793 DAG.
getStore(Chain, dl, Arg, PtrOff,
7795 Subtarget.getFrameLowering()->getStackAlign()));
7802 "Unexpected register handling for calling convention.");
7808 "Custom register handling only expected for VarArg.");
7813 if (Arg.getValueType().getStoreSize() == LocVT.
getStoreSize())
7817 else if (Arg.getValueType().getFixedSizeInBits() <
7825 assert(Arg.getValueType() == MVT::f64 && CFlags.IsVarArg && !IsPPC64 &&
7826 "Unexpected custom register for argument!");
7827 CCValAssign &GPR1 = VA;
7836 CCValAssign &PeekArg = ArgLocs[
I];
7839 CCValAssign &GPR2 = ArgLocs[
I++];
7847 if (!MemOpChains.
empty())
7852 if (CFlags.IsIndirect && !Subtarget.usePointerGlueHelper()) {
7853 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7854 const MCRegister TOCBaseReg = Subtarget.getTOCPointerRegister();
7855 const MCRegister StackPtrReg = Subtarget.getStackPointerRegister();
7856 const MVT PtrVT = Subtarget.getScalarIntVT();
7857 const unsigned TOCSaveOffset =
7858 Subtarget.getFrameLowering()->getTOCSaveOffset();
7873 for (
auto Reg : RegsToPass) {
7878 const int SPDiff = 0;
7879 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7880 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7888 const Type *RetTy)
const {
7890 CCState CCInfo(CallConv, isVarArg, MF, RVLocs,
Context);
7891 return CCInfo.CheckReturn(
7906 CCInfo.AnalyzeReturn(Outs,
7915 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7916 CCValAssign &VA = RVLocs[i];
7919 SDValue Arg = OutVals[RealResIdx];
7934 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7935 bool isLittleEndian = Subtarget.isLittleEndian();
7938 DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7942 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7957 RetOps.push_back(Glue);
7959 return DAG.
getNode(PPCISD::RET_GLUE, dl, MVT::Other, RetOps);
7963PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7968 EVT IntVT =
Op.getValueType();
7972 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7976 return DAG.
getNode(PPCISD::DYNAREAOFFSET, dl, VTs,
Ops);
7988 bool isPPC64 = Subtarget.isPPC64();
7989 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7998 DAG.
getLoad(PtrVT, dl, Chain, StackPtr, MachinePointerInfo());
8004 return DAG.
getStore(Chain, dl, LoadLinkSP, StackPtr, MachinePointerInfo());
8009 bool isPPC64 = Subtarget.isPPC64();
8014 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
8020 int LROffset = Subtarget.getFrameLowering()->getReturnSaveOffset();
8030PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
8032 bool isPPC64 = Subtarget.isPPC64();
8037 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
8043 int FPOffset = Subtarget.getFrameLowering()->getFramePointerSaveOffset();
8066 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
8068 SDVTList VTs = DAG.
getVTList(PtrVT, MVT::Other);
8070 return DAG.
getNode(PPCISD::PROBED_ALLOCA, dl, VTs,
Ops);
8071 return DAG.
getNode(PPCISD::DYNALLOC, dl, VTs,
Ops);
8078 bool isPPC64 = Subtarget.isPPC64();
8088 return DAG.
getNode(PPCISD::EH_SJLJ_SETJMP,
DL,
8090 Op.getOperand(0),
Op.getOperand(1));
8096 return DAG.
getNode(PPCISD::EH_SJLJ_LONGJMP,
DL, MVT::Other,
8097 Op.getOperand(0),
Op.getOperand(1));
8101 if (
Op.getValueType().isVector())
8102 return LowerVectorLoad(
Op, DAG);
8104 assert(
Op.getValueType() == MVT::i1 &&
8105 "Custom lowering only for i1 loads");
8114 MachineMemOperand *MMO =
LD->getMemOperand();
8118 BasePtr, MVT::i8, MMO);
8126 if (
Op.getOperand(1).getValueType().isVector())
8127 return LowerVectorStore(
Op, DAG);
8129 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
8130 "Custom lowering only for i1 stores");
8140 MachineMemOperand *MMO =
ST->getMemOperand();
8149 assert(
Op.getValueType() == MVT::i1 &&
8150 "Custom lowering only for i1 results");
8178 EVT TrgVT =
Op.getValueType();
8202 if (SrcSize == 256) {
8213 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8219 SmallVector<int, 16> ShuffV;
8220 if (Subtarget.isLittleEndian())
8221 for (
unsigned i = 0; i < TrgNumElts; ++i)
8224 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8228 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8241 EVT ResVT =
Op.getValueType();
8242 EVT CmpVT =
Op.getOperand(0).getValueType();
8244 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8250 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8263 SDNodeFlags
Flags =
Op.getNode()->getFlags();
8267 if (Subtarget.hasP9Vector() &&
LHS == TV &&
RHS == FV) {
8284 if (!
Flags.hasNoInfs() || !
Flags.hasNoNaNs() || ResVT == MVT::f128)
8297 if (
LHS.getValueType() == MVT::f32)
8299 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8300 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8308 if (
LHS.getValueType() == MVT::f32)
8310 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8317 if (
LHS.getValueType() == MVT::f32)
8319 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8331 if (
Cmp.getValueType() == MVT::f32)
8333 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8334 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8339 if (
Cmp.getValueType() == MVT::f32)
8341 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8345 if (
Cmp.getValueType() == MVT::f32)
8347 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8351 if (
Cmp.getValueType() == MVT::f32)
8353 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8357 if (
Cmp.getValueType() == MVT::f32)
8359 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8368 case PPCISD::FCTIDZ:
8369 return PPCISD::STRICT_FCTIDZ;
8370 case PPCISD::FCTIWZ:
8371 return PPCISD::STRICT_FCTIWZ;
8372 case PPCISD::FCTIDUZ:
8373 return PPCISD::STRICT_FCTIDUZ;
8374 case PPCISD::FCTIWUZ:
8375 return PPCISD::STRICT_FCTIWUZ;
8377 return PPCISD::STRICT_FCFID;
8378 case PPCISD::FCFIDU:
8379 return PPCISD::STRICT_FCFIDU;
8380 case PPCISD::FCFIDS:
8381 return PPCISD::STRICT_FCFIDS;
8382 case PPCISD::FCFIDUS:
8383 return PPCISD::STRICT_FCFIDUS;
8390 bool IsStrict =
Op->isStrictFPOpcode();
8399 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8401 MVT DestTy =
Op.getSimpleValueType();
8402 assert(Src.getValueType().isFloatingPoint() &&
8403 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8404 DestTy == MVT::i64) &&
8405 "Invalid FP_TO_INT types");
8406 if (Src.getValueType() == MVT::f32) {
8410 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8415 if ((DestTy == MVT::i8 || DestTy == MVT::i16) &&
Subtarget.hasP9Vector())
8421 Opc = IsSigned ? PPCISD::FCTIWZ
8422 : (
Subtarget.hasFPCVT() ? PPCISD::FCTIWUZ : PPCISD::FCTIDZ);
8426 "i64 FP_TO_UINT is supported only with FPCVT");
8427 Opc = IsSigned ? PPCISD::FCTIDZ : PPCISD::FCTIDUZ;
8429 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8441void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8443 const SDLoc &dl)
const {
8447 bool IsStrict =
Op->isStrictFPOpcode();
8450 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8451 (IsSigned || Subtarget.hasFPCVT());
8454 MachinePointerInfo MPI =
8463 MachineMemOperand *MMO =
8469 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8473 if (
Op.getValueType() == MVT::i32 && !i32Stack &&
8474 !Subtarget.isLittleEndian()) {
8491 const SDLoc &dl)
const {
8494 if (
Op->isStrictFPOpcode())
8501 const SDLoc &dl)
const {
8502 bool IsStrict =
Op->isStrictFPOpcode();
8505 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8506 EVT SrcVT = Src.getValueType();
8507 EVT DstVT =
Op.getValueType();
8510 if (SrcVT == MVT::f128)
8511 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8515 if (SrcVT == MVT::ppcf128) {
8516 if (DstVT == MVT::i32) {
8521 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8532 {Op.getOperand(0), Lo, Hi}, Flags);
8535 {Res.getValue(1), Res}, Flags);
8541 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8565 {Chain, Src, FltOfs}, Flags);
8569 {Chain, Val}, Flags);
8572 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8590 if (Subtarget.hasDirectMove() && Subtarget.isPPC64())
8591 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8594 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8596 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8597 RLI.Alignment, RLI.MMOFlags(),
8598 MMOMetadata(RLI.AAInfo, RLI.Ranges));
8609bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8614 if (
Op->isStrictFPOpcode())
8619 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8623 Op.getOperand(0).getValueType())) {
8625 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8630 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8631 LD->isNonTemporal())
8633 if (
LD->getMemoryVT() != MemVT)
8643 RLI.Ptr =
LD->getBasePtr();
8644 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8646 "Non-pre-inc AM on PPC?");
8651 RLI.Chain =
LD->getChain();
8652 RLI.MPI =
LD->getPointerInfo();
8653 RLI.IsDereferenceable =
LD->isDereferenceable();
8654 RLI.IsInvariant =
LD->isInvariant();
8655 RLI.Alignment =
LD->getAlign();
8656 RLI.AAInfo =
LD->getAAInfo();
8657 RLI.Ranges =
LD->getRanges();
8659 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8666bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8667 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8674 if (!Subtarget.hasP9Vector() &&
8678 for (SDUse &Use : Origin->
uses()) {
8681 if (
Use.getResNo() != 0)
8708 bool IsSingle =
Op.getValueType() == MVT::f32 &&
Subtarget.hasFPCVT();
8709 unsigned ConvOpc = IsSingle ? (IsSigned ? PPCISD::FCFIDS : PPCISD::FCFIDUS)
8710 : (IsSigned ? PPCISD::FCFID : PPCISD::FCFIDU);
8711 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8712 if (
Op->isStrictFPOpcode()) {
8714 Chain =
Op.getOperand(0);
8716 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8718 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8726 const SDLoc &dl)
const {
8727 assert((
Op.getValueType() == MVT::f32 ||
8728 Op.getValueType() == MVT::f64) &&
8729 "Invalid floating point type as target of conversion");
8730 assert(Subtarget.hasFPCVT() &&
8731 "Int to FP conversions with direct moves require FPCVT");
8732 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8733 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8736 unsigned MovOpc = (WordInt && !
Signed) ? PPCISD::MTVSRZ : PPCISD::MTVSRA;
8755 for (
unsigned i = 1; i < NumConcat; ++i)
8762 const SDLoc &dl)
const {
8763 bool IsStrict =
Op->isStrictFPOpcode();
8764 unsigned Opc =
Op.getOpcode();
8765 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8768 "Unexpected conversion type");
8769 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8770 "Supports conversions to v2f64/v4f32 only.");
8774 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8777 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8782 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8784 SmallVector<int, 16> ShuffV;
8785 for (
unsigned i = 0; i < WideNumElts; ++i)
8788 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8789 int SaveElts = FourEltRes ? 4 : 2;
8790 if (Subtarget.isLittleEndian())
8791 for (
int i = 0; i < SaveElts; i++)
8792 ShuffV[i * Stride] = i;
8794 for (
int i = 1; i <= SaveElts; i++)
8795 ShuffV[i * Stride - 1] = i - 1;
8803 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8804 EVT ExtVT = Src.getValueType();
8805 if (Subtarget.hasP9Altivec())
8816 {Op.getOperand(0), Extend}, Flags);
8818 return DAG.
getNode(
Opc, dl,
Op.getValueType(), Extend);
8826 bool IsStrict =
Op->isStrictFPOpcode();
8827 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8832 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8834 EVT InVT = Src.getValueType();
8835 EVT OutVT =
Op.getValueType();
8838 return LowerINT_TO_FPVector(
Op, DAG, dl);
8841 if (
Op.getValueType() == MVT::f128)
8842 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8845 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8848 if (Src.getValueType() == MVT::i1) {
8860 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8861 Subtarget.isPPC64() && Subtarget.hasFPCVT())
8862 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8864 assert((IsSigned || Subtarget.hasFPCVT()) &&
8865 "UINT_TO_FP is supported only with FPCVT");
8867 if (Src.getValueType() == MVT::i64) {
8882 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT() &&
8883 !
Op->getFlags().hasApproximateFuncs()) {
8923 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8927 DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI, RLI.Alignment,
8928 RLI.MMOFlags(), MMOMetadata(RLI.AAInfo));
8931 }
else if (Subtarget.hasLFIWAX() &&
8932 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8935 MMOMetadata(RLI.AAInfo, RLI.Ranges));
8939 Ops, MVT::i32, MMO);
8942 }
else if (Subtarget.hasFPCVT() &&
8943 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8946 MMOMetadata(RLI.AAInfo, RLI.Ranges));
8950 Ops, MVT::i32, MMO);
8953 }
else if (((Subtarget.hasLFIWAX() &&
8955 (Subtarget.hasFPCVT() &&
8970 "Expected an i32 store");
8976 RLI.Alignment =
Align(4);
8980 MMOMetadata(RLI.AAInfo, RLI.Ranges));
8983 PPCISD::LFIWZX : PPCISD::LFIWAX,
8984 dl, DAG.
getVTList(MVT::f64, MVT::Other),
8985 Ops, MVT::i32, MMO);
8986 Chain =
Bits.getValue(1);
8994 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8998 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)},
9007 assert(Src.getValueType() == MVT::i32 &&
9008 "Unhandled INT_TO_FP type in custom expander!");
9018 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
9021 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
9031 "Expected an i32 store");
9037 RLI.Alignment =
Align(4);
9042 MMOMetadata(RLI.AAInfo, RLI.Ranges));
9047 Chain = Ld.getValue(1);
9048 if (ReusingLoad && RLI.ResChain) {
9052 assert(Subtarget.isPPC64() &&
9053 "i32->FP without LFIWAX supported only on PPC64");
9062 Chain, dl, Ext64, FIdx,
9068 MVT::f64, dl, Chain, FIdx,
9070 Chain = Ld.getValue(1);
9077 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
9081 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)}, Flags);
9099 assert(
Mode < 4 &&
"Unsupported rounding mode!");
9100 unsigned InternalRnd =
Mode ^ (~(
Mode >> 1) & 1);
9101 if (Subtarget.isISA3_0())
9104 PPC::MFFSCRNI, Dl, {MVT::f64, MVT::Other},
9105 {DAG.getConstant(InternalRnd, Dl, MVT::i32, true), Chain}),
9108 (InternalRnd & 2) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9109 {DAG.
getConstant(30, Dl, MVT::i32,
true), Chain});
9111 (InternalRnd & 1) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9129 if (!Subtarget.isISA3_0()) {
9130 MFFS = DAG.
getNode(PPCISD::MFFS, Dl, {MVT::f64, MVT::Other}, Chain);
9134 if (Subtarget.isPPC64()) {
9135 if (Subtarget.isISA3_0()) {
9140 PPC::RLDIMI, Dl, MVT::i64,
9145 NewFPSCR =
SDValue(InsertRN, 0);
9152 SDValue Addr = Subtarget.isLittleEndian()
9156 if (Subtarget.isISA3_0()) {
9157 Chain = DAG.
getStore(Chain, Dl, DstFlag, Addr, MachinePointerInfo());
9159 Chain = DAG.
getStore(Chain, Dl, MFFS, StackSlot, MachinePointerInfo());
9161 DAG.
getLoad(MVT::i32, Dl, Chain, Addr, MachinePointerInfo());
9164 PPC::RLWIMI, Dl, MVT::i32,
9165 {Tmp, DstFlag, DAG.getTargetConstant(0, Dl, MVT::i32),
9166 DAG.getTargetConstant(30, Dl, MVT::i32),
9167 DAG.getTargetConstant(31, Dl, MVT::i32)}),
9169 Chain = DAG.
getStore(Chain, Dl, Tmp, Addr, MachinePointerInfo());
9172 DAG.
getLoad(MVT::f64, Dl, Chain, StackSlot, MachinePointerInfo());
9175 if (Subtarget.isISA3_0())
9181 PPC::MTFSF, Dl, MVT::Other,
9209 EVT VT =
Op.getValueType();
9214 SDValue MFFS = DAG.
getNode(PPCISD::MFFS, dl, {MVT::f64, MVT::Other}, Chain);
9225 Chain = DAG.
getStore(Chain, dl, MFFS, StackSlot, MachinePointerInfo());
9229 "Stack slot adjustment is valid only on big endian subtargets!");
9232 CWD = DAG.
getLoad(MVT::i32, dl, Chain, Addr, MachinePointerInfo());
9259 EVT VT =
Op.getValueType();
9263 VT ==
Op.getOperand(1).getValueType() &&
9283 SDValue OutOps[] = { OutLo, OutHi };
9288 EVT VT =
Op.getValueType();
9292 VT ==
Op.getOperand(1).getValueType() &&
9312 SDValue OutOps[] = { OutLo, OutHi };
9318 EVT VT =
Op.getValueType();
9321 VT ==
Op.getOperand(1).getValueType() &&
9341 SDValue OutOps[] = { OutLo, OutHi };
9348 EVT VT =
Op.getValueType();
9355 EVT AmtVT =
Z.getValueType();
9365 X = DAG.
getNode(PPCISD::SHL, dl, VT,
X, IsFSHL ? Z : SubZ);
9366 Y = DAG.
getNode(PPCISD::SRL, dl, VT,
Y, IsFSHL ? SubZ : Z);
9378 static const MVT VTys[] = {
9379 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9382 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9385 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9390 EVT CanonicalVT = VTys[SplatSize-1];
9403 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9404 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9413 EVT DestVT = MVT::Other) {
9414 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9423 EVT DestVT = MVT::Other) {
9426 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9438 for (
unsigned i = 0; i != 16; ++i)
9459 EVT VecVT =
V->getValueType(0);
9460 bool RightType = VecVT == MVT::v2f64 ||
9461 (HasP8Vector && VecVT == MVT::v4f32) ||
9462 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9466 bool IsSplat =
true;
9467 bool IsLoad =
false;
9473 if (
V->isConstant())
9475 for (
int i = 0, e =
V->getNumOperands(); i < e; ++i) {
9476 if (
V->getOperand(i).isUndef())
9480 if (
V->getOperand(i).getOpcode() ==
ISD::LOAD ||
9482 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9484 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9486 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD))
9490 if (
V->getOperand(i) != Op0 ||
9491 (!IsLoad && !
V->isOnlyUserOf(
V->getOperand(i).getNode())))
9494 return !(IsSplat && IsLoad);
9504 (
Op.getValueType() != MVT::f128))
9509 if ((
Lo.getValueType() != MVT::i64) || (
Hi.getValueType() != MVT::i64))
9512 if (!Subtarget.isLittleEndian())
9515 return DAG.
getNode(PPCISD::BUILD_FP128, dl, MVT::f128,
Lo,
Hi);
9529 InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED) {
9532 IsPermuted = InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED;
9545 APFloat APFloatToConvert = ArgAPFloat;
9546 bool LosesInfo =
true;
9551 ArgAPFloat = APFloatToConvert;
9573 APFloat APFloatToConvert = ArgAPFloat;
9574 bool LosesInfo =
true;
9578 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9587 EVT Ty =
Op->getValueType(0);
9590 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9599 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9603 if (Ty == MVT::v2i64) {
9606 if (MemVT == MVT::i32) {
9608 Opcode = PPCISD::ZEXT_LD_SPLAT;
9610 Opcode = PPCISD::SEXT_LD_SPLAT;
9618 bool IsLittleEndian) {
9624 APInt ConstValue(VTSize, 0);
9628 unsigned BitPos = 0;
9636 ConstValue.
insertBits(CN->getAPIntValue().zextOrTrunc(EltWidth),
9637 IsLittleEndian ? BitPos : VTSize - EltWidth - BitPos);
9641 for (
unsigned J = 0; J < 16; ++J) {
9643 if (ExtractValue != 0x00 && ExtractValue != 0xFF)
9645 if (ExtractValue == 0xFF)
9660 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9662 if (Subtarget.hasP10Vector()) {
9663 APInt BitMask(32, 0);
9669 BitMask != 0 && BitMask != 0xffff) {
9671 MachineSDNode *MSDNode =
9683 if (
SDValue VecPat = combineBVLoadsSpecialValue(
Op, DAG))
9687 APInt APSplatBits, APSplatUndef;
9688 unsigned SplatBitSize = 0;
9690 bool BVNIsConstantSplat =
9692 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
9698 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9699 Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
9702 if ((
Op->getValueType(0) == MVT::v2f64) &&
9705 PPCISD::XXSPLTI_SP_TO_DP, dl, MVT::v2f64,
9721 PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9727 DAG.
getNode(PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9736 LowerVecSplatSmallFP(
Op, DAG, BVNIsConstantSplat, SplatBitSize))
9739 bool IsSplat64 =
false;
9741 int32_t SextVal = 0;
9742 if (BVNIsConstantSplat && SplatBitSize <= 64) {
9744 if (SplatBitSize <= 32) {
9746 }
else if (SplatBitSize == 64 && Subtarget.hasP8Altivec()) {
9747 int64_t Splat64Val =
static_cast<int64_t
>(SplatBits);
9748 bool P9Vector = Subtarget.hasP9Vector();
9749 int32_t
Hi = P9Vector ? 127 : 15;
9750 int32_t
Lo = P9Vector ? -128 : -16;
9751 IsSplat64 = Splat64Val >=
Lo && Splat64Val <=
Hi;
9752 SextVal =
static_cast<int32_t
>(SplatBits);
9756 if (!BVNIsConstantSplat || (SplatBitSize > 32 && !IsSplat64)) {
9757 unsigned NewOpcode = PPCISD::LD_SPLAT;
9763 const SDValue *InputLoad = &
Op.getOperand(0);
9768 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9769 unsigned ElementSize =
9770 MemorySize * ((NewOpcode == PPCISD::LD_SPLAT) ? 1 : 2);
9772 assert(((ElementSize == 2 * MemorySize)
9773 ? (NewOpcode == PPCISD::ZEXT_LD_SPLAT ||
9774 NewOpcode == PPCISD::SEXT_LD_SPLAT)
9775 : (NewOpcode == PPCISD::LD_SPLAT)) &&
9776 "Unmatched element size and opcode!\n");
9781 unsigned NumUsesOfInputLD = 128 / ElementSize;
9783 if (BVInOp.isUndef())
9798 if (NumUsesOfInputLD == 1 &&
9799 (
Op->getValueType(0) == MVT::v2i64 && NewOpcode != PPCISD::LD_SPLAT &&
9800 !Subtarget.isLittleEndian() && Subtarget.hasVSX() &&
9801 Subtarget.hasLFIWAX()))
9809 if (NumUsesOfInputLD == 1 && Subtarget.isLittleEndian() &&
9810 Subtarget.isISA3_1() && ElementSize <= 16)
9813 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9815 Subtarget.hasVSX()) {
9822 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other),
Ops,
9823 LD->getMemoryVT(),
LD->getMemOperand());
9835 if (Subtarget.hasVSX() && Subtarget.isPPC64() &&
9837 Subtarget.hasP8Vector()))
9843 unsigned SplatSize = SplatBitSize / 8;
9848 if (SplatBits == 0) {
9850 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9862 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 2)
9864 Op.getValueType(), DAG, dl);
9866 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 4)
9871 if (Subtarget.hasP9Vector() && SplatSize == 1)
9877 if (SextVal >= -16 && SextVal <= 15) {
9880 unsigned UseSize = SplatSize == 8 ? 4 : SplatSize;
9887 DAG.
getBitcast(MVT::v4i32, Res), DAG, dl, MVT::v2i64);
9893 if (Subtarget.hasP9Vector() && SextVal >= -128 && SextVal <= 127) {
9899 switch (SplatSize) {
9903 IID = Intrinsic::ppc_altivec_vupklsb;
9907 IID = Intrinsic::ppc_altivec_vextsb2w;
9911 IID = Intrinsic::ppc_altivec_vextsb2d;
9918 assert(!IsSplat64 &&
"Unhandled 64-bit splat pattern");
9927 if (SextVal >= -32 && SextVal <= 31) {
9932 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9933 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9936 if (VT ==
Op.getValueType())
9945 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9959 static const signed char SplatCsts[] = {
9960 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9961 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9964 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9967 int i = SplatCsts[idx];
9971 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9974 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9976 static const unsigned IIDs[] = {
9977 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9978 Intrinsic::ppc_altivec_vslw
9985 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9987 static const unsigned IIDs[] = {
9988 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9989 Intrinsic::ppc_altivec_vsrw
9996 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9997 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9999 static const unsigned IIDs[] = {
10000 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
10001 Intrinsic::ppc_altivec_vrlw
10008 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
10010 unsigned Amt = Subtarget.isLittleEndian() ? 15 : 1;
10014 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
10016 unsigned Amt = Subtarget.isLittleEndian() ? 14 : 2;
10020 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
10022 unsigned Amt = Subtarget.isLittleEndian() ? 13 : 3;
10035 unsigned OpNum = (PFEntry >> 26) & 0x0F;
10036 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
10037 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
10053 if (LHSID == (1*9+2)*9+3)
return LHS;
10054 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
10066 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
10067 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
10068 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
10069 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
10072 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
10073 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
10074 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
10075 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
10078 for (
unsigned i = 0; i != 16; ++i)
10079 ShufIdxs[i] = (i&3)+0;
10082 for (
unsigned i = 0; i != 16; ++i)
10083 ShufIdxs[i] = (i&3)+4;
10086 for (
unsigned i = 0; i != 16; ++i)
10087 ShufIdxs[i] = (i&3)+8;
10090 for (
unsigned i = 0; i != 16; ++i)
10091 ShufIdxs[i] = (i&3)+12;
10112 const unsigned BytesInVector = 16;
10113 bool IsLE = Subtarget.isLittleEndian();
10117 unsigned ShiftElts = 0, InsertAtByte = 0;
10121 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
10122 0, 15, 14, 13, 12, 11, 10, 9};
10123 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
10124 1, 2, 3, 4, 5, 6, 7, 8};
10126 ArrayRef<int>
Mask =
N->getMask();
10127 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
10139 bool FoundCandidate =
false;
10143 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
10146 for (
unsigned i = 0; i < BytesInVector; ++i) {
10147 unsigned CurrentElement =
Mask[i];
10150 if (V2.
isUndef() && CurrentElement != VINSERTBSrcElem)
10153 bool OtherElementsInOrder =
true;
10156 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
10163 (!V2.
isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
10164 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
10165 OtherElementsInOrder =
false;
10172 if (OtherElementsInOrder) {
10179 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
10180 : BigEndianShifts[CurrentElement & 0xF];
10181 Swap = CurrentElement < BytesInVector;
10183 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
10184 FoundCandidate =
true;
10189 if (!FoundCandidate)
10199 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10201 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8,
V1, Shl,
10204 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8,
V1, V2,
10213 const unsigned NumHalfWords = 8;
10214 const unsigned BytesInVector = NumHalfWords * 2;
10219 bool IsLE = Subtarget.isLittleEndian();
10223 unsigned ShiftElts = 0, InsertAtByte = 0;
10227 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
10228 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
10231 uint32_t OriginalOrderLow = 0x1234567;
10232 uint32_t OriginalOrderHigh = 0x89ABCDEF;
10235 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10236 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10253 bool FoundCandidate =
false;
10256 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10257 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10259 uint32_t MaskOtherElts = ~(0xF <<
MaskShift);
10260 uint32_t TargetOrder = 0x0;
10267 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
10268 TargetOrder = OriginalOrderLow;
10272 if (MaskOneElt == VINSERTHSrcElem &&
10273 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10274 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10275 FoundCandidate =
true;
10281 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
10283 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10285 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
10286 : BigEndianShifts[MaskOneElt & 0x7];
10287 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10288 Swap = MaskOneElt < NumHalfWords;
10289 FoundCandidate =
true;
10295 if (!FoundCandidate)
10307 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10310 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
10315 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
10330 auto ShuffleMask = SVN->
getMask();
10345 ShuffleMask = CommutedSV->
getMask();
10354 APInt APSplatValue, APSplatUndef;
10355 unsigned SplatBitSize;
10358 HasAnyUndefs, 0, !Subtarget.isLittleEndian()) ||
10370 bool IsLE = Subtarget.isLittleEndian();
10371 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
10372 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
10373 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
10375 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
10376 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
10377 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
10385 for (; SplatBitSize < 32; SplatBitSize <<= 1)
10386 SplatVal |= (SplatVal << SplatBitSize);
10389 PPCISD::XXSPLTI32DX,
DL, MVT::v2i64, DAG.
getBitcast(MVT::v2i64,
LHS),
10400 assert(
Op.getValueType() == MVT::v1i128 &&
10401 "Only set v1i128 as custom, other type shouldn't reach here!");
10406 if (SHLAmt % 8 == 0) {
10407 std::array<int, 16>
Mask;
10408 std::iota(
Mask.begin(),
Mask.end(), 0);
10409 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10438 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10443 V1 =
Op.getOperand(0);
10444 V2 =
Op.getOperand(1);
10446 EVT VT =
Op.getValueType();
10447 bool isLittleEndian = Subtarget.isLittleEndian();
10449 unsigned ShiftElts, InsertAtByte;
10457 bool IsPermutedLoad =
false;
10459 if (InputLoad && Subtarget.hasVSX() && V2.
isUndef() &&
10468 if (IsPermutedLoad) {
10469 assert((isLittleEndian || IsFourByte) &&
10470 "Unexpected size for permuted load on big endian target");
10471 SplatIdx += IsFourByte ? 2 : 1;
10472 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10473 "Splat of a value outside of the loaded memory");
10478 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10481 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10483 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10487 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10500 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10503 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10512 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10515 if (Subtarget.hasP9Vector() &&
10525 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv2, Conv2,
10527 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Shl,
10531 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Conv2,
10536 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
10538 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10539 return SplatInsertNode;
10542 if (Subtarget.hasP9Altivec()) {
10544 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10547 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10551 if (Subtarget.hasVSX() &&
10559 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv1, Conv2,
10564 if (Subtarget.hasVSX() &&
10572 SDValue PermDI = DAG.
getNode(PPCISD::XXPERMDI, dl, MVT::v2i64, Conv1, Conv2,
10577 if (Subtarget.hasP9Vector()) {
10597 if (Subtarget.hasVSX()) {
10618 if (V2.isUndef()) {
10631 (Subtarget.hasP8Altivec() && (
10642 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10652 (Subtarget.hasP8Altivec() && (
10660 ArrayRef<int> PermMask = SVOp->
getMask();
10663 unsigned PFIndexes[4];
10664 bool isFourElementShuffle =
true;
10665 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10667 unsigned EltNo = 8;
10668 for (
unsigned j = 0;
j != 4; ++
j) {
10669 if (PermMask[i * 4 + j] < 0)
10672 unsigned ByteSource = PermMask[i * 4 +
j];
10673 if ((ByteSource & 3) != j) {
10674 isFourElementShuffle =
false;
10679 EltNo = ByteSource / 4;
10680 }
else if (EltNo != ByteSource / 4) {
10681 isFourElementShuffle =
false;
10685 PFIndexes[i] = EltNo;
10693 if (isFourElementShuffle) {
10695 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10696 PFIndexes[2] * 9 + PFIndexes[3];
10699 unsigned Cost = (PFEntry >> 30);
10719 if (V2.isUndef()) V2 =
V1;
10721 return LowerVPERM(
Op, DAG, PermMask, VT,
V1, V2);
10727 unsigned Opcode = PPCISD::VPERM;
10730 bool NeedSwap =
false;
10731 bool isLittleEndian = Subtarget.isLittleEndian();
10732 bool isPPC64 = Subtarget.isPPC64();
10734 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10736 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10737 "XXPERM instead\n");
10738 Opcode = PPCISD::XXPERM;
10743 if ((!isLittleEndian && !V2->
hasOneUse() &&
V1->hasOneUse()) ||
10744 (isLittleEndian && !
V1->hasOneUse() && V2->
hasOneUse())) {
10746 NeedSwap = !NeedSwap;
10760 bool V1HasXXSWAPD =
V1->getOperand(0)->getOpcode() == PPCISD::XXSWAPD;
10781 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10783 if (V1HasXXSWAPD) {
10786 else if (SrcElt < 16)
10789 if (V2HasXXSWAPD) {
10792 else if (SrcElt > 15)
10801 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10802 if (isLittleEndian)
10804 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10807 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10810 if (V1HasXXSWAPD) {
10811 dl = SDLoc(
V1->getOperand(0));
10812 V1 =
V1->getOperand(0)->getOperand(1);
10814 if (V2HasXXSWAPD) {
10819 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10820 if (ValType != MVT::v2f64)
10826 ShufflesHandledWithVPERM++;
10830 if (Opcode == PPCISD::XXPERM) {
10831 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10833 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10836 dbgs() <<
"With the following permute control vector:\n";
10840 if (Opcode == PPCISD::XXPERM)
10841 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10845 if (isLittleEndian)
10849 DAG.
getNode(Opcode, dl,
V1.getValueType(),
V1, V2, VPermMask);
10851 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10863 switch (IntrinsicID) {
10867 case Intrinsic::ppc_altivec_vcmpbfp_p:
10871 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10875 case Intrinsic::ppc_altivec_vcmpequb_p:
10879 case Intrinsic::ppc_altivec_vcmpequh_p:
10883 case Intrinsic::ppc_altivec_vcmpequw_p:
10887 case Intrinsic::ppc_altivec_vcmpequd_p:
10894 case Intrinsic::ppc_altivec_vcmpneb_p:
10895 case Intrinsic::ppc_altivec_vcmpneh_p:
10896 case Intrinsic::ppc_altivec_vcmpnew_p:
10897 case Intrinsic::ppc_altivec_vcmpnezb_p:
10898 case Intrinsic::ppc_altivec_vcmpnezh_p:
10899 case Intrinsic::ppc_altivec_vcmpnezw_p:
10901 switch (IntrinsicID) {
10904 case Intrinsic::ppc_altivec_vcmpneb_p:
10907 case Intrinsic::ppc_altivec_vcmpneh_p:
10910 case Intrinsic::ppc_altivec_vcmpnew_p:
10913 case Intrinsic::ppc_altivec_vcmpnezb_p:
10916 case Intrinsic::ppc_altivec_vcmpnezh_p:
10919 case Intrinsic::ppc_altivec_vcmpnezw_p:
10927 case Intrinsic::ppc_altivec_vcmpgefp_p:
10931 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10935 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10939 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10943 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10947 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10954 case Intrinsic::ppc_altivec_vcmpgtub_p:
10958 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10962 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10966 case Intrinsic::ppc_altivec_vcmpgtud_p:
10974 case Intrinsic::ppc_altivec_vcmpequq:
10975 case Intrinsic::ppc_altivec_vcmpgtsq:
10976 case Intrinsic::ppc_altivec_vcmpgtuq:
10979 switch (IntrinsicID) {
10982 case Intrinsic::ppc_altivec_vcmpequq:
10985 case Intrinsic::ppc_altivec_vcmpgtsq:
10988 case Intrinsic::ppc_altivec_vcmpgtuq:
10995 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10996 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10997 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10998 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10999 case Intrinsic::ppc_vsx_xvcmpgesp_p:
11000 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
11002 switch (IntrinsicID) {
11003 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
11006 case Intrinsic::ppc_vsx_xvcmpgedp_p:
11009 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
11012 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
11015 case Intrinsic::ppc_vsx_xvcmpgesp_p:
11018 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
11028 case Intrinsic::ppc_altivec_vcmpbfp:
11031 case Intrinsic::ppc_altivec_vcmpeqfp:
11034 case Intrinsic::ppc_altivec_vcmpequb:
11037 case Intrinsic::ppc_altivec_vcmpequh:
11040 case Intrinsic::ppc_altivec_vcmpequw:
11043 case Intrinsic::ppc_altivec_vcmpequd:
11049 case Intrinsic::ppc_altivec_vcmpneb:
11050 case Intrinsic::ppc_altivec_vcmpneh:
11051 case Intrinsic::ppc_altivec_vcmpnew:
11052 case Intrinsic::ppc_altivec_vcmpnezb:
11053 case Intrinsic::ppc_altivec_vcmpnezh:
11054 case Intrinsic::ppc_altivec_vcmpnezw:
11056 switch (IntrinsicID) {
11059 case Intrinsic::ppc_altivec_vcmpneb:
11062 case Intrinsic::ppc_altivec_vcmpneh:
11065 case Intrinsic::ppc_altivec_vcmpnew:
11068 case Intrinsic::ppc_altivec_vcmpnezb:
11071 case Intrinsic::ppc_altivec_vcmpnezh:
11074 case Intrinsic::ppc_altivec_vcmpnezw:
11081 case Intrinsic::ppc_altivec_vcmpgefp:
11084 case Intrinsic::ppc_altivec_vcmpgtfp:
11087 case Intrinsic::ppc_altivec_vcmpgtsb:
11090 case Intrinsic::ppc_altivec_vcmpgtsh:
11093 case Intrinsic::ppc_altivec_vcmpgtsw:
11096 case Intrinsic::ppc_altivec_vcmpgtsd:
11102 case Intrinsic::ppc_altivec_vcmpgtub:
11105 case Intrinsic::ppc_altivec_vcmpgtuh:
11108 case Intrinsic::ppc_altivec_vcmpgtuw:
11111 case Intrinsic::ppc_altivec_vcmpgtud:
11117 case Intrinsic::ppc_altivec_vcmpequq_p:
11118 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11119 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11122 switch (IntrinsicID) {
11125 case Intrinsic::ppc_altivec_vcmpequq_p:
11128 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11131 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11145 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
11151 auto MapNodeWithSplatVector =
11152 [&](
unsigned Opcode,
11153 std::initializer_list<SDValue> ExtraOps = {}) ->
SDValue {
11158 Ops.append(ExtraOps.begin(), ExtraOps.end());
11159 return DAG.
getNode(Opcode, dl, MVT::v16i8,
Ops);
11162 switch (IntrinsicID) {
11163 case Intrinsic::thread_pointer:
11165 if (Subtarget.isPPC64())
11169 case Intrinsic::ppc_rldimi: {
11170 assert(Subtarget.isPPC64() &&
"rldimi is only available in 64-bit!");
11172 APInt
Mask =
Op.getConstantOperandAPInt(4);
11174 return Op.getOperand(2);
11175 if (
Mask.isAllOnes())
11178 unsigned MB = 0, ME = 0;
11182 if (ME < 63 - SH) {
11185 }
else if (ME > 63 - SH) {
11191 {Op.getOperand(2), Src,
11192 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
11193 DAG.getTargetConstant(MB, dl, MVT::i32)}),
11197 case Intrinsic::ppc_rlwimi: {
11198 APInt
Mask =
Op.getConstantOperandAPInt(4);
11200 return Op.getOperand(2);
11201 if (
Mask.isAllOnes())
11204 unsigned MB = 0, ME = 0;
11208 PPC::RLWIMI, dl, MVT::i32,
11209 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
11210 DAG.getTargetConstant(MB, dl, MVT::i32),
11211 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11215 case Intrinsic::ppc_bcdshift:
11216 return MapNodeWithSplatVector(PPCISD::BCDSHIFT, {
Op.getOperand(3)});
11217 case Intrinsic::ppc_bcdshiftround:
11218 return MapNodeWithSplatVector(PPCISD::BCDSHIFTROUND, {
Op.getOperand(3)});
11219 case Intrinsic::ppc_bcdtruncate:
11220 return MapNodeWithSplatVector(PPCISD::BCDTRUNC, {
Op.getOperand(3)});
11221 case Intrinsic::ppc_bcdunsignedtruncate:
11222 return MapNodeWithSplatVector(PPCISD::BCDUTRUNC);
11223 case Intrinsic::ppc_bcdunsignedshift:
11224 return MapNodeWithSplatVector(PPCISD::BCDUSHIFT);
11226 case Intrinsic::ppc_rlwnm: {
11227 if (
Op.getConstantOperandVal(3) == 0)
11229 unsigned MB = 0, ME = 0;
11234 {Op.getOperand(1), Op.getOperand(2),
11235 DAG.getTargetConstant(MB, dl, MVT::i32),
11236 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11240 case Intrinsic::ppc_mma_disassemble_acc: {
11241 if (Subtarget.isISAFuture()) {
11242 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11253 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11254 Subtarget.isLittleEndian() ? Value2 :
Value,
11255 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11259 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11260 Subtarget.isLittleEndian() ? Value2 :
Value,
11261 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11265 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11266 Subtarget.isLittleEndian() ?
Value : Value2,
11267 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11271 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11272 Subtarget.isLittleEndian() ?
Value : Value2,
11273 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11280 case Intrinsic::ppc_vsx_disassemble_pair: {
11283 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
11285 WideVec = DAG.
getNode(PPCISD::XXMFACC, dl, MVT::v512i1, WideVec);
11288 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
11290 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8, WideVec,
11291 DAG.
getConstant(Subtarget.isLittleEndian() ? NumVecs - 1 - VecNo
11299 case Intrinsic::ppc_build_dmr: {
11302 for (
int i = 1; i < 9; i += 2) {
11310 DAG.
getNode(PPCISD::PAIR_BUILD, dl, MVT::v256i1, {Hi, Lo}));
11317 case Intrinsic::ppc_mma_dmxxextfdmr512: {
11318 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr512 requires ISA Future");
11320 assert(Idx && (
Idx->getSExtValue() == 0 ||
Idx->getSExtValue() == 1) &&
11321 "Specify P of 0 or 1 for lower or upper 512 bytes");
11322 unsigned HiLo =
Idx->getSExtValue();
11326 Opcode = PPC::DMXXEXTFDMR512;
11327 Subx = PPC::sub_wacc_lo;
11329 Opcode = PPC::DMXXEXTFDMR512_HI;
11330 Subx = PPC::sub_wacc_hi;
11333 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
11337 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11341 case Intrinsic::ppc_mma_dmxxextfdmr256: {
11342 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr256 requires ISA Future");
11344 assert(Idx && (
Idx->getSExtValue() >= 0 ||
Idx->getSExtValue() <= 3) &&
11345 "Specify a dmr row pair 0-3");
11346 unsigned IdxVal =
Idx->getSExtValue();
11350 Subx = PPC::sub_dmrrowp0;
11353 Subx = PPC::sub_dmrrowp1;
11356 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11359 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11363 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v256i1,
11369 DAG.
getMachineNode(PPC::DMXXEXTFDMR256, dl, MVT::v256i1, {Subreg, P}),
11373 case Intrinsic::ppc_mma_dmxxinstdmr512: {
11374 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr512 requires ISA Future");
11376 assert(Idx && (
Idx->getSExtValue() == 0 ||
Idx->getSExtValue() == 1) &&
11377 "Specify P of 0 or 1 for lower or upper 512 bytes");
11378 unsigned HiLo =
Idx->getSExtValue();
11382 Opcode = PPCISD::INST512;
11383 Subx = PPC::sub_wacc_lo;
11385 Opcode = PPCISD::INST512HI;
11386 Subx = PPC::sub_wacc_hi;
11392 Op.getOperand(1), Wacc, SubReg),
11396 case Intrinsic::ppc_mma_dmxxinstdmr256: {
11397 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr256 requires ISA Future");
11399 assert(Idx && (
Idx->getSExtValue() >= 0 ||
Idx->getSExtValue() <= 3) &&
11400 "Specify a dmr row pair 0-3");
11401 unsigned IdxVal =
Idx->getSExtValue();
11405 Subx = PPC::sub_dmrrowp0;
11408 Subx = PPC::sub_dmrrowp1;
11411 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11414 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11420 DAG.
getNode(PPCISD::INST256, dl, MVT::v256i1,
Op.getOperand(2),
P);
11422 Op.getOperand(1), DMRRowp, SubReg),
11426 case Intrinsic::ppc_mma_xxmfacc:
11427 case Intrinsic::ppc_mma_xxmtacc: {
11429 if (!Subtarget.isISAFuture())
11440 case Intrinsic::ppc_unpack_longdouble: {
11442 assert(Idx && (
Idx->getSExtValue() == 0 ||
Idx->getSExtValue() == 1) &&
11443 "Argument of long double unpack must be 0 or 1!");
11446 Idx->getValueType(0)));
11449 case Intrinsic::ppc_compare_exp_lt:
11450 case Intrinsic::ppc_compare_exp_gt:
11451 case Intrinsic::ppc_compare_exp_eq:
11452 case Intrinsic::ppc_compare_exp_uo: {
11454 switch (IntrinsicID) {
11455 case Intrinsic::ppc_compare_exp_lt:
11458 case Intrinsic::ppc_compare_exp_gt:
11461 case Intrinsic::ppc_compare_exp_eq:
11464 case Intrinsic::ppc_compare_exp_uo:
11470 PPC::SELECT_CC_I4, dl, MVT::i32,
11471 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
11472 Op.getOperand(1), Op.getOperand(2)),
11474 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11475 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
11478 case Intrinsic::ppc_test_data_class: {
11479 EVT OpVT =
Op.getOperand(1).getValueType();
11480 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
11481 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
11494 {Op.getOperand(2), Op.getOperand(1)}),
11496 if (Subtarget.isISA3_1()) {
11503 TestDataClass, SubRegIdx),
11506 return DAG.
getNode(PPCISD::SETBC, dl, MVT::i32, CRBit);
11512 {TestDataClass, DAG.getConstant(1, dl, MVT::i32),
11513 DAG.getConstant(0, dl, MVT::i32),
11514 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
11517 case Intrinsic::ppc_fnmsub: {
11518 EVT VT =
Op.getOperand(1).getValueType();
11519 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
11524 return DAG.
getNode(PPCISD::FNMSUB, dl, VT,
Op.getOperand(1),
11525 Op.getOperand(2),
Op.getOperand(3));
11527 case Intrinsic::ppc_convert_f128_to_ppcf128:
11528 case Intrinsic::ppc_convert_ppcf128_to_f128: {
11529 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
11530 ? RTLIB::CONVERT_PPCF128_F128
11531 : RTLIB::CONVERT_F128_PPCF128;
11533 std::pair<SDValue, SDValue>
Result =
11534 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
11538 case Intrinsic::ppc_maxfe:
11539 case Intrinsic::ppc_maxfl:
11540 case Intrinsic::ppc_maxfs:
11541 case Intrinsic::ppc_minfe:
11542 case Intrinsic::ppc_minfl:
11543 case Intrinsic::ppc_minfs: {
11544 EVT VT =
Op.getValueType();
11547 [VT](
const SDUse &Use) { return Use.getValueType() == VT; }) &&
11548 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
11551 if (IntrinsicID == Intrinsic::ppc_minfe ||
11552 IntrinsicID == Intrinsic::ppc_minfl ||
11553 IntrinsicID == Intrinsic::ppc_minfs)
11574 SDValue Tmp = DAG.
getNode(PPCISD::VCMP, dl,
Op.getOperand(2).getValueType(),
11575 Op.getOperand(1),
Op.getOperand(2),
11586 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11594 switch (
Op.getConstantOperandVal(1)) {
11599 Bitx = PPC::sub_eq;
11600 SetOp = PPCISD::SETBC;
11605 Bitx = PPC::sub_eq;
11606 SetOp = PPCISD::SETBCR;
11611 Bitx = PPC::sub_lt;
11612 SetOp = PPCISD::SETBC;
11617 Bitx = PPC::sub_lt;
11618 SetOp = PPCISD::SETBCR;
11623 if (Subtarget.isISA3_1()) {
11628 CR6Reg, SubRegIdx, GlueOp),
11630 return DAG.
getNode(SetOp, dl, MVT::i32, CRBit);
11658 switch (
Op.getConstantOperandVal(ArgStart)) {
11659 case Intrinsic::ppc_cfence: {
11660 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11661 SDValue Val =
Op.getOperand(ArgStart + 1);
11663 if (Ty == MVT::i128) {
11668 unsigned Opcode = Subtarget.isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11671 Opcode,
DL, MVT::Other,
11676 case Intrinsic::ppc_disassemble_dmr: {
11678 "llvm.ppc.disassemble.dmr must carry a chain argument.");
11679 return DAG.
getStore(
Op.getOperand(0),
DL,
Op.getOperand(ArgStart + 2),
11680 Op.getOperand(ArgStart + 1), MachinePointerInfo());
11691 if (!Subtarget.isPPC64())
11694 if (Subtarget.hasP9Vector()) {
11701 int VectorIndex = 0;
11702 if (Subtarget.isLittleEndian())
11712 auto CreateRotateInsert =
11713 [&](
unsigned Opcode, MVT VT,
SDValue Dest,
SDValue Src,
unsigned RotAmt,
11714 unsigned MaskBegin,
11715 std::optional<unsigned> MaskEnd = std::nullopt) ->
SDValue {
11719 if (MaskEnd.has_value())
11731 CreateRotateInsert(PPC::RLWIMI, MVT::i32, Rot, Val32, 24, 0, 7);
11733 return CreateRotateInsert(PPC::RLWIMI, MVT::i32,
Swap, Val32, 24, 16, 23);
11746 return CreateRotateInsert(PPC::RLDIMI, MVT::i64, HiSwap, LoSwap, 32, 0);
11752 EVT MemVT =
N->getMemoryVT();
11754 "Expect quadword atomic operations");
11756 unsigned Opc =
N->getOpcode();
11761 SDVTList Tys = DAG.
getVTList(MVT::i64, MVT::i64, MVT::Other);
11764 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11765 for (
int I = 1,
E =
N->getNumOperands();
I <
E; ++
I)
11766 Ops.push_back(
N->getOperand(
I));
11768 Ops, MemVT,
N->getMemOperand());
11775 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11782 SDVTList Tys = DAG.
getVTList(MVT::Other);
11785 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11791 Ops.push_back(ValLo);
11792 Ops.push_back(ValHi);
11793 Ops.push_back(
N->getOperand(2));
11795 N->getMemOperand());
11807 enum DataClassMask {
11809 DC_NEG_INF = 1 << 4,
11810 DC_POS_INF = 1 << 5,
11811 DC_NEG_ZERO = 1 << 2,
11812 DC_POS_ZERO = 1 << 3,
11813 DC_NEG_SUBNORM = 1,
11814 DC_POS_SUBNORM = 1 << 1,
11817 EVT VT =
Op.getValueType();
11819 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11820 : VT == MVT::f64 ? PPC::XSTSTDCDP
11831 return DAG.
getNOT(Dl, Rev, MVT::i1);
11838 TestOp, Dl, MVT::i32,
11840 DC_NEG_ZERO | DC_POS_ZERO |
11841 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11847 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11853 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11871 bool IsQuiet = Mask &
fcQNan;
11877 if (VT == MVT::f128) {
11881 QuietMask = 0x8000;
11882 }
else if (VT == MVT::f64) {
11894 QuietMask = 0x80000;
11895 }
else if (VT == MVT::f32) {
11897 QuietMask = 0x400000;
11913 unsigned NativeMask = 0;
11915 NativeMask |= DC_NAN;
11917 NativeMask |= DC_NEG_INF;
11919 NativeMask |= DC_POS_INF;
11921 NativeMask |= DC_NEG_ZERO;
11923 NativeMask |= DC_POS_ZERO;
11925 NativeMask |= DC_NEG_SUBNORM;
11927 NativeMask |= DC_POS_SUBNORM;
11930 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11932 TestOp, Dl, MVT::i32,
11941 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11943 uint64_t RHSC =
Op.getConstantOperandVal(1);
11946 if (
LHS.getValueType() == MVT::ppcf128) {
11970 bool Future = Subtarget.isISAFuture();
11973 "Mask predication not supported");
11976 unsigned IID = Future ? Intrinsic::ppc_vsx_lxvrl : Intrinsic::ppc_vsx_lxvl;
11977 unsigned EltBits =
Op->getValueType(0).getScalarType().getSizeInBits();
11981 SDVTList Tys = DAG.
getVTList(
Op->getValueType(0), MVT::Other);
11984 VPLD->getMemoryVT(), VPLD->getMemOperand());
11991 "Mask predication not supported");
11996 Op->getOperand(1).getValueType().getScalarType().getSizeInBits();
11997 bool Future = Subtarget.isISAFuture();
11998 unsigned IID = Future ? Intrinsic::ppc_vsx_stxvrl : Intrinsic::ppc_vsx_stxvl;
12001 VPST->getChain(), DAG.
getConstant(IID, dl, MVT::i32),
12004 SDVTList Tys = DAG.
getVTList(MVT::Other);
12007 VPST->getMemoryVT(), VPST->getMemOperand());
12018 "Unexpected partial reduction");
12041 unsigned EltSize =
Op.getValueType().getScalarSizeInBits();
12043 int64_t
IntVal =
Op.getConstantOperandVal(0);
12044 if (IntVal >= -16 && IntVal <= 15)
12050 if (Subtarget.hasLFIWAX() && Subtarget.hasVSX() &&
12057 MMOMetadata(RLI.AAInfo, RLI.Ranges));
12060 PPCISD::LD_SPLAT, dl, DAG.
getVTList(MVT::v4i32, MVT::Other),
Ops,
12064 return Bits.getValue(0);
12080 !Subtarget.isLittleEndian() && ValVT.
isInteger() &&
12085 64 -
Op.getValueType().getScalarSizeInBits(), dl, ShiftAmountTy);
12093 MachinePointerInfo());
12100 return DAG.
getLoad(
Op.getValueType(), dl,
Store, FIdx, MachinePointerInfo());
12106 "Should only be called for ISD::INSERT_VECTOR_ELT");
12110 EVT VT =
Op.getValueType();
12115 if (VT == MVT::v2f64 &&
C)
12118 if (Subtarget.hasP9Vector()) {
12127 if ((VT == MVT::v4f32) && (V2.
getValueType() == MVT::f32) &&
12133 BitcastLoad,
Op.getOperand(2));
12134 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
12138 if (Subtarget.isISA3_1()) {
12139 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.isPPC64())
12143 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
12144 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
12154 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
12157 unsigned InsertAtElement =
C->getZExtValue();
12158 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
12159 if (Subtarget.isLittleEndian()) {
12160 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
12162 return DAG.
getNode(PPCISD::VECINSERT, dl, VT,
V1, Mtvsrz,
12174 EVT VT =
Op.getValueType();
12175 bool IsV1024i1 = VT == MVT::v1024i1;
12176 bool IsV2048i1 = VT == MVT::v2048i1;
12180 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12182 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12183 "Dense Math support required.");
12184 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12193 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
12194 MachineMemOperand *NewMMO =
12202 DAG.
getVTList(MVT::v256i1, MVT::Other),
12203 LoadOps, MVT::v256i1, NewMMO);
12208 if (Subtarget.isLittleEndian()) {
12209 std::reverse(Loads.
begin(), Loads.
end());
12210 std::reverse(LoadChains.
begin(), LoadChains.
end());
12222 SDValue Dmr1Value = DMFInsert1024(MoreLoads, dl, DAG);
12228 const SDValue DmrPOps[] = {DmrPRC,
Value, Dmr0Sub, Dmr1Value, Dmr1Sub};
12231 DAG.
getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v2048i1, DmrPOps), 0);
12240 DAG.
getNode(PPCISD::INST512, dl, MVT::v512i1, Pairs[0], Pairs[1]);
12243 DAG.
getNode(PPCISD::INST512HI, dl, MVT::v512i1, Pairs[2], Pairs[3]);
12248 {RC, Lo, LoSub, Hi, HiSub}),
12258 EVT VT =
Op.getValueType();
12260 if (VT == MVT::v1024i1 || VT == MVT::v2048i1)
12261 return LowerDMFVectorLoad(
Op, DAG);
12263 if (VT != MVT::v256i1 && VT != MVT::v512i1)
12267 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
12268 "Type unsupported without MMA");
12269 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12270 "Type unsupported without paired vector support");
12274 if (VT == MVT::v256i1 && Subtarget.isISAFuture())
12283 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
12285 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
12294 if (Subtarget.isLittleEndian()) {
12295 std::reverse(Loads.
begin(), Loads.
end());
12296 std::reverse(LoadChains.
begin(), LoadChains.
end());
12300 DAG.
getNode(VT == MVT::v512i1 ? PPCISD::ACC_BUILD : PPCISD::PAIR_BUILD,
12316 bool IsV1024i1 = VT == MVT::v1024i1;
12317 bool IsV2048i1 = VT == MVT::v2048i1;
12321 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12323 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12324 "Dense Math support required.");
12325 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12327 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12330 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12335 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12339 MachineSDNode *ExtNode =
12343 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes,
Hi);
12349 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12355 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12361 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12366 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12371 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12376 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12380 MachineSDNode *ExtNode =
12381 DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr0Lo);
12385 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr0Hi);
12388 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr1Lo);
12392 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr1Hi);
12397 if (Subtarget.isLittleEndian())
12400 SDVTList Tys = DAG.
getVTList(MVT::Other);
12402 StoreChain, DAG.
getConstant(Intrinsic::ppc_vsx_stxvp, dl, MVT::i32),
12406 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
12407 MachineMemOperand *NewMMO =
12416 MVT::v256i1, NewMMO);
12432 EVT StoreVT =
Value.getValueType();
12434 if (StoreVT == MVT::v1024i1 || StoreVT == MVT::v2048i1)
12435 return LowerDMFVectorStore(
Op, DAG);
12437 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
12441 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
12442 "Type unsupported without MMA");
12443 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12444 "Type unsupported without paired vector support");
12448 if (StoreVT == MVT::v256i1 && Subtarget.isISAFuture() &&
12456 unsigned NumVecs = 2;
12457 if (StoreVT == MVT::v512i1) {
12458 if (Subtarget.isISAFuture()) {
12459 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12461 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
12464 Value2 =
SDValue(ExtNode, 1);
12469 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
12470 unsigned VecNum = Subtarget.isLittleEndian() ? NumVecs - 1 -
Idx :
Idx;
12472 if (Subtarget.isISAFuture()) {
12473 VecNum = Subtarget.isLittleEndian() ? 1 - (
Idx % 2) : (
Idx % 2);
12474 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
12475 Idx > 1 ? Value2 :
Value,
12478 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
Value,
12482 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
12496 if (
Op.getValueType() == MVT::v4i32) {
12513 LHS,
RHS, DAG, dl, MVT::v4i32);
12516 LHS, RHSSwap,
Zero, DAG, dl, MVT::v4i32);
12521 }
else if (
Op.getValueType() == MVT::v16i8) {
12523 bool isLittleEndian = Subtarget.isLittleEndian();
12527 LHS,
RHS, DAG, dl, MVT::v8i16);
12532 LHS,
RHS, DAG, dl, MVT::v8i16);
12540 for (
unsigned i = 0; i != 8; ++i) {
12541 if (isLittleEndian) {
12543 Ops[i*2+1] = 2*i+16;
12546 Ops[i*2+1] = 2*i+1+16;
12549 if (isLittleEndian)
12559 bool IsStrict =
Op->isStrictFPOpcode();
12560 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
12561 !Subtarget.hasP9Vector())
12571 "Should only be called for ISD::FP_EXTEND");
12575 if (
Op.getValueType() != MVT::v2f64 ||
12576 Op.getOperand(0).getValueType() != MVT::v2f32)
12588 "Node should have 2 operands with second one being a constant!");
12600 int DWord =
Idx >> 1;
12603 if (Subtarget.isLittleEndian())
12606 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64,
12620 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12622 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12623 LD->getMemoryVT(),
LD->getMemOperand());
12628 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewOp,
12633 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12635 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12636 LD->getMemoryVT(),
LD->getMemOperand());
12637 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewLd,
12648 if (STI.useCRBits())
12666 if (STI.useCRBits())
12674 SDNode *
N =
Op.getNode();
12675 EVT VT =
N->getValueType(0);
12676 EVT CarryType =
N->getValueType(1);
12677 unsigned Opc =
N->getOpcode();
12679 Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12681 N->getOperand(0),
N->getOperand(1));
12693 SDNode *
N =
Op.getNode();
12694 unsigned Opc =
N->getOpcode();
12695 EVT VT =
N->getValueType(0);
12696 EVT CarryType =
N->getValueType(1);
12697 SDValue CarryOp =
N->getOperand(2);
12699 Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12705 Op.getOperand(0),
Op.getOperand(1), CarryOp);
12719 EVT VT =
Op.getNode()->getValueType(0);
12745 EVT VT =
Op.getNode()->getValueType(0);
12777 EVT OpVT =
LHS.getValueType();
12778 EVT VT =
Op.getValueType();
12793 unsigned Opcode = PPCISD::SUBC;
12803 Opcode = PPCISD::ADDC;
12810 if (Subtarget.isPPC64() && OpVT != MVT::i64) {
12817 SDVTList VTs = DAG.
getVTList(OpVT, MVT::i32);
12837 EVT OpVT =
A.getValueType();
12838 EVT ResVT =
Op.getValueType();
12843 if (Subtarget.isPPC64() && OpVT != MVT::i64) {
12853 SDVTList VTs = DAG.
getVTList(OpVT, MVT::i32);
12881 EVT VT =
LHS.getValueType();
12882 EVT ResVT =
Op.getValueType();
12885 if (Subtarget.isISA3_0())
12889 bool Is64BitCmp = (VT == MVT::i64);
12894 bool Use64BitOps = Subtarget.isPPC64();
12897 unsigned CmpOpc = Is64BitCmp ? PPC::CMPD : PPC::CMPW;
12908 unsigned MFOCRFOpc = Use64BitOps ? PPC::MFOCRF8 : PPC::MFOCRF;
12909 EVT MFVT = Use64BitOps ? MVT::i64 : MVT::i32;
12920 unsigned RLWinmOpc = Use64BitOps ? PPC::RLWINM8 : PPC::RLWINM;
12938 unsigned SubOpc = Use64BitOps ? PPC::SUBF8 : PPC::SUBF;
12952 switch (
Op.getOpcode()) {
12973 return LowerSSUBO(
Op, DAG);
12975 return LowerSADDO(
Op, DAG);
12987 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
13008 return LowerSET_ROUNDING(
Op, DAG);
13015 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
13016 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
13028 return LowerFP_ROUND(
Op, DAG);
13042 return LowerINTRINSIC_VOID(
Op, DAG);
13044 return LowerBSWAP(
Op, DAG);
13046 return LowerATOMIC_LOAD_STORE(
Op, DAG);
13048 return LowerIS_FPCLASS(
Op, DAG);
13051 return LowerADDSUBO(
Op, DAG);
13054 return LowerADDSUBO_CARRY(
Op, DAG);
13056 return LowerUCMP(
Op, DAG);
13058 return LowerABDU(
Op, DAG);
13060 return LowerSCMP(
Op, DAG);
13066 if (
Op->getFlags().hasNoFPExcept())
13070 return LowerVP_LOAD(
Op, DAG);
13071 case ISD::VP_STORE:
13072 return LowerVP_STORE(
Op, DAG);
13074 return LowerPartialReduce(
Op, DAG);
13082 switch (
N->getOpcode()) {
13084 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
13101 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
13104 assert(
N->getValueType(0) == MVT::i1 &&
13105 "Unexpected result type for CTR decrement intrinsic");
13107 N->getValueType(0));
13117 switch (
N->getConstantOperandVal(0)) {
13118 case Intrinsic::ppc_pack_longdouble:
13120 N->getOperand(2),
N->getOperand(1)));
13122 case Intrinsic::ppc_maxfe:
13123 case Intrinsic::ppc_minfe:
13124 case Intrinsic::ppc_fnmsub:
13125 case Intrinsic::ppc_convert_f128_to_ppcf128:
13132 if (!Subtarget.isSVR4ABI() || Subtarget.isPPC64())
13135 EVT VT =
N->getValueType(0);
13137 if (VT == MVT::i64) {
13150 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
13154 Results.push_back(LoweredValue);
13155 if (
N->isStrictFPOpcode())
13160 if (!
N->getValueType(0).isVector())
13193 return Builder.CreateIntrinsicWithoutFolding(Id, {});
13199 unsigned SZ = ValueTy->getPrimitiveSizeInBits();
13201 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
13202 "Only 8/16/32/64-bit atomic loads supported");
13208 IntID = Intrinsic::ppc_lbarx;
13209 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13212 IntID = Intrinsic::ppc_lharx;
13213 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13216 IntID = Intrinsic::ppc_lwarx;
13219 IntID = Intrinsic::ppc_ldarx;
13223 Builder.CreateIntrinsic(IntID, Addr,
nullptr,
"larx");
13225 return Builder.CreateTruncOrBitCast(
Call, ValueTy);
13236 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
13237 "Only 8/16/32/64-bit atomic loads supported");
13243 IntID = Intrinsic::ppc_stbcx;
13244 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13247 IntID = Intrinsic::ppc_sthcx;
13248 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13251 IntID = Intrinsic::ppc_stwcx;
13254 IntID = Intrinsic::ppc_stdcx;
13258 if (SZ == 8 || SZ == 16)
13259 Val = Builder.CreateZExt(Val, Builder.getInt32Ty());
13261 Value *
Call = Builder.CreateIntrinsic(IntID, {Addr, Val},
13263 return Builder.CreateXor(
Call, Builder.getInt32(1));
13286 return Builder.CreateIntrinsicWithoutFolding(Intrinsic::ppc_cfence,
13295 return !Subtarget.fenceKeepsReservation();
13300 unsigned BinOpcode,
13301 unsigned CmpOpcode,
13302 unsigned CmpPred)
const {
13307 unsigned AtomicSize =
MI.getOperand(3).getImm();
13309 auto LoadMnemonic = PPC::LDARX;
13310 auto StoreMnemonic = PPC::STDCX;
13311 switch (AtomicSize) {
13315 LoadMnemonic = PPC::LBARX;
13316 StoreMnemonic = PPC::STBCX;
13317 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13320 LoadMnemonic = PPC::LHARX;
13321 StoreMnemonic = PPC::STHCX;
13322 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13325 LoadMnemonic = PPC::LWARX;
13326 StoreMnemonic = PPC::STWCX;
13329 LoadMnemonic = PPC::LDARX;
13330 StoreMnemonic = PPC::STDCX;
13338 if (CmpOpcode == PPC::CMPW && (AtomicSize == 1 || AtomicSize == 2))
13349 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13351 F->insert(It, loopMBB);
13353 F->insert(It, loop2MBB);
13354 F->insert(It, exitMBB);
13360 Register TmpReg = (!BinOpcode) ? incr :
13361 RegInfo.createVirtualRegister( AtomicSize == 8 ? &PPC::G8RCRegClass
13362 : &PPC::GPRCRegClass);
13387 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
13392 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13394 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
13395 Register ExtReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13396 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
13426 switch(
MI.getOpcode()) {
13430 return TII->isSignExtended(
MI.getOperand(1).getReg(),
13431 &
MI.getMF()->getRegInfo());
13455 case PPC::EXTSB8_32_64:
13456 case PPC::EXTSB8_rec:
13457 case PPC::EXTSB_rec:
13460 case PPC::EXTSH8_32_64:
13461 case PPC::EXTSH8_rec:
13462 case PPC::EXTSH_rec:
13464 case PPC::EXTSWSLI:
13465 case PPC::EXTSWSLI_32_64:
13466 case PPC::EXTSWSLI_32_64_rec:
13467 case PPC::EXTSWSLI_rec:
13468 case PPC::EXTSW_32:
13469 case PPC::EXTSW_32_64:
13470 case PPC::EXTSW_32_64_rec:
13471 case PPC::EXTSW_rec:
13474 case PPC::SRAWI_rec:
13475 case PPC::SRAW_rec:
13485 unsigned OpIdx,
bool IsByte,
13490 bool IsSignExtended =
13493 if (!IsSignExtended) {
13494 Register ValueReg =
RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13496 TII->get(IsByte ? PPC::EXTSB : PPC::EXTSH), ValueReg)
13498 MI.getOperand(OpIdx).setReg(ValueReg);
13504 unsigned CmpOpcode,
unsigned CmpPred)
const {
13508 assert(!Subtarget.hasPartwordAtomics() &&
13509 "Assumes that part-word atomics are not available");
13517 const bool is8bit =
MI.getOperand(3).getImm() == 1;
13518 if (CmpOpcode == PPC::CMPW)
13526 bool is64bit = Subtarget.isPPC64();
13527 bool isLittleEndian = Subtarget.isLittleEndian();
13528 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13539 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13541 F->insert(It, loopMBB);
13543 F->insert(It, loop2MBB);
13544 F->insert(It, exitMBB);
13550 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13553 Register PtrReg = RegInfo.createVirtualRegister(RC);
13554 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
13556 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
13557 Register Incr2Reg = RegInfo.createVirtualRegister(GPRC);
13558 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
13559 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
13560 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
13561 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
13562 Register Tmp3Reg = RegInfo.createVirtualRegister(GPRC);
13563 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
13564 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
13565 Register SrwDestReg = RegInfo.createVirtualRegister(GPRC);
13568 (!BinOpcode) ? Incr2Reg : RegInfo.createVirtualRegister(GPRC);
13595 if (ptrA != ZeroReg) {
13596 Ptr1Reg = RegInfo.createVirtualRegister(RC);
13597 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13605 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13606 .
addReg(Ptr1Reg, {}, is64bit ? PPC::sub_32 : 0)
13609 .
addImm(is8bit ? 28 : 27);
13610 if (!isLittleEndian)
13611 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13613 .
addImm(is8bit ? 24 : 16);
13615 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13620 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13630 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13634 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13639 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13643 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
13646 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13653 Register SReg = RegInfo.createVirtualRegister(GPRC);
13654 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13658 unsigned ValueReg = SReg;
13659 unsigned CmpReg = Incr2Reg;
13660 if (CmpOpcode == PPC::CMPW) {
13661 ValueReg = RegInfo.createVirtualRegister(GPRC);
13662 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
13665 Register ValueSReg = RegInfo.createVirtualRegister(GPRC);
13666 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
13668 ValueReg = ValueSReg;
13700 .
addImm(is8bit ? 24 : 16)
13721 Register DstReg =
MI.getOperand(0).getReg();
13723 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
13724 Register mainDstReg =
MRI.createVirtualRegister(RC);
13725 Register restoreDstReg =
MRI.createVirtualRegister(RC);
13728 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13729 "Invalid Pointer Size!");
13777 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
13778 Register BufReg =
MI.getOperand(1).getReg();
13780 if (Subtarget.is64BitELFABI()) {
13793 BaseReg = Subtarget.isPPC64() ? PPC::X1 : PPC::R1;
13795 BaseReg = Subtarget.isPPC64() ? PPC::BP8 : PPC::BP;
13798 TII->get(Subtarget.isPPC64() ? PPC::STD : PPC::STW))
13821 TII->get(Subtarget.isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
13824 if (Subtarget.isPPC64()) {
13842 TII->get(PPC::PHI), DstReg)
13846 MI.eraseFromParent();
13860 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13861 "Invalid Pointer Size!");
13864 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13867 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
13868 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
13882 Register BufReg =
MI.getOperand(0).getReg();
13887 if (PVT == MVT::i64) {
13899 if (PVT == MVT::i64) {
13911 if (PVT == MVT::i64) {
13923 if (PVT == MVT::i64) {
13935 if (PVT == MVT::i64 && Subtarget.isSVR4ABI()) {
13945 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
13948 MI.eraseFromParent();
13964 "Unexpected stack alignment");
13968 unsigned StackProbeSize =
13971 StackProbeSize &= ~(StackAlign - 1);
13972 return StackProbeSize ? StackProbeSize : StackAlign;
13984 const bool isPPC64 = Subtarget.isPPC64();
14016 MF->
insert(MBBIter, TestMBB);
14017 MF->
insert(MBBIter, BlockMBB);
14018 MF->
insert(MBBIter, TailMBB);
14023 Register DstReg =
MI.getOperand(0).getReg();
14024 Register NegSizeReg =
MI.getOperand(1).getReg();
14026 Register FinalStackPtr =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
14027 Register FramePointer =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
14028 Register ActualNegSizeReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
14034 if (!
MRI.hasOneNonDBGUse(NegSizeReg))
14036 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
14042 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
14043 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
14045 .
addDef(ActualNegSizeReg)
14047 .
add(
MI.getOperand(2))
14048 .
add(
MI.getOperand(3));
14054 .
addReg(ActualNegSizeReg);
14057 int64_t NegProbeSize = -(int64_t)ProbeSize;
14059 Register ScratchReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
14061 Register TempReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
14063 .
addImm(NegProbeSize >> 16);
14067 .
addImm(NegProbeSize & 0xFFFF);
14074 Register Div =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
14076 .
addReg(ActualNegSizeReg)
14078 Register Mul =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
14082 Register NegMod =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
14085 .
addReg(ActualNegSizeReg);
14094 Register CmpResult =
MRI.createVirtualRegister(&PPC::CRRCRegClass);
14095 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
14120 MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
14122 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
14123 MaxCallFrameSizeReg)
14124 .
add(
MI.getOperand(2))
14125 .
add(
MI.getOperand(3));
14126 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
14128 .
addReg(MaxCallFrameSizeReg);
14134 MBB->addSuccessor(TestMBB);
14137 MI.eraseFromParent();
14139 ++NumDynamicAllocaProbed;
14147static bool IsSelect(
unsigned Opcode,
bool CheckOnlyCC =
false) {
14150 case PPC::SELECT_CC_I4:
14151 case PPC::SELECT_CC_I8:
14152 case PPC::SELECT_CC_F4:
14153 case PPC::SELECT_CC_F8:
14154 case PPC::SELECT_CC_F16:
14155 case PPC::SELECT_CC_VRRC:
14156 case PPC::SELECT_CC_VSFRC:
14157 case PPC::SELECT_CC_VSSRC:
14158 case PPC::SELECT_CC_VSRC:
14159 case PPC::SELECT_CC_SPE4:
14160 case PPC::SELECT_CC_SPE:
14163 case PPC::SELECT_I4:
14164 case PPC::SELECT_I8:
14165 case PPC::SELECT_F4:
14166 case PPC::SELECT_F8:
14167 case PPC::SELECT_F16:
14168 case PPC::SELECT_SPE:
14169 case PPC::SELECT_SPE4:
14170 case PPC::SELECT_VRRC:
14171 case PPC::SELECT_VSFRC:
14172 case PPC::SELECT_VSSRC:
14173 case PPC::SELECT_VSRC:
14174 return !CheckOnlyCC;
14190 assert(
IsSelect(
MI.getOpcode()) &&
"Instruction must be a SELECT variant");
14194 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
14195 MI.getOpcode() == PPC::SELECT_CC_I8 ||
14196 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
14198 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
14199 MI.getOpcode() == PPC::SELECT_CC_I8)
14200 Cond.push_back(
MI.getOperand(4));
14203 Cond.push_back(
MI.getOperand(1));
14206 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
14207 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
14208 MI.eraseFromParent();
14221 F->insert(It, copy0MBB);
14222 F->insert(It, sinkMBB);
14230 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
14246 .
addImm(
MI.getOperand(4).getImm())
14247 .
addReg(
MI.getOperand(1).getReg())
14251 .
addReg(
MI.getOperand(1).getReg())
14261 .
addReg(
MI.getOperand(3).getReg())
14263 .
addReg(
MI.getOperand(2).getReg())
14265 MI.eraseFromParent();
14280 loop1MBB =
F->CreateMachineBasicBlock(LLVM_BB);
14281 loop2MBB =
F->CreateMachineBasicBlock(LLVM_BB);
14282 exitMBB =
F->CreateMachineBasicBlock(LLVM_BB);
14283 F->insert(It, loop1MBB);
14284 F->insert(It, loop2MBB);
14285 F->insert(It, exitMBB);
14320 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
14322 unsigned LoadMnemonic = PPC::LDARX;
14323 unsigned StoreMnemonic = PPC::STDCX;
14324 switch (
MI.getOpcode()) {
14327 case PPC::ATOMIC_CMP_SWAP_I8:
14328 LoadMnemonic = PPC::LBARX;
14329 StoreMnemonic = PPC::STBCX;
14330 assert(
Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14332 case PPC::ATOMIC_CMP_SWAP_I16:
14333 LoadMnemonic = PPC::LHARX;
14334 StoreMnemonic = PPC::STHCX;
14335 assert(
Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14337 case PPC::ATOMIC_CMP_SWAP_I32:
14338 LoadMnemonic = PPC::LWARX;
14339 StoreMnemonic = PPC::STWCX;
14341 case PPC::ATOMIC_CMP_SWAP_I64:
14342 LoadMnemonic = PPC::LDARX;
14343 StoreMnemonic = PPC::STDCX;
14351 Register oldval =
MI.getOperand(3).getReg();
14352 Register newval =
MI.getOperand(4).getReg();
14366 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
14435 bool isLittleEndian =
Subtarget.isLittleEndian();
14436 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
14441 Register oldval =
MI.getOperand(3).getReg();
14442 Register newval =
MI.getOperand(4).getReg();
14450 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
14455 return RegInfo.createVirtualRegister(RC);
14459 Register Shift1Reg = createVReg(GPRC);
14460 Register ShiftReg = isLittleEndian ? Shift1Reg : createVReg(GPRC);
14461 Register NewVal2Reg = createVReg(GPRC);
14462 Register NewVal3Reg = createVReg(GPRC);
14463 Register OldVal2Reg = createVReg(GPRC);
14464 Register OldVal3Reg = createVReg(GPRC);
14465 Register MaskReg = createVReg(GPRC);
14466 Register Mask2Reg = createVReg(GPRC);
14467 Register Mask3Reg = createVReg(GPRC);
14468 Register Tmp2Reg = createVReg(GPRC);
14469 Register Tmp4Reg = createVReg(GPRC);
14470 Register TmpDestReg = createVReg(GPRC);
14471 Register TmpReg = createVReg(GPRC);
14472 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
14473 Register CrReg = createVReg(&PPC::CRRCRegClass);
14477 if (ptrA != ZeroReg) {
14478 Ptr1Reg = createVReg(RC);
14479 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
14486 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
14487 .
addReg(Ptr1Reg, {}, is64bit ? PPC::sub_32 : 0)
14490 .
addImm(is8bit ? 28 : 27);
14491 if (!isLittleEndian)
14492 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
14494 .
addImm(is8bit ? 24 : 16);
14496 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
14501 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
14508 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
14511 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
14518 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
14522 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
14525 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
14528 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
14538 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
14559 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
14604 switch (
MI.getOpcode()) {
14605 case TargetOpcode::STACKMAP:
14607 case TargetOpcode::PATCHPOINT:
14613 if (Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls())
14617 case PPC::EH_SjLj_SetJmp32:
14618 case PPC::EH_SjLj_SetJmp64:
14621 case PPC::EH_SjLj_LongJmp32:
14622 case PPC::EH_SjLj_LongJmp64:
14625 case PPC::ReadTB: {
14641 F->insert(It, readMBB);
14642 F->insert(It, sinkMBB);
14653 Register ReadAgainReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
14661 Register CmpReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14663 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
14675 case PPC::ATOMIC_LOAD_ADD_NOWP:
14678 case PPC::ATOMIC_LOAD_ADD:
14681 case PPC::ATOMIC_LOAD_ADD_I64:
14684 case PPC::ATOMIC_LOAD_AND_NOWP:
14687 case PPC::ATOMIC_LOAD_AND:
14690 case PPC::ATOMIC_LOAD_AND_I64:
14693 case PPC::ATOMIC_LOAD_OR_NOWP:
14696 case PPC::ATOMIC_LOAD_OR:
14699 case PPC::ATOMIC_LOAD_OR_I64:
14702 case PPC::ATOMIC_LOAD_XOR_NOWP:
14705 case PPC::ATOMIC_LOAD_XOR:
14708 case PPC::ATOMIC_LOAD_XOR_I64:
14711 case PPC::ATOMIC_LOAD_NAND_NOWP:
14714 case PPC::ATOMIC_LOAD_NAND:
14717 case PPC::ATOMIC_LOAD_NAND_I64:
14720 case PPC::ATOMIC_LOAD_SUB_NOWP:
14723 case PPC::ATOMIC_LOAD_SUB:
14726 case PPC::ATOMIC_LOAD_SUB_I64:
14729 case PPC::ATOMIC_LOAD_MIN_NOWP:
14732 case PPC::ATOMIC_LOAD_MIN:
14735 case PPC::ATOMIC_LOAD_MIN_I64:
14738 case PPC::ATOMIC_LOAD_MAX_NOWP:
14741 case PPC::ATOMIC_LOAD_MAX:
14744 case PPC::ATOMIC_LOAD_MAX_I64:
14747 case PPC::ATOMIC_LOAD_UMIN_NOWP:
14750 case PPC::ATOMIC_LOAD_UMIN:
14753 case PPC::ATOMIC_LOAD_UMIN_I64:
14756 case PPC::ATOMIC_LOAD_UMAX_NOWP:
14759 case PPC::ATOMIC_LOAD_UMAX:
14762 case PPC::ATOMIC_LOAD_UMAX_I64:
14765 case PPC::ATOMIC_SWAP_NOWP:
14768 case PPC::ATOMIC_SWAP:
14769 case PPC::ATOMIC_SWAP_I64:
14772 case PPC::ATOMIC_CMP_SWAP_I32:
14773 case PPC::ATOMIC_CMP_SWAP_I64:
14774 case PPC::ATOMIC_CMP_SWAP_I8:
14775 case PPC::ATOMIC_CMP_SWAP_I16: {
14777 bool useHardware =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
14778 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
14779 (Subtarget.hasPartwordAtomics() &&
14780 (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
14781 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16));
14789 case PPC::FADDrtz: {
14799 Register MFFSReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14814 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
14824 case PPC::ANDI_rec_1_EQ_BIT:
14825 case PPC::ANDI_rec_1_GT_BIT:
14826 case PPC::ANDI_rec_1_EQ_BIT8:
14827 case PPC::ANDI_rec_1_GT_BIT8: {
14828 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14829 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
14832 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14833 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
14836 Register Dest = RegInfo.createVirtualRegister(
14837 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
14841 .
addReg(
MI.getOperand(1).getReg())
14844 MI.getOperand(0).getReg())
14845 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
14848 case PPC::TCHECK_RET: {
14851 Register CRReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14854 MI.getOperand(0).getReg())
14858 case PPC::TBEGIN_RET: {
14860 unsigned Imm =
MI.getOperand(1).getImm();
14863 MI.getOperand(0).getReg())
14867 case PPC::SETRNDi: {
14869 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14872 if (
MRI.use_empty(OldFPSCRReg))
14873 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14875 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14886 unsigned Mode =
MI.getOperand(1).getImm();
14887 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
14891 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
14896 case PPC::SETRND: {
14904 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
14905 if (Subtarget.hasDirectMove()) {
14906 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
14910 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
14913 if (RC == &PPC::F8RCRegClass) {
14915 assert((RegInfo.getRegClass(DestReg) == &PPC::G8RCRegClass) &&
14916 "Unsupported RegClass.");
14918 StoreOp = PPC::STFD;
14922 assert((RegInfo.getRegClass(SrcReg) == &PPC::G8RCRegClass) &&
14923 (RegInfo.getRegClass(DestReg) == &PPC::F8RCRegClass) &&
14924 "Unsupported RegClass.");
14957 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14960 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14972 Register OldFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14974 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
14976 Register ImDefReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14977 Register ExtSrcReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14982 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
14983 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
14988 Register NewFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14989 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
14995 Register NewFPSCRReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14996 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
15007 case PPC::SETFLM: {
15011 Register OldFPSCRReg =
MI.getOperand(0).getReg();
15012 if (
MRI.use_empty(OldFPSCRReg))
15013 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
15015 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
15018 Register NewFPSCRReg =
MI.getOperand(1).getReg();
15026 case PPC::PROBED_ALLOCA_32:
15027 case PPC::PROBED_ALLOCA_64:
15030 case PPC::SPLIT_QUADWORD: {
15037 .
addUse(Src, {}, PPC::sub_gp8_x1);
15040 .
addUse(Src, {}, PPC::sub_gp8_x0);
15043 case PPC::LQX_PSEUDO:
15044 case PPC::STQX_PSEUDO: {
15050 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
15056 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
15057 :
TII->get(PPC::STQ))
15067 MI.eraseFromParent();
15080 int RefinementSteps =
Subtarget.hasRecipPrec() ? 1 : 3;
15083 return RefinementSteps;
15090 EVT VT =
Op.getValueType();
15093 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
15117PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
15120 EVT VT =
Op.getValueType();
15121 if (VT != MVT::f64 &&
15122 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
15125 return DAG.
getNode(PPCISD::FSQRT, SDLoc(
Op), VT,
Op);
15129 int Enabled,
int &RefinementSteps,
15130 bool &UseOneConstNR,
15131 bool Reciprocal)
const {
15133 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
15134 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
15135 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
15136 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
15142 UseOneConstNR = !Subtarget.needsTwoConstNR();
15143 return DAG.
getNode(PPCISD::FRSQRTE, SDLoc(Operand), VT, Operand);
15150 int &RefinementSteps)
const {
15152 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
15153 (VT == MVT::f64 && Subtarget.hasFRE()) ||
15154 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
15155 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
15158 return DAG.
getNode(PPCISD::FRE, SDLoc(Operand), VT, Operand);
15174 switch (Subtarget.getCPUDirective()) {
15201 unsigned Bytes,
int Dist,
15215 if (FS != BFS || FS != (
int)Bytes)
return false;
15220 int64_t Offset1 = 0, Offset2 = 0;
15223 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
15231 bool isGA1 =
TLI.isGAPlusOffset(
Loc.getNode(), GV1, Offset1);
15232 bool isGA2 =
TLI.isGAPlusOffset(BaseLoc.
getNode(), GV2, Offset2);
15233 if (isGA1 && isGA2 && GV1 == GV2)
15234 return Offset1 == (Offset2 + Dist*Bytes);
15241 unsigned Bytes,
int Dist,
15244 EVT VT = LS->getMemoryVT();
15251 switch (
N->getConstantOperandVal(1)) {
15252 default:
return false;
15253 case Intrinsic::ppc_altivec_lvx:
15254 case Intrinsic::ppc_altivec_lvxl:
15255 case Intrinsic::ppc_vsx_lxvw4x:
15256 case Intrinsic::ppc_vsx_lxvw4x_be:
15259 case Intrinsic::ppc_vsx_lxvd2x:
15260 case Intrinsic::ppc_vsx_lxvd2x_be:
15263 case Intrinsic::ppc_altivec_lvebx:
15266 case Intrinsic::ppc_altivec_lvehx:
15269 case Intrinsic::ppc_altivec_lvewx:
15279 switch (
N->getConstantOperandVal(1)) {
15280 default:
return false;
15281 case Intrinsic::ppc_altivec_stvx:
15282 case Intrinsic::ppc_altivec_stvxl:
15283 case Intrinsic::ppc_vsx_stxvw4x:
15286 case Intrinsic::ppc_vsx_stxvd2x:
15289 case Intrinsic::ppc_vsx_stxvw4x_be:
15292 case Intrinsic::ppc_vsx_stxvd2x_be:
15295 case Intrinsic::ppc_altivec_stvebx:
15298 case Intrinsic::ppc_altivec_stvehx:
15301 case Intrinsic::ppc_altivec_stvewx:
15318 SDValue Chain = LD->getChain();
15319 EVT VT = LD->getMemoryVT();
15328 while (!Queue.empty()) {
15329 SDNode *ChainNext = Queue.pop_back_val();
15330 if (!Visited.
insert(ChainNext).second)
15337 if (!Visited.
count(ChainLD->getChain().getNode()))
15338 Queue.push_back(ChainLD->getChain().getNode());
15340 for (
const SDUse &O : ChainNext->
ops())
15341 if (!Visited.
count(O.getNode()))
15342 Queue.push_back(O.getNode());
15344 LoadRoots.
insert(ChainNext);
15355 for (
SDNode *
I : LoadRoots) {
15356 Queue.push_back(
I);
15358 while (!Queue.empty()) {
15359 SDNode *LoadRoot = Queue.pop_back_val();
15360 if (!Visited.
insert(LoadRoot).second)
15372 Queue.push_back(U);
15403 auto Final = Shifted;
15414 DAGCombinerInfo &DCI)
const {
15417 SelectionDAG &DAG = DCI.DAG;
15422 if (!DCI.isAfterLegalizeDAG())
15427 for (
const SDNode *U :
N->users())
15432 auto OpSize =
N->getOperand(0).getValueSizeInBits();
15436 if (OpSize <
Size) {
15454 DAGCombinerInfo &DCI)
const {
15455 SelectionDAG &DAG = DCI.DAG;
15458 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
15469 N->getValueType(0) != MVT::i1)
15472 if (
N->getOperand(0).getValueType() != MVT::i32 &&
15473 N->getOperand(0).getValueType() != MVT::i64)
15481 N->getOperandCondCode(
N->getOpcode() ==
ISD::SETCC ? 2 : 4);
15482 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
15493 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
15516 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15517 N->getOperand(0).getOpcode() !=
ISD::OR &&
15518 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15528 N->getOperand(1).getOpcode() !=
ISD::AND &&
15529 N->getOperand(1).getOpcode() !=
ISD::OR &&
15530 N->getOperand(1).getOpcode() !=
ISD::XOR &&
15541 SmallPtrSet<SDNode *, 16> Visited;
15543 for (
unsigned i = 0; i < 2; ++i) {
15547 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
15559 while (!BinOps.
empty()) {
15567 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15601 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15605 for (
const SDNode *User : Inputs[i].
getNode()->
users()) {
15606 if (User !=
N && !Visited.
count(User))
15615 if (
User->getOperand(0) == Inputs[i])
15618 if (
User->getOperand(0) == Inputs[i] ||
15619 User->getOperand(1) == Inputs[i])
15625 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15626 for (
const SDNode *User : PromOps[i].
getNode()->
users()) {
15627 if (User !=
N && !Visited.
count(User))
15636 if (
User->getOperand(0) == PromOps[i])
15639 if (
User->getOperand(0) == PromOps[i] ||
15640 User->getOperand(1) == PromOps[i])
15647 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15656 std::list<HandleSDNode> PromOpHandles;
15657 for (
auto &PromOp : PromOps)
15658 PromOpHandles.emplace_back(PromOp);
15665 while (!PromOpHandles.empty()) {
15666 SDValue PromOp = PromOpHandles.back().getValue();
15667 PromOpHandles.pop_back();
15676 PromOpHandles.emplace_front(PromOp);
15690 default:
C = 0;
break;
15703 PromOpHandles.emplace_front(PromOp);
15710 for (
unsigned i = 0; i < 2; ++i)
15720 return N->getOperand(0);
15728 DAGCombinerInfo &DCI)
const {
15729 SelectionDAG &DAG = DCI.DAG;
15746 if (
N->getValueType(0) != MVT::i32 &&
15747 N->getValueType(0) != MVT::i64)
15750 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
15751 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.isPPC64())))
15754 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15755 N->getOperand(0).getOpcode() !=
ISD::OR &&
15756 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15763 SmallPtrSet<SDNode *, 16> Visited;
15767 while (!BinOps.
empty()) {
15775 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15801 DenseMap<SDNode *, EVT> SelectTruncOp[2];
15806 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15811 if (User !=
N && !Visited.
count(User))
15817 if (
User->getOperand(0) == Inputs[i])
15818 SelectTruncOp[0].
insert(std::make_pair(User,
15819 User->getOperand(0).getValueType()));
15821 if (
User->getOperand(0) == Inputs[i])
15822 SelectTruncOp[0].
insert(std::make_pair(User,
15823 User->getOperand(0).getValueType()));
15824 if (
User->getOperand(1) == Inputs[i])
15825 SelectTruncOp[1].
insert(std::make_pair(User,
15826 User->getOperand(1).getValueType()));
15831 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15833 if (User !=
N && !Visited.
count(User))
15839 if (
User->getOperand(0) == PromOps[i])
15840 SelectTruncOp[0].
insert(std::make_pair(User,
15841 User->getOperand(0).getValueType()));
15843 if (
User->getOperand(0) == PromOps[i])
15844 SelectTruncOp[0].
insert(std::make_pair(User,
15845 User->getOperand(0).getValueType()));
15846 if (
User->getOperand(1) == PromOps[i])
15847 SelectTruncOp[1].
insert(std::make_pair(User,
15848 User->getOperand(1).getValueType()));
15853 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
15854 bool ReallyNeedsExt =
false;
15858 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15863 Inputs[i].getOperand(0).getValueSizeInBits();
15864 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
15869 OpBits-PromBits))) ||
15872 (OpBits-(PromBits-1)))) {
15873 ReallyNeedsExt =
true;
15881 std::list<HandleSDNode> PromOpHandles;
15882 for (
auto &PromOp : PromOps)
15883 PromOpHandles.emplace_back(PromOp);
15887 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15894 SDValue InSrc = Inputs[i].getOperand(0);
15912 while (!PromOpHandles.empty()) {
15914 PromOpHandles.pop_back();
15918 default:
C = 0;
break;
15931 PromOpHandles.emplace_front(PromOp);
15941 (SelectTruncOp[1].count(PromOp.
getNode()) &&
15943 PromOpHandles.emplace_front(PromOp);
15951 for (
unsigned i = 0; i < 2; ++i) {
15969 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
15970 if (SI0 != SelectTruncOp[0].
end())
15972 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
15973 if (SI1 != SelectTruncOp[1].
end())
15982 if (!ReallyNeedsExt)
15983 return N->getOperand(0);
15990 N->getValueSizeInBits(0), PromBits),
15991 dl,
N->getValueType(0)));
15994 "Invalid extension type");
15997 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
16007 auto isValidForConvert = [IsPPC64](
SDValue &Operand) {
16016 const APInt &Val =
C->getAPIntValue();
16022 if (IsPPC64 && Val.
ult(1ULL << 16))
16036 if (LoadNode->isVolatile())
16057 return (isValidForConvert(
LHS) && isValidForConvert(
RHS));
16067 "CC mus be ISD::SETNE or ISD::SETEQ");
16069 auto getV16i8Load = [&](
const SDValue &Operand) {
16087 LoadNode->getBasePtr(), NewMMO);
16128 SDValue LHSVec = getV16i8Load(
N->getOperand(0));
16129 SDValue RHSVec = getV16i8Load(
N->getOperand(1));
16132 DAG.
getConstant(Intrinsic::ppc_altivec_vcmpequb_p,
DL, MVT::i32);
16135 IntrID, CRSel, LHSVec, RHSVec);
16138 return DAG.
getSetCC(
DL,
N->getValueType(0), PredResult,
16156 auto IsAndWithOne = [](
SDValue &
V) {
16167 auto IsCompareWithZero = [](
SDValue &
V) {
16174 return (IsAndWithOne(
LHS) && IsCompareWithZero(
RHS)) ||
16175 (IsAndWithOne(
RHS) && IsCompareWithZero(
LHS));
16192 EVT VT =
V.getValueType();
16199 return MakeXor1(
LHS);
16202 return MakeXor1(
RHS);
16219 DAGCombinerInfo &DCI)
const {
16220 if (Subtarget.isISA3_1())
16223 EVT VT =
N->getValueType(0);
16224 if (VT != MVT::i32 && (VT != MVT::i64 || !Subtarget.isPPC64()))
16240 SelectionDAG &DAG = DCI.DAG;
16242 EVT XVT =
X.getValueType();
16246 MVT OpVT = Subtarget.isPPC64() ? MVT::i64 : MVT::i32;
16259 Addc, Addc, Carry);
16262 if (OpVT == MVT::i64 && VT == MVT::i32)
16269 DAGCombinerInfo &DCI)
const {
16271 "Should be called with a SETCC node");
16293 SelectionDAG &DAG = DCI.DAG;
16294 EVT VT =
N->getValueType(0);
16295 EVT OpVT =
LHS.getValueType();
16313 if (Subtarget.hasAltivec() &&
16318 return DAGCombineTruncBoolExt(
N, DCI);
16325 Op.getValueType() == MVT::f64;
16337combineElementTruncationToVectorTruncation(
SDNode *
N,
16338 DAGCombinerInfo &DCI)
const {
16340 "Should be called with a BUILD_VECTOR node");
16342 SelectionDAG &DAG = DCI.DAG;
16345 SDValue FirstInput =
N->getOperand(0);
16347 "The input operand must be an fp-to-int conversion.");
16352 if (FirstConversion == PPCISD::FCTIDZ ||
16353 FirstConversion == PPCISD::FCTIDUZ ||
16354 FirstConversion == PPCISD::FCTIWZ ||
16355 FirstConversion == PPCISD::FCTIWUZ) {
16356 bool IsSplat =
true;
16357 bool Is32Bit = FirstConversion == PPCISD::FCTIWZ ||
16358 FirstConversion == PPCISD::FCTIWUZ;
16361 EVT TargetVT =
N->getValueType(0);
16362 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
16363 SDValue NextOp =
N->getOperand(i);
16364 if (NextOp.
getOpcode() != PPCISD::MFVSR)
16367 if (NextConversion != FirstConversion)
16375 if (
N->getOperand(i) != FirstInput)
16386 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
16387 SDValue In =
N->getOperand(i).getOperand(0);
16397 Ops.push_back(Trunc);
16400 Ops.push_back(
In.isUndef() ? DAG.
getUNDEF(SrcVT) :
In.getOperand(0));
16404 if (FirstConversion == PPCISD::FCTIDZ ||
16405 FirstConversion == PPCISD::FCTIWZ)
16410 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
16412 return DAG.
getNode(Opcode, dl, TargetVT, BV);
16430 static const APInt BasePattern =
APInt(128, 0x8000000000000000ULL) << 64;
16434 if (FullVal == BasePattern)
16435 return std::make_tuple(Uim,
uint8_t{0});
16438 if (FullVal ==
APInt(128, 1))
16439 return std::make_tuple(Uim,
uint8_t{127});
16441 return std::nullopt;
16461 "Expected a BuildVectorSDNode in combineBVLoadsSpecialValue");
16465 EVT VT =
Op.getValueType();
16466 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
16480 for (
const SDValue &Operand :
Op.getNode()->op_values()) {
16490 for (
unsigned Index = 0;
Index < NumElems; ++
Index) {
16494 uint64_t ElemValue =
C->getZExtValue();
16498 ElemValue &= ((1ULL << ElemBits) - 1);
16502 (IsLittleEndian) ? (Index * ElemBits) : (128 - (
Index + 1) * ElemBits);
16505 APInt ElemAPInt(128, ElemValue);
16506 ElemAPInt <<= BitPos;
16509 FullVal |= ElemAPInt;
16516 const auto &[Uim, ShiftAmount] = *UIMOpt;
16520 if (ShiftAmount == 0) {
16525 <<
"combineBVLoadsSpecialValue: Instruction Emitted ";
16526 LxvkqInstr.
dump());
16530 assert(ShiftAmount == 127 &&
"Unexpected lxvkq shift amount value");
16542 DAG.
getMachineNode(PPC::VSRQ, Dl, VT, ShiftAmountVec, ShiftAmountVec),
16545 <<
"\n combineBVLoadsSpecialValue: Instruction Emitted ";
16561 "Should be called with a BUILD_VECTOR node");
16566 if (!
N->getValueType(0).getVectorElementType().isByteSized())
16569 bool InputsAreConsecutiveLoads =
true;
16570 bool InputsAreReverseConsecutive =
true;
16571 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
16572 SDValue FirstInput =
N->getOperand(0);
16573 bool IsRoundOfExtLoad =
false;
16583 N->getNumOperands() == 1)
16586 if (!IsRoundOfExtLoad)
16591 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
16593 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
16596 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
16602 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
16613 InputsAreConsecutiveLoads =
false;
16615 InputsAreReverseConsecutive =
false;
16618 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
16623 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
16624 "The loads cannot be both consecutive and reverse consecutive.");
16628 if (InputsAreConsecutiveLoads) {
16629 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
16633 ReturnSDVal = WideLoad;
16634 }
else if (InputsAreReverseConsecutive) {
16636 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
16641 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
16649 for (
auto *LD : InputLoads)
16651 return ReturnSDVal;
16662 unsigned NumElems =
Input.getValueType().getVectorNumElements();
16668 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16670 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
16672 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
16673 CorrectElems = CorrectElems >> 8;
16674 Elems = Elems >> 8;
16681 EVT VT =
N->getValueType(0);
16685 Input.getValueType().getVectorElementType(),
16719 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
16745 Elems = Elems << 8;
16754 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16755 if (!isSExtOfVecExtract(
N->getOperand(i))) {
16762 int TgtElemArrayIdx;
16763 int InputSize =
Input.getValueType().getScalarSizeInBits();
16764 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
16765 if (InputSize + OutputSize == 40)
16766 TgtElemArrayIdx = 0;
16767 else if (InputSize + OutputSize == 72)
16768 TgtElemArrayIdx = 1;
16769 else if (InputSize + OutputSize == 48)
16770 TgtElemArrayIdx = 2;
16771 else if (InputSize + OutputSize == 80)
16772 TgtElemArrayIdx = 3;
16773 else if (InputSize + OutputSize == 96)
16774 TgtElemArrayIdx = 4;
16778 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
16780 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
16781 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
16782 if (Elems != CorrectElems) {
16798 if (
N->getValueType(0) != MVT::v1i128)
16801 SDValue Operand =
N->getOperand(0);
16808 EVT MemoryType = LD->getMemoryVT();
16812 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
16813 MemoryType == MVT::i32 || MemoryType == MVT::i64;
16816 if (!ValidLDType ||
16822 LD->getChain(), LD->getBasePtr(),
16826 DAG.
getVTList(MVT::v1i128, MVT::Other),
16827 LoadOps, MemoryType, LD->getMemOperand());
16831 DAGCombinerInfo &DCI)
const {
16833 "Should be called with a BUILD_VECTOR node");
16835 SelectionDAG &DAG = DCI.DAG;
16838 if (!Subtarget.hasVSX())
16845 if (FirstInput.
getOpcode() == PPCISD::MFVSR) {
16846 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
16861 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
16870 if (Subtarget.isISA3_1()) {
16876 if (
N->getValueType(0) != MVT::v2f64)
16887 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
16898 if (!Ext1Op || !Ext2Op)
16907 if (FirstElem == 0 && SecondElem == 1)
16908 SubvecIdx = Subtarget.isLittleEndian() ? 1 : 0;
16909 else if (FirstElem == 2 && SecondElem == 3)
16910 SubvecIdx = Subtarget.isLittleEndian() ? 0 : 1;
16916 PPCISD::SINT_VEC_TO_FP : PPCISD::UINT_VEC_TO_FP;
16917 return DAG.
getNode(NodeType, dl, MVT::v2f64,
16922 DAGCombinerInfo &DCI)
const {
16925 "Need an int -> FP conversion node here");
16930 SelectionDAG &DAG = DCI.DAG;
16936 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
16938 if (!
Op.getOperand(0).getValueType().isSimple())
16940 if (
Op.getOperand(0).getValueType().getSimpleVT() <= MVT(MVT::i1) ||
16941 Op.getOperand(0).getValueType().getSimpleVT() > MVT(MVT::i64))
16944 SDValue FirstOperand(
Op.getOperand(0));
16945 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
16946 (FirstOperand.getValueType() == MVT::i8 ||
16947 FirstOperand.getValueType() == MVT::i16);
16948 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
16950 bool DstDouble =
Op.getValueType() == MVT::f64;
16951 unsigned ConvOp =
Signed ?
16952 (DstDouble ? PPCISD::FCFID : PPCISD::FCFIDS) :
16953 (DstDouble ? PPCISD::FCFIDU : PPCISD::FCFIDUS);
16958 SDValue Ops[] = { LDN->getChain(), LDN->getBasePtr(), WidthConst };
16961 Ops, MVT::i8, LDN->getMemOperand());
16966 SDValue ExtOps[] = { Ld, WidthConst };
16968 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
16970 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
16978 if (
Op.getOperand(0).getValueType() == MVT::i32)
16982 "UINT_TO_FP is supported only with FPCVT");
16986 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16991 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16998 Subtarget.hasFPCVT()) ||
17000 SDValue Src =
Op.getOperand(0).getOperand(0);
17001 if (Src.getValueType() == MVT::f32) {
17003 DCI.AddToWorklist(Src.getNode());
17004 }
else if (Src.getValueType() != MVT::f64) {
17016 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
17019 DCI.AddToWorklist(
FP.getNode());
17043 switch (
N->getOpcode()) {
17048 Chain = LD->getChain();
17049 Base = LD->getBasePtr();
17050 MMO = LD->getMemOperand();
17069 MVT VecTy =
N->getValueType(0).getSimpleVT();
17077 Chain =
Load.getValue(1);
17079 PPCISD::XXSWAPD, dl, DAG.
getVTList(MVT::v2f64, MVT::Other), Chain,
Load);
17083 if (VecTy != MVT::v2f64) {
17088 N,
Swap.getValue(1));
17110 switch (
N->getOpcode()) {
17115 Chain = ST->getChain();
17116 Base = ST->getBasePtr();
17117 MMO = ST->getMemOperand();
17137 SDValue Src =
N->getOperand(SrcOpnd);
17138 MVT VecTy = Src.getValueType().getSimpleVT();
17141 if (VecTy != MVT::v2f64) {
17147 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
17149 Chain =
Swap.getValue(1);
17153 StoreOps, VecTy, MMO);
17160 DAGCombinerInfo &DCI)
const {
17163 unsigned Opcode =
N->getOperand(1).getOpcode();
17165 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
17169 &&
"Not a FP_TO_INT Instruction!");
17172 EVT Op1VT =
N->getOperand(1).getValueType();
17179 bool ValidTypeForStoreFltAsInt =
17180 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 &&
Subtarget.isPPC64()) ||
17181 (
Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
17184 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !
Subtarget.hasP9Vector()))
17187 if ((Op1VT != MVT::i64 && !
Subtarget.hasP8Vector()) ||
17195 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
17210 bool PrevElemFromFirstVec = Mask[0] < NumElts;
17211 for (
int i = 1, e = Mask.size(); i < e; i++) {
17212 if (PrevElemFromFirstVec && Mask[i] < NumElts)
17214 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
17216 PrevElemFromFirstVec = !PrevElemFromFirstVec;
17227 for (
int i = 0, e =
Op.getNumOperands(); i < e; i++) {
17228 FirstOp =
Op.getOperand(i);
17234 for (
int i = 1, e =
Op.getNumOperands(); i < e; i++)
17235 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
17245 Op =
Op.getOperand(0);
17261 int RHSFirstElt,
int RHSLastElt,
int HalfVec,
unsigned LHSNumValidElts,
17264 Subtarget.isLittleEndian() ? HalfVec : HalfVec - LHSNumValidElts;
17266 Subtarget.isLittleEndian() ? HalfVec : HalfVec - RHSNumValidElts;
17267 for (
int I = 0,
E = ShuffV.
size();
I <
E; ++
I) {
17268 int Idx = ShuffV[
I];
17269 if (Idx >= LHSFirstElt && Idx <= LHSLastElt)
17270 ShuffV[
I] += LHSEltFixup;
17271 else if (Idx >= RHSFirstElt && Idx <= RHSLastElt)
17272 ShuffV[
I] += RHSEltFixup;
17283 SDLoc dl(OrigSToV);
17286 "Expecting a SCALAR_TO_VECTOR here");
17299 "Cannot produce a permuted scalar_to_vector for one element vector");
17301 unsigned ResultInElt = NumElts / 2;
17302 ResultInElt -=
Subtarget.isLittleEndian() ? 0 : 1;
17303 NewMask[ResultInElt] = Idx->getZExtValue();
17307 return DAG.
getNode(PPCISD::SCALAR_TO_VECTOR_PERMUTED, dl, VT,
17312 int HalfVec,
int LHSLastElementDefined,
17313 int RHSLastElementDefined) {
17314 for (
int Index : ShuffV) {
17318 if ((LHSLastElementDefined >= 0) && (Index < HalfVec) &&
17319 (Index > LHSLastElementDefined))
17322 if ((RHSLastElementDefined >= 0) &&
17323 (Index > HalfVec + RHSLastElementDefined))
17330 int ScalarSize,
uint64_t ShuffleEltWidth,
unsigned &NumValidElts,
17331 int FirstElt,
int &LastElt,
SDValue VecShuffOperand,
SDValue SToVNode,
17347 LastElt = (
uint64_t)ScalarSize > ShuffleEltWidth
17348 ? ScalarSize / ShuffleEltWidth - 1 + FirstElt
17351 if (SToVPermuted.
getValueType() != VecShuffOperandType)
17352 SToVPermuted = DAG.
getBitcast(VecShuffOperandType, SToVPermuted);
17353 return SToVPermuted;
17373 int NumElts =
LHS.getValueType().getVectorNumElements();
17376 bool IsLittleEndian = Subtarget.isLittleEndian();
17383 if (!Subtarget.hasDirectMove())
17403 SmallVector<int, 16> ShuffV(Mask);
17406 if (SToVLHS || SToVRHS) {
17409 int ShuffleNumElts = ShuffV.
size();
17410 int HalfVec = ShuffleNumElts / 2;
17416 unsigned LHSNumValidElts = HalfVec;
17417 unsigned RHSNumValidElts = HalfVec;
17422 int LHSFirstElt = 0;
17423 int RHSFirstElt = ShuffleNumElts;
17424 int LHSLastElt = -1;
17425 int RHSLastElt = -1;
17433 int LHSScalarSize = 0;
17434 int RHSScalarSize = 0;
17437 if (!IsLittleEndian && LHSScalarSize >= 64)
17442 if (!IsLittleEndian && RHSScalarSize >= 64)
17445 if (LHSScalarSize != 0)
17447 LHSScalarSize, ShuffleEltWidth, LHSNumValidElts, LHSFirstElt,
17448 LHSLastElt,
LHS, SToVLHS, DAG, Subtarget);
17449 if (RHSScalarSize != 0)
17451 RHSScalarSize, ShuffleEltWidth, RHSNumValidElts, RHSFirstElt,
17452 RHSLastElt,
RHS, SToVRHS, DAG, Subtarget);
17463 ShuffV, LHSFirstElt, LHSLastElt, RHSFirstElt, RHSLastElt, HalfVec,
17464 LHSNumValidElts, RHSNumValidElts, Subtarget);
17490 if (IsLittleEndian) {
17493 if (Mask[0] < NumElts)
17494 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17498 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
17503 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17507 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
17512 if (Mask[0] < NumElts)
17513 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17517 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
17522 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17526 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
17536 if (IsLittleEndian)
17545 DAGCombinerInfo &DCI)
const {
17547 "Not a reverse memop pattern!");
17549 auto IsElementReverse = [](
const ShuffleVectorSDNode *SVN) ->
bool {
17552 auto I =
Mask.rbegin();
17553 auto E =
Mask.rend();
17555 for (;
I !=
E; ++
I) {
17563 SelectionDAG &DAG = DCI.DAG;
17566 if (!
isTypeLegal(VT) || !Subtarget.isLittleEndian() || !Subtarget.hasVSX())
17572 if (!Subtarget.hasP9Vector())
17575 if(!IsElementReverse(SVN))
17582 for (SDUse &Use : LSBase->
uses())
17583 if (
Use.getResNo() == 0 &&
17590 PPCISD::LOAD_VEC_BE, dl, DAG.
getVTList(VT, MVT::Other), LoadOps,
17605 PPCISD::STORE_VEC_BE, dl, DAG.
getVTList(MVT::Other), StoreOps,
17614 if (IntrinsicID == Intrinsic::ppc_stdcx)
17616 else if (IntrinsicID == Intrinsic::ppc_stwcx)
17618 else if (IntrinsicID == Intrinsic::ppc_sthcx)
17620 else if (IntrinsicID == Intrinsic::ppc_stbcx)
17629 if (
N->getOpcode() == PPCISD::ADDC &&
N->hasAnyUseOfValue(1)) {
17633 if (
LHS->getOpcode() == PPCISD::ADDE &&
17644 if (
N->getOpcode() == PPCISD::SUBE) {
17650 if (
LHS ==
RHS &&
LHS.getOpcode() == PPCISD::ADDC) {
17653 if (AddcLHS.
getOpcode() == PPCISD::ADDE &&
17675 SDValue CmpLHS =
N->getOperand(0);
17676 SDValue CmpRHS =
N->getOperand(1);
17677 SDValue TrueVal =
N->getOperand(2);
17678 SDValue FalseVal =
N->getOperand(3);
17692 if (FalseVal.getOpcode() !=
ISD::SRL || !FalseVal.hasOneUse())
17695 SDValue ShiftVal = FalseVal.getOperand(0);
17696 SDValue ShiftAmt = FalseVal.getOperand(1);
17700 if (!ShiftConst || !ShiftConst->getAPIntValue().isMinSignedValue())
17727 if (CtlzArg != CmpLHS)
17735 DAG.
getNode(PPCISD::SRL,
DL, FalseVal.getValueType(), ShiftVal, ShiftAmt);
17782 auto isZeroOrOne = [=](
SDValue &
V) {
17784 V.getConstantOperandVal(0) == Intrinsic::ppc_test_data_class)
17789 if (!isZeroOrOne(NonNullConstant))
17799 EVT VType =
N->getValueType(0);
17803 return NewNonNullConstant;
17822 EVT XorVT =
N->getValueType(0);
17823 if ((XorVT != MVT::i32 && XorVT != MVT::i64))
17831 if (!XorConst || !XorConst->
isOne()) {
17833 if (!XorConst || !XorConst->
isOne())
17840 if (!
LHS.hasOneUse())
17848 SelectNode =
LHS.getOperand(0);
17862 if (MachineOpc != PPC::SELECT_CC_I4 && MachineOpc != PPC::SELECT_CC_I8)
17872 if (!ConstOp1 || !ConstOp2)
17876 if (!((ConstOp1->
isOne() && ConstOp2->
isZero()) ||
17885 MachineOpc = (XorVT == MVT::i32) ? PPC::SELECT_CC_I4 : PPC::SELECT_CC_I8;
17887 bool ConstOp1IsOne = ConstOp1->
isOne();
17890 {SelectNode.getOperand(0),
17891 DAG.getConstant(ConstOp1IsOne ? 0 : 1, DL, XorVT),
17892 DAG.getConstant(ConstOp1IsOne ? 1 : 0, DL, XorVT),
17893 SelectNode.getOperand(3)}),
17901 switch (
N->getOpcode()) {
17904 return combineADD(
N, DCI);
17936 return combineSHL(
N, DCI);
17938 return combineSRA(
N, DCI);
17940 return combineSRL(
N, DCI);
17942 return combineMUL(
N, DCI);
17944 case PPCISD::FNMSUB:
17945 return combineFMALike(
N, DCI);
17948 return N->getOperand(0);
17952 return N->getOperand(0);
17958 return N->getOperand(0);
17969 N->getValueType(0) == MVT::i64 && N0.
getValueType() == MVT::i32 &&
17977 if (
SDValue SECC = combineSignExtendSetCC(
N, DCI))
17986 return DAGCombineExtBoolTrunc(
N, DCI);
17988 return combineTRUNCATE(
N, DCI);
17990 if (
SDValue CSCC = combineSetCC(
N, DCI))
17996 return DAGCombineTruncBoolExt(
N, DCI);
17999 return combineFPToIntToFP(
N, DCI);
18008 EVT Op1VT =
N->getOperand(1).getValueType();
18009 unsigned Opcode =
N->getOperand(1).getOpcode();
18013 SDValue Val = combineStoreFPToInt(
N, DCI);
18027 N->getOperand(1).getNode()->hasOneUse() &&
18028 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
18029 (Subtarget.hasLDBRX() && Subtarget.isPPC64() && Op1VT == MVT::i64))) {
18037 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
18044 if (Op1VT.
bitsGT(mVT)) {
18049 if (Op1VT == MVT::i64)
18054 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
18074 ST->getBasePtr(), ST->getOffset(), MemVT,
18075 ST->getMemOperand(), ST->getAddressingMode(),
18079 return ST->isUnindexed()
18088 if (Subtarget.needsSwapsForVSXMemOps() &&
18089 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
18090 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
18097 EVT VT = LD->getValueType(0);
18103 if (Subtarget.needsSwapsForVSXMemOps() &&
18104 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
18105 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
18116 auto ReplaceTwoFloatLoad = [&]() {
18117 if (VT != MVT::i64)
18132 if (!LD->hasNUsesOfValue(2, 0))
18135 auto UI = LD->user_begin();
18136 while (UI.getUse().getResNo() != 0) ++UI;
18138 while (UI.getUse().getResNo() != 0) ++UI;
18139 SDNode *RightShift = *UI;
18147 if (RightShift->getOpcode() !=
ISD::SRL ||
18149 RightShift->getConstantOperandVal(1) != 32 ||
18150 !RightShift->hasOneUse())
18153 SDNode *Trunc2 = *RightShift->user_begin();
18163 Bitcast->getValueType(0) != MVT::f32)
18169 if (Subtarget.isLittleEndian())
18175 SDValue BasePtr = LD->getBasePtr();
18176 if (LD->isIndexed()) {
18178 "Non-pre-inc AM on PPC?");
18186 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
18187 LD->getPointerInfo(), LD->getAlign(),
18188 MMOFlags, LD->getAAInfo());
18194 LD->getPointerInfo().getWithOffset(4),
18197 if (LD->isIndexed()) {
18211 if (ReplaceTwoFloatLoad())
18214 EVT MemVT = LD->getMemoryVT();
18217 if (LD->isUnindexed() && VT.
isVector() &&
18220 !Subtarget.hasP8Vector() &&
18221 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
18222 VT == MVT::v4f32))) &&
18223 LD->getAlign() < ABIAlignment) {
18225 SDValue Chain = LD->getChain();
18226 SDValue Ptr = LD->getBasePtr();
18227 bool isLittleEndian = Subtarget.isLittleEndian();
18254 MVT PermCntlTy, PermTy, LDTy;
18255 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
18256 : Intrinsic::ppc_altivec_lvsl;
18257 IntrLD = Intrinsic::ppc_altivec_lvx;
18258 IntrPerm = Intrinsic::ppc_altivec_vperm;
18259 PermCntlTy = MVT::v16i8;
18260 PermTy = MVT::v4i32;
18279 SDValue BaseLoadOps[] = { Chain, LDXIntID, Ptr };
18283 BaseLoadOps, LDTy, BaseMMO);
18292 int IncValue = IncOffset;
18309 SDValue ExtraLoadOps[] = { Chain, LDXIntID, Ptr };
18313 ExtraLoadOps, LDTy, ExtraMMO);
18324 if (isLittleEndian)
18326 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
18329 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
18332 Perm = Subtarget.hasAltivec()
18347 bool isLittleEndian = Subtarget.isLittleEndian();
18348 unsigned IID =
N->getConstantOperandVal(0);
18349 Intrinsic::ID Intr = (isLittleEndian ? Intrinsic::ppc_altivec_lvsr
18350 : Intrinsic::ppc_altivec_lvsl);
18351 if (IID == Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
18358 .zext(
Add.getScalarValueSizeInBits()))) {
18359 SDNode *BasePtr =
Add->getOperand(0).getNode();
18360 for (
SDNode *U : BasePtr->users()) {
18362 U->getConstantOperandVal(0) == IID) {
18373 SDNode *BasePtr =
Add->getOperand(0).getNode();
18374 for (
SDNode *U : BasePtr->users()) {
18377 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
18383 V->getConstantOperandVal(0) == IID) {
18395 (IID == Intrinsic::ppc_altivec_vmaxsw ||
18396 IID == Intrinsic::ppc_altivec_vmaxsh ||
18397 IID == Intrinsic::ppc_altivec_vmaxsb)) {
18400 if ((
V1.getSimpleValueType() == MVT::v4i32 ||
18401 V1.getSimpleValueType() == MVT::v8i16 ||
18402 V1.getSimpleValueType() == MVT::v16i8) &&
18407 V1.getOperand(1) == V2) {
18428 switch (
N->getConstantOperandVal(1)) {
18431 case Intrinsic::ppc_altivec_vsum4sbs:
18432 case Intrinsic::ppc_altivec_vsum4shs:
18433 case Intrinsic::ppc_altivec_vsum4ubs: {
18440 APInt APSplatBits, APSplatUndef;
18441 unsigned SplatBitSize;
18444 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
18445 !Subtarget.isLittleEndian());
18447 if (BVNIsConstantSplat && APSplatBits == 0)
18452 case Intrinsic::ppc_vsx_lxvw4x:
18453 case Intrinsic::ppc_vsx_lxvd2x:
18456 if (Subtarget.needsSwapsForVSXMemOps())
18464 if (Subtarget.needsSwapsForVSXMemOps()) {
18465 switch (
N->getConstantOperandVal(1)) {
18468 case Intrinsic::ppc_vsx_stxvw4x:
18469 case Intrinsic::ppc_vsx_stxvd2x:
18478 bool Is64BitBswapOn64BitTgt =
18479 Subtarget.isPPC64() &&
N->getValueType(0) == MVT::i64;
18481 N->getOperand(0).hasOneUse();
18482 if (IsSingleUseNormalLd &&
18483 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
18484 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
18495 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
18496 MVT::i64 : MVT::i32, MVT::Other),
18497 Ops, LD->getMemoryVT(), LD->getMemOperand());
18501 if (
N->getValueType(0) == MVT::i16)
18518 !IsSingleUseNormalLd)
18523 if (!LD->isSimple())
18525 SDValue BasePtr = LD->getBasePtr();
18527 LD->getPointerInfo(), LD->getAlign());
18532 LD->getMemOperand(), 4, 4);
18536 if (Subtarget.isLittleEndian())
18542 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
18551 if (!
N->getOperand(0).hasOneUse() &&
18552 !
N->getOperand(1).hasOneUse() &&
18553 !
N->getOperand(2).hasOneUse()) {
18556 SDNode *VCMPrecNode =
nullptr;
18558 SDNode *LHSN =
N->getOperand(0).getNode();
18560 if (
User->getOpcode() == PPCISD::VCMP_rec &&
18564 VCMPrecNode =
User;
18576 SDNode *FlagUser =
nullptr;
18578 FlagUser ==
nullptr; ++UI) {
18579 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
18592 return SDValue(VCMPrecNode, 0);
18603 SDValue LHS =
N->getOperand(2), RHS =
N->getOperand(3);
18614 auto RHSAPInt = RHS->getAsAPIntVal();
18615 if (!RHSAPInt.isIntN(64))
18618 unsigned Val = RHSAPInt.getZExtValue();
18619 auto isImpossibleCompare = [&]() {
18622 if (Val != 0 && Val != 1) {
18624 return N->getOperand(0);
18627 N->getOperand(0),
N->getOperand(4));
18632 unsigned StoreWidth = 0;
18635 if (
SDValue Impossible = isImpossibleCompare())
18647 SDValue Ops[] = {LHS.getOperand(0), LHS.getOperand(2), LHS.getOperand(3),
18651 PPCISD::STORE_COND, dl,
18653 MemNode->getMemoryVT(), MemNode->getMemOperand());
18657 if (
N->getOperand(0) == LHS.getValue(1))
18668 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other, InChain,
18670 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
18676 assert(isDot &&
"Can't compare against a vector result!");
18678 if (
SDValue Impossible = isImpossibleCompare())
18681 bool BranchOnWhenPredTrue = (
CC ==
ISD::SETEQ) ^ (Val == 0);
18688 EVT VTs[] = { LHS.getOperand(2).getValueType(), MVT::Glue };
18693 switch (LHS.getConstantOperandVal(1)) {
18709 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other,
N->getOperand(0),
18712 N->getOperand(4), CompNode.
getValue(1));
18717 return DAGCombineBuildVector(
N, DCI);
18724 return DAGCombineBitcast(
N, DCI);
18735 EVT VT =
N->getValueType(0);
18736 if (VT == MVT::i64 && !Subtarget.isPPC64())
18738 if ((VT != MVT::i32 && VT != MVT::i64) ||
18746 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
18766 const APInt &DemandedElts,
18768 unsigned Depth)
const {
18770 switch (
Op.getOpcode()) {
18772 case PPCISD::LBRX: {
18775 Known.Zero = 0xFFFF0000;
18778 case PPCISD::ADDE: {
18779 if (
Op.getResNo() == 0) {
18784 Known.Zero = ~1ULL;
18789 switch (
Op.getConstantOperandVal(0)) {
18791 case Intrinsic::ppc_altivec_vcmpbfp_p:
18792 case Intrinsic::ppc_altivec_vcmpeqfp_p:
18793 case Intrinsic::ppc_altivec_vcmpequb_p:
18794 case Intrinsic::ppc_altivec_vcmpequh_p:
18795 case Intrinsic::ppc_altivec_vcmpequw_p:
18796 case Intrinsic::ppc_altivec_vcmpequd_p:
18797 case Intrinsic::ppc_altivec_vcmpequq_p:
18798 case Intrinsic::ppc_altivec_vcmpgefp_p:
18799 case Intrinsic::ppc_altivec_vcmpgtfp_p:
18800 case Intrinsic::ppc_altivec_vcmpgtsb_p:
18801 case Intrinsic::ppc_altivec_vcmpgtsh_p:
18802 case Intrinsic::ppc_altivec_vcmpgtsw_p:
18803 case Intrinsic::ppc_altivec_vcmpgtsd_p:
18804 case Intrinsic::ppc_altivec_vcmpgtsq_p:
18805 case Intrinsic::ppc_altivec_vcmpgtub_p:
18806 case Intrinsic::ppc_altivec_vcmpgtuh_p:
18807 case Intrinsic::ppc_altivec_vcmpgtuw_p:
18808 case Intrinsic::ppc_altivec_vcmpgtud_p:
18809 case Intrinsic::ppc_altivec_vcmpgtuq_p:
18816 switch (
Op.getConstantOperandVal(1)) {
18819 case Intrinsic::ppc_load2r:
18821 Known.Zero = 0xFFFF0000;
18831 switch (Subtarget.getCPUDirective()) {
18853 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
18861 uint64_t LoopSize = 0;
18862 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
18864 LoopSize +=
TII->getInstSizeInBytes(J);
18869 if (LoopSize > 16 && LoopSize <= 32)
18883 if (Constraint.
size() == 1) {
18884 switch (Constraint[0]) {
18902 }
else if (Constraint ==
"wc") {
18904 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
18905 Constraint ==
"wf" || Constraint ==
"ws" ||
18906 Constraint ==
"wi" || Constraint ==
"ww") {
18919 Value *CallOperandVal =
info.CallOperandVal;
18922 if (!CallOperandVal)
18929 else if ((
StringRef(constraint) ==
"wa" ||
18941 switch (*constraint) {
18971std::pair<unsigned, const TargetRegisterClass *>
18975 if (Constraint.
size() == 1) {
18977 switch (Constraint[0]) {
18979 if (VT == MVT::i64 && Subtarget.isPPC64())
18980 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
18981 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
18983 if (VT == MVT::i64 && Subtarget.isPPC64())
18984 return std::make_pair(0U, &PPC::G8RCRegClass);
18985 return std::make_pair(0U, &PPC::GPRCRegClass);
18991 if (Subtarget.hasSPE()) {
18992 if (VT == MVT::f32 || VT == MVT::i32)
18993 return std::make_pair(0U, &PPC::GPRCRegClass);
18994 if (VT == MVT::f64 || VT == MVT::i64)
18995 return std::make_pair(0U, &PPC::SPERCRegClass);
18997 if (VT == MVT::f32 || VT == MVT::i32)
18998 return std::make_pair(0U, &PPC::F4RCRegClass);
18999 if (VT == MVT::f64 || VT == MVT::i64)
19000 return std::make_pair(0U, &PPC::F8RCRegClass);
19004 if (Subtarget.hasAltivec() && VT.
isVector())
19005 return std::make_pair(0U, &PPC::VRRCRegClass);
19006 else if (Subtarget.hasVSX())
19008 return std::make_pair(0U, &PPC::VFRCRegClass);
19011 return std::make_pair(0U, &PPC::CRRCRegClass);
19013 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
19015 return std::make_pair(0U, &PPC::CRBITRCRegClass);
19016 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
19017 Constraint ==
"wf" || Constraint ==
"wi") &&
19018 Subtarget.hasVSX()) {
19022 return std::make_pair(0U, &PPC::VSRCRegClass);
19023 if (VT == MVT::f32 && Subtarget.hasP8Vector())
19024 return std::make_pair(0U, &PPC::VSSRCRegClass);
19025 return std::make_pair(0U, &PPC::VSFRCRegClass);
19026 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
19027 if (VT == MVT::f32 && Subtarget.hasP8Vector())
19028 return std::make_pair(0U, &PPC::VSSRCRegClass);
19030 return std::make_pair(0U, &PPC::VSFRCRegClass);
19031 }
else if (Constraint ==
"lr") {
19032 if (VT == MVT::i64)
19033 return std::make_pair(0U, &PPC::LR8RCRegClass);
19035 return std::make_pair(0U, &PPC::LRRCRegClass);
19040 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
19044 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
19045 int VSNum = atoi(Constraint.
data() + 3);
19046 assert(VSNum >= 0 && VSNum <= 63 &&
19047 "Attempted to access a vsr out of range");
19049 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
19050 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
19055 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
19056 int RegNum = atoi(Constraint.
data() + 2);
19057 if (RegNum > 31 || RegNum < 0)
19059 if (VT == MVT::f32 || VT == MVT::i32)
19060 return Subtarget.hasSPE()
19061 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
19062 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
19063 if (VT == MVT::f64 || VT == MVT::i64)
19064 return Subtarget.hasSPE()
19065 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
19066 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
19070 std::pair<unsigned, const TargetRegisterClass *> R =
19079 if (R.first && VT == MVT::i64 && Subtarget.isPPC64() &&
19080 PPC::GPRCRegClass.contains(R.first))
19081 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
19082 PPC::sub_32, &PPC::G8RCRegClass),
19083 &PPC::G8RCRegClass);
19086 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
19087 R.first = PPC::CR0;
19088 R.second = &PPC::CRRCRegClass;
19091 if (Subtarget.isAIXABI() && !Subtarget.isAIXExtendedAltivecABI()) {
19092 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
19093 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
19094 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
19095 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
19096 "default AIX AltiVec ABI and cannot be used\n";
19106 std::vector<SDValue> &
Ops,
19111 if (Constraint.
size() > 1)
19114 char Letter = Constraint[0];
19129 EVT TCVT = MVT::i64;
19170 if (Result.getNode()) {
19171 Ops.push_back(Result);
19182 if (
I.getNumOperands() <= 1)
19186 auto IntrinsicID =
Ops[1].getNode()->getAsZExtVal();
19187 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
19188 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
19191 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
19207 if (Ty->isVectorTy() && AM.
BaseOffs != 0 && !Subtarget.hasP9Vector())
19219 switch (AM.
Scale) {
19247 unsigned Depth =
Op.getConstantOperandVal(0);
19271 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
19279 unsigned Depth =
Op.getConstantOperandVal(0);
19286 bool isPPC64 = PtrVT == MVT::i64;
19292 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
19294 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
19300 FrameAddr, MachinePointerInfo());
19304#define GET_REGISTER_MATCHER
19305#include "PPCGenAsmMatcher.inc"
19309 bool IsPPC64 = Subtarget.isPPC64();
19321 if ((IsPPC64 && Reg == PPC::R2) || Reg == PPC::R0)
19327 Reg = Reg.id() - PPC::R0 + PPC::X0;
19334 if (Subtarget.is32BitELFABI())
19339 if (Subtarget.isAIXABI())
19353 return Subtarget.isGVIndirectSymbol(
G->getGlobal());
19369 case Intrinsic::ppc_atomicrmw_xchg_i128:
19370 case Intrinsic::ppc_atomicrmw_add_i128:
19371 case Intrinsic::ppc_atomicrmw_sub_i128:
19372 case Intrinsic::ppc_atomicrmw_nand_i128:
19373 case Intrinsic::ppc_atomicrmw_and_i128:
19374 case Intrinsic::ppc_atomicrmw_or_i128:
19375 case Intrinsic::ppc_atomicrmw_xor_i128:
19376 case Intrinsic::ppc_cmpxchg_i128:
19378 Info.memVT = MVT::i128;
19379 Info.ptrVal =
I.getArgOperand(0);
19381 Info.align =
Align(16);
19386 case Intrinsic::ppc_atomic_load_i128:
19388 Info.memVT = MVT::i128;
19389 Info.ptrVal =
I.getArgOperand(0);
19391 Info.align =
Align(16);
19395 case Intrinsic::ppc_atomic_store_i128:
19397 Info.memVT = MVT::i128;
19398 Info.ptrVal =
I.getArgOperand(2);
19400 Info.align =
Align(16);
19404 case Intrinsic::ppc_altivec_lvx:
19405 case Intrinsic::ppc_altivec_lvxl:
19406 case Intrinsic::ppc_altivec_lvebx:
19407 case Intrinsic::ppc_altivec_lvehx:
19408 case Intrinsic::ppc_altivec_lvewx:
19409 case Intrinsic::ppc_vsx_lxvd2x:
19410 case Intrinsic::ppc_vsx_lxvw4x:
19411 case Intrinsic::ppc_vsx_lxvd2x_be:
19412 case Intrinsic::ppc_vsx_lxvw4x_be:
19413 case Intrinsic::ppc_vsx_lxvl:
19414 case Intrinsic::ppc_vsx_lxvll: {
19417 case Intrinsic::ppc_altivec_lvebx:
19420 case Intrinsic::ppc_altivec_lvehx:
19423 case Intrinsic::ppc_altivec_lvewx:
19426 case Intrinsic::ppc_vsx_lxvd2x:
19427 case Intrinsic::ppc_vsx_lxvd2x_be:
19437 Info.ptrVal =
I.getArgOperand(0);
19440 Info.align =
Align(1);
19445 case Intrinsic::ppc_altivec_stvx:
19446 case Intrinsic::ppc_altivec_stvxl:
19447 case Intrinsic::ppc_altivec_stvebx:
19448 case Intrinsic::ppc_altivec_stvehx:
19449 case Intrinsic::ppc_altivec_stvewx:
19450 case Intrinsic::ppc_vsx_stxvd2x:
19451 case Intrinsic::ppc_vsx_stxvw4x:
19452 case Intrinsic::ppc_vsx_stxvd2x_be:
19453 case Intrinsic::ppc_vsx_stxvw4x_be:
19454 case Intrinsic::ppc_vsx_stxvl:
19455 case Intrinsic::ppc_vsx_stxvll: {
19458 case Intrinsic::ppc_altivec_stvebx:
19461 case Intrinsic::ppc_altivec_stvehx:
19464 case Intrinsic::ppc_altivec_stvewx:
19467 case Intrinsic::ppc_vsx_stxvd2x:
19468 case Intrinsic::ppc_vsx_stxvd2x_be:
19478 Info.ptrVal =
I.getArgOperand(1);
19481 Info.align =
Align(1);
19486 case Intrinsic::ppc_stdcx:
19487 case Intrinsic::ppc_stwcx:
19488 case Intrinsic::ppc_sthcx:
19489 case Intrinsic::ppc_stbcx: {
19491 auto Alignment =
Align(8);
19493 case Intrinsic::ppc_stdcx:
19496 case Intrinsic::ppc_stwcx:
19498 Alignment =
Align(4);
19500 case Intrinsic::ppc_sthcx:
19502 Alignment =
Align(2);
19504 case Intrinsic::ppc_stbcx:
19506 Alignment =
Align(1);
19511 Info.ptrVal =
I.getArgOperand(0);
19513 Info.align = Alignment;
19531 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
19532 if (
Op.isMemset() && Subtarget.hasVSX()) {
19533 uint64_t TailSize =
Op.size() % 16;
19537 if (TailSize > 2 && TailSize <= 4) {
19542 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
19547 if (Subtarget.isPPC64()) {
19558 assert(Ty->isIntegerTy());
19560 unsigned BitSize = Ty->getPrimitiveSizeInBits();
19561 return !(BitSize == 0 || BitSize > 64);
19569 return NumBits1 == 64 && NumBits2 == 32;
19577 return NumBits1 == 64 && NumBits2 == 32;
19584 EVT MemVT = LD->getMemoryVT();
19585 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
19586 (Subtarget.isPPC64() && MemVT == MVT::i32)) &&
19602 "invalid fpext types");
19604 if (DestVT == MVT::f128)
19619 unsigned *
Fast)
const {
19633 !Subtarget.allowsUnalignedFPAccess())
19637 if (Subtarget.hasVSX()) {
19638 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
19639 VT != MVT::v4f32 && VT != MVT::v4i32)
19646 if (VT == MVT::ppcf128)
19661 if (!ConstNode->getAPIntValue().isSignedIntN(64))
19669 int64_t
Imm = ConstNode->getSExtValue();
19674 uint64_t UImm =
static_cast<uint64_t
>(
Imm);
19690 if (Subtarget.hasSPE() || Subtarget.useSoftFloat())
19692 switch (Ty->getScalarType()->getTypeID()) {
19697 return Subtarget.hasP9Vector();
19705 if (!
I->hasOneUse())
19709 assert(
User &&
"A single use instruction with no uses.");
19711 switch (
I->getOpcode()) {
19712 case Instruction::FMul: {
19714 if (
User->getOpcode() != Instruction::FSub &&
19715 User->getOpcode() != Instruction::FAdd)
19721 bool AllowContract =
I->getFastMathFlags().allowContract() &&
19722 User->getFastMathFlags().allowContract();
19728 case Instruction::Load: {
19741 if (
User->getOpcode() != Instruction::Store)
19761 static const MCPhysReg ScratchRegs[] = {
19762 PPC::X12, PPC::LR8, PPC::CTR8, 0
19765 return ScratchRegs;
19770 return Subtarget.isPPC64() ? PPC::X3 : PPC::R3;
19775 return Subtarget.isPPC64() ? PPC::X4 : PPC::R4;
19780 EVT VT ,
unsigned DefinedValues)
const {
19781 if (VT == MVT::v2i64)
19782 return Subtarget.hasDirectMove();
19784 if (Subtarget.hasVSX())
19811 return PPCISD::FNMSUB;
19812 case PPCISD::FNMSUB:
19818 bool LegalOps,
bool OptForSize,
19820 unsigned Depth)
const {
19824 unsigned Opc =
Op.getOpcode();
19825 EVT VT =
Op.getValueType();
19829 case PPCISD::FNMSUB:
19849 if (Flags.hasNoSignedZeros()) {
19853 N0Cost,
Depth + 1);
19857 N1Cost,
Depth + 1);
19859 if (NegN0 && N0Cost <= N1Cost) {
19860 Cost = std::min(N0Cost, N2Cost);
19862 }
else if (NegN1) {
19863 Cost = std::min(N1Cost, N2Cost);
19883 if (M.getStackProtectorGuard() ==
"tls" || Subtarget.isTargetLinux())
19890 bool ForCodeSize)
const {
19891 if (!VT.
isSimple() || !Subtarget.hasVSX())
19901 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
19906 APSInt IntResult(16,
false);
19911 if (IsExact && IntResult <= 15 && IntResult >= -16)
19928 unsigned Opcode =
N->getOpcode();
19945 if (VT.
isVector() &&
TLI.isOperationLegal(Opcode, VT) &&
19948 if (Mask->getZExtValue() == OpSizeInBits - 1)
19955 DAGCombinerInfo &DCI)
const {
19956 EVT VT =
N->getValueType(0);
19959 unsigned Opc =
N->getOpcode();
19961 "Unexpected opcode.");
19968 if (EltTy != MVT::i64 && EltTy != MVT::i32)
19973 bool AddSplatCase =
false;
19977 AddSplatCase =
true;
19981 if (!AddSplatCase) {
19985 unsigned SplatBitSize;
19987 APInt APSplatBits, APSplatUndef;
19989 bool BVNIsConstantSplat =
19991 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
19992 if (!BVNIsConstantSplat || SplatBitSize != EltBits)
20003 if (SplatBits == (EltBits - 1)) {
20007 NewOpc = PPCISD::SHL;
20010 NewOpc = PPCISD::SRL;
20013 NewOpc = PPCISD::SRA;
20017 return DCI.DAG.getNode(NewOpc,
DL, VT, N0, SplatOnes);
20025 if (EltTy != MVT::i64 || SplatBits != 1)
20028 return DCI.DAG.getNode(
ISD::ADD, SDLoc(
N), VT, N0, N0);
20031SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20035 if (
N->getValueType(0).isVector())
20036 return combineVectorShift(
N, DCI);
20040 if (!Subtarget.isISA3_0() || !Subtarget.isPPC64() ||
20043 N->getValueType(0) != MVT::i64)
20058 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
20064SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20068 if (
N->getValueType(0).isVector())
20069 return combineVectorShift(
N, DCI);
20074SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20078 if (
N->getValueType(0).isVector())
20079 return combineVectorShift(
N, DCI);
20096 auto isZextOfCompareWithConstant = [](
SDValue Op) {
20098 Op.getValueType() != MVT::i64)
20102 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
20103 Cmp.getOperand(0).getValueType() != MVT::i64)
20107 int64_t NegConstant = 0 -
Constant->getSExtValue();
20116 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
20117 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
20120 if (LHSHasPattern && !RHSHasPattern)
20122 else if (!LHSHasPattern && !RHSHasPattern)
20126 EVT CarryType =
Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
20129 SDValue Z = Cmp.getOperand(0);
20131 int64_t NegConstant = 0 -
Constant->getSExtValue();
20133 switch (Cmp.getOperandCondCode(2)) {
20144 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
20162 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
20184 if (!
Subtarget.isUsingPCRelativeCalls())
20192 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
20195 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
20203 if (!GSDN || !ConstNode)
20231 EVT VT =
N->getValueType(0);
20236 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
20248 unsigned NumOfEles =
RHS.getNumOperands();
20249 for (
unsigned i = 0; i < NumOfEles; ++i) {
20251 if (!CN || CN->getSExtValue() != 1)
20266SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20288 DAGCombinerInfo &DCI)
const {
20290 if (Subtarget.useCRBits()) {
20292 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
20293 return CRTruncValue;
20300 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
20303 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
20313 EltToExtract = EltToExtract ? 0 : 1;
20323 return DCI.DAG.getNode(
20325 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
20330SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20331 SelectionDAG &DAG = DCI.DAG;
20334 if (!ConstOpOrElement)
20342 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne, EVT VT) ->
bool {
20343 switch (this->Subtarget.getCPUDirective()) {
20366 return IsAddOne && IsNeg ? VT.
isVector() :
true;
20370 EVT VT =
N->getValueType(0);
20375 APInt MulAmtAbs = MulAmt.
abs();
20377 if ((MulAmtAbs - 1).isPowerOf2()) {
20381 if (!IsProfitable(IsNeg,
true, VT))
20394 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
20398 if (!IsProfitable(IsNeg,
false, VT))
20419 DAGCombinerInfo &DCI)
const {
20423 SDNodeFlags
Flags =
N->getFlags();
20424 EVT VT =
N->getValueType(0);
20425 SelectionDAG &DAG = DCI.DAG;
20426 unsigned Opc =
N->getOpcode();
20428 bool LegalOps = !DCI.isBeforeLegalizeOps();
20436 if (!
Flags.hasNoSignedZeros())
20452bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
20454 if (!Subtarget.is64BitELFABI())
20464 if (!TM.Options.GuaranteedTailCallOpt && !
EnableSCO)
20469 if (!Callee ||
Callee->isVarArg())
20482bool PPCTargetLowering::
20483isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
20488 if (CI->getBitWidth() > 64)
20490 int64_t ConstVal = CI->getZExtValue();
20492 (
isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
20501PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
20507 if ((Flags & FlagSet) == FlagSet)
20510 if ((Flags & FlagSet) == FlagSet)
20513 if ((Flags & FlagSet) == FlagSet)
20516 if ((Flags & FlagSet) == FlagSet)
20537 if ((FrameIndexAlign % 4) != 0)
20538 FlagSet &=
~PPC::MOF_RPlusSImm16Mult4;
20539 if ((FrameIndexAlign % 16) != 0)
20540 FlagSet &=
~PPC::MOF_RPlusSImm16Mult16;
20544 if ((FrameIndexAlign % 4) == 0)
20546 if ((FrameIndexAlign % 16) == 0)
20560 if ((
Imm & 0x3) == 0)
20562 if ((
Imm & 0xf) == 0)
20568 const APInt &ConstImm = CN->getAPIntValue();
20587 const APInt &ConstImm = CN->getAPIntValue();
20597 }
else if (
RHS.getOpcode() == PPCISD::Lo && !
RHS.getConstantOperandVal(1))
20608 return (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR ||
20617unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
20622 if (!Subtarget.hasP9Vector())
20627 if (Subtarget.hasPrefixInstrs())
20630 if (Subtarget.hasSPE())
20639 unsigned ParentOp = Parent->
getOpcode();
20643 if ((ID == Intrinsic::ppc_vsx_lxvp) || (ID == Intrinsic::ppc_vsx_stxvp)) {
20644 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
20656 if (LSB->isIndexed())
20662 assert(MN &&
"Parent should be a MemSDNode!");
20667 "Not expecting scalar integers larger than 16 bytes!");
20670 else if (
Size == 32)
20677 else if (
Size == 256) {
20678 assert(Subtarget.pairedVectorMemops() &&
20679 "256-bit vectors are only available when paired vector memops is "
20687 else if (MemVT == MVT::f128 || MemVT.
isVector())
20718 FlagSet &= ~PPC::MOF_NoExt;
20723 bool IsNonP1034BitConst =
20727 IsNonP1034BitConst)
20740 int16_t ForceXFormImm = 0;
20743 Disp =
N.getOperand(0);
20744 Base =
N.getOperand(1);
20755 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
20756 Disp =
N.getOperand(0);
20757 Base =
N.getOperand(1);
20762 Disp = DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20771 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID>
CC)
const {
20777 if (PartVT == MVT::f64 &&
20778 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
20787SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
20791 EVT RetVT =
Op.getValueType();
20795 bool SignExtend =
TLI.shouldSignExtendTypeInLibCall(RetTy,
false);
20798 EVT ArgVT =
N.getValueType();
20801 Entry.IsSExt =
TLI.shouldSignExtendTypeInLibCall(ArgTy, SignExtend);
20802 Entry.IsZExt = !Entry.IsSExt;
20803 Args.push_back(Entry);
20810 TLI.isInTailCallPosition(DAG,
Op.getNode(), TCChain) &&
20811 (RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
20821 return TLI.LowerCallTo(CLI).first;
20824SDValue PPCTargetLowering::lowerLibCallBasedOnType(
20825 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
20827 if (
Op.getValueType() == MVT::f32)
20828 return lowerToLibCall(LibCallFloatName,
Op, DAG);
20830 if (
Op.getValueType() == MVT::f64)
20831 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
20836bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
20837 SDNodeFlags
Flags =
Op.getNode()->getFlags();
20838 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
20842bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
20843 return Op.getNode()->getFlags().hasApproximateFuncs();
20846bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
20851SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
20852 const char *LibCallFloatName,
20853 const char *LibCallDoubleNameFinite,
20854 const char *LibCallFloatNameFinite,
20857 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
20860 if (!isLowringToMASSFiniteSafe(
Op))
20861 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
20864 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
20865 LibCallDoubleNameFinite,
Op, DAG);
20869 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
20870 "__xl_powf_finite",
Op, DAG);
20874 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
20875 "__xl_sinf_finite",
Op, DAG);
20879 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
20880 "__xl_cosf_finite",
Op, DAG);
20884 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
20885 "__xl_logf_finite",
Op, DAG);
20889 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
20890 "__xl_log10f_finite",
Op, DAG);
20894 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
20895 "__xl_expf_finite",
Op, DAG);
20920 unsigned Flags = computeMOFlags(Parent,
N, DAG);
20931 assert(Subtarget.isUsingPCRelativeCalls() &&
20932 "Must be using PC-Relative calls when a valid PC-Relative node is "
20962 Disp =
N.getOperand(1).getOperand(0);
20967 Base =
N.getOperand(0);
20975 EVT CNType = CN->getValueType(0);
20976 uint64_t CNImm = CN->getZExtValue();
20987 if ((CNType == MVT::i32 ||
isInt<32>(CNImm)) &&
20989 int32_t Addr = (int32_t)CNImm;
20994 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
21010 unsigned Opcode =
N.getOpcode();
21018 Base =
N.getOperand(0);
21037 Base = FI ?
N :
N.getOperand(1);
21038 Disp = FI ? DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
21049 bool IsVarArg)
const {
21059 return Subtarget.isPPC64() && Subtarget.hasQuadwordAtomics();
21096 return Intrinsic::ppc_atomicrmw_xchg_i128;
21098 return Intrinsic::ppc_atomicrmw_add_i128;
21100 return Intrinsic::ppc_atomicrmw_sub_i128;
21102 return Intrinsic::ppc_atomicrmw_and_i128;
21104 return Intrinsic::ppc_atomicrmw_or_i128;
21106 return Intrinsic::ppc_atomicrmw_xor_i128;
21108 return Intrinsic::ppc_atomicrmw_nand_i128;
21116 Module *M = Builder.getModule();
21120 Value *IncrLo = Builder.CreateTrunc(Incr, Int64Ty,
"incr_lo");
21122 Builder.CreateTrunc(Builder.CreateLShr(Incr, 64), Int64Ty,
"incr_hi");
21123 Value *LoHi = Builder.CreateIntrinsic(
21125 {AlignedAddr, IncrLo, IncrHi});
21126 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
21127 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
21128 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
21129 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
21130 return Builder.CreateOr(
21131 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
21138 Module *M = Builder.getModule();
21144 Value *CmpLo = Builder.CreateTrunc(CmpVal, Int64Ty,
"cmp_lo");
21146 Builder.CreateTrunc(Builder.CreateLShr(CmpVal, 64), Int64Ty,
"cmp_hi");
21147 Value *NewLo = Builder.CreateTrunc(NewVal, Int64Ty,
"new_lo");
21149 Builder.CreateTrunc(Builder.CreateLShr(NewVal, 64), Int64Ty,
"new_hi");
21152 Builder.CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
21154 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
21155 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
21156 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
21157 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
21158 return Builder.CreateOr(
21159 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
21163 return Subtarget.useCRBits();
21168bool PPCTargetLowering::isShuffleMaskLegal(
ArrayRef<int> Mask,
EVT VT)
const {
21179 DAGCombinerInfo &DCI)
const {
21184 EVT ResVT =
N->getValueType(0);
21186 EVT SrcVT = Src.getValueType();
21189 bool IsLittleEndian =
Subtarget.isLittleEndian();
21191 if (ResVT != MVT::i16 && ResVT != MVT::i8)
21194 GenerateVBPERM(DAG, dl, Src, SrcVT, TruncResVT, IsLittleEndian);
21207 bool IsV16i8 = (ResVT == MVT::v16i1 && SrcVT == MVT::v16i8);
21208 bool IsV8i16 = (ResVT == MVT::v8i1 && SrcVT == MVT::v8i16);
21209 bool IsV8i8 = (ResVT == MVT::v8i1 && SrcVT == MVT::v8i8);
21211 if (!IsV16i8 && !IsV8i16 && !IsV8i8)
21219 SmallVector<int, 16> BitIndices(16, 128);
21223 BitIndices[
Idx] = EltSize * (NumElts -
Idx) - 1;
21224 if (IsV8i8 && IsLE)
21225 BitIndices[
Idx] += 64;
21228 std::reverse(BitIndices.begin(), BitIndices.end());
21230 for (
auto Idx : BitIndices)
21235 DAG.
getConstant(Intrinsic::ppc_altivec_vbpermq, dl, MVT::i32),
21243 bool BVNIsConstantSplat,
21244 unsigned SplatBitSize)
const {
21246 if (!BVNIsConstantSplat || !Subtarget.hasVSX() || !Subtarget.hasP8Vector() ||
21247 Subtarget.hasP10Vector())
21250 EVT VT =
Op->getValueType(0);
21251 if (!((SplatBitSize == 64 && VT == MVT::v2f64) ||
21252 (SplatBitSize == 32 && VT == MVT::v4f32)))
21259 APFloat APFloatVal = CN->getValueAPF();
21261 APSInt IntResult(16,
false);
21264 if (!(IsExact && IntResult <= 15 && IntResult >= -16 && !APFloatVal.
isZero()))
21267 int64_t
IntVal = IntResult.getSExtValue();
21272 if (SplatBitSize == 64)
21275 DAG.
getConstant(Intrinsic::ppc_vsx_xvcvsxwdp, dl, MVT::i32), IntSplat);
21277 return DAG.
getNode(PPCISD::XVCVSXWSP, dl, MVT::v4f32, IntSplat);
static MCRegister MatchRegisterName(StringRef Name)
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall, std::optional< CallLowering::PtrAuthInfo > &PAI, MachineRegisterInfo &MRI)
static bool isSignExtended(SDValue N, SelectionDAG &DAG)
const AArch64Subtarget & Subtarget
const TargetLowering & TLI
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 SDValue GeneratePerfectShuffle(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 isFloatingPointZero(SDValue Op)
isFloatingPointZero - Return true if this is +0.0.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
Atomic ordering constants.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
const HexagonInstrInfo * TII
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, ISD::ArgFlagsTy Flags, SelectionDAG &DAG, const SDLoc &dl)
CreateCopyOfByValArgument - Make a copy of an aggregate at address specified by "Src" to address "Dst...
Module.h This file contains the declarations for the Module class.
This defines the Use class.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
static int getEstimateRefinementSteps(EVT VT, const LoongArchSubtarget &Subtarget)
static bool isSplat(Value *V)
Return true if V is a splat of a value (which is used when multiplying a matrix with a scalar).
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static bool isConstantOrUndef(const SDValue Op)
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
cl::opt< bool > ANDIGlueBug("ppc-expose-andi-glue-bug", cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden)
static SDValue getCanonicalConstSplat(uint64_t Val, unsigned SplatSize, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
getCanonicalConstSplat - Build a canonical splat immediate of Val with an element size of SplatSize.
static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
static const TargetRegisterClass * getRegClassForSVT(MVT::SimpleValueType SVT, bool IsPPC64, bool HasP8Vector, bool HasVSX)
static bool isGPRShadowAligned(MCPhysReg Reg, Align RequiredAlign)
static SDValue DAGCombineAddc(SDNode *N, llvm::PPCTargetLowering::DAGCombinerInfo &DCI)
static bool needStackSlotPassParameters(const PPCSubtarget &Subtarget, const SmallVectorImpl< ISD::OutputArg > &Outs)
std::tuple< uint32_t, uint8_t > LXVKQPattern
static bool isAlternatingShuffMask(const ArrayRef< int > &Mask, int NumElts)
static bool isShuffleMaskInRange(const SmallVectorImpl< int > &ShuffV, int HalfVec, int LHSLastElementDefined, int RHSLastElementDefined)
static SDValue addShuffleForVecExtend(SDNode *N, SelectionDAG &DAG, SDValue Input, uint64_t Elems, uint64_t CorrectElems)
static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool findConsecutiveLoad(LoadSDNode *LD, SelectionDAG &DAG)
static SDValue generateEquivalentSub(SDNode *N, int Size, bool Complement, bool Swap, SDLoc &DL, SelectionDAG &DAG)
This function is called when we have proved that a SETCC node can be replaced by subtraction (and oth...
static unsigned mapArgRegToOffsetAIX(unsigned Reg, const PPCFrameLowering *FL)
static void CalculateTailCallArgDest(SelectionDAG &DAG, MachineFunction &MF, bool IsPPC64, SDValue Arg, int SPDiff, unsigned ArgOffset, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
CalculateTailCallArgDest - Remember Argument for later processing.
static MachineBasicBlock * emitAtomicCmpSwapSoftware(MachineInstr &MI, MachineBasicBlock *BB, const TargetInstrInfo *TII, const PPCSubtarget &Subtarget)
Emit software-emulated atomic compare-and-swap for I8/I16 without hardware partword atomic support.
static SDValue DAGCombineSube(SDNode *N, llvm::PPCTargetLowering::DAGCombinerInfo &DCI)
static SDValue combineADDToMAT_PCREL_ADDR(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setAlignFlagsForFI(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Set alignment flags based on whether or not the Frame Index is aligned.
static bool isTOCSaveRestoreRequired(const PPCSubtarget &Subtarget)
static cl::opt< bool > EnableILPPref("ppc-ilp-pref", cl::desc("Set the node scheduling preference to ILP on PPC"), cl::init(true), cl::Hidden)
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 cl::opt< bool > EnableInnermostLoopAlign32("ppc-innermost-loop-align32", cl::desc("Align innermost loops to 32 bytes on ppc"), cl::init(true), cl::Hidden)
static bool IsSelect(unsigned Opcode, bool CheckOnlyCC=false)
Check if the opcode is a SELECT or SELECT_CC variant.
static bool provablyDisjointOr(SelectionDAG &DAG, const SDValue &N)
Used when computing address flags for selecting loads and stores.
static bool callsShareTOCBase(const Function *Caller, const GlobalValue *CalleeGV, const TargetMachine &TM)
static void prepareOutOfLineGlueCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, SDValue CallSeqStart, const CallBase *CB, const SDLoc &dl, bool hasNest, const PPCSubtarget &Subtarget)
static SDValue generateSToVPermutedForVecShuffle(int ScalarSize, uint64_t ShuffleEltWidth, unsigned &NumValidElts, int FirstElt, int &LastElt, SDValue VecShuffOperand, SDValue SToVNode, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
constexpr uint64_t AIXSmallTlsPolicySizeLimit
static bool isPCRelNode(SDValue N)
static void LowerMemOpCallTo(SelectionDAG &DAG, MachineFunction &MF, SDValue Chain, SDValue Arg, SDValue PtrOff, int SPDiff, unsigned ArgOffset, bool isPPC64, bool isTailCall, bool isVector, SmallVectorImpl< SDValue > &MemOpChains, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments, const SDLoc &dl)
LowerMemOpCallTo - Store the argument to the stack or remember it in case of tail calls.
static cl::opt< unsigned > PPCGatherAllAliasesMaxDepth("ppc-gather-alias-max-depth", cl::init(18), cl::Hidden, cl::desc("max depth when checking alias info in GatherAllAliases()"))
static bool IsSelectCC(unsigned Opcode)
static bool areCallingConvEligibleForTCO_64SVR4(CallingConv::ID CallerCC, CallingConv::ID CalleeCC)
static const MCPhysReg FPR[]
FPR - The set of FP registers that should be allocated for arguments on Darwin and AIX.
static SDNode * isBLACompatibleAddress(SDValue Op, SelectionDAG &DAG)
isCallCompatibleAddress - Return the immediate to use if the specified 32-bit value is representable ...
static Align CalculateStackSlotAlignment(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotAlignment - Calculates the alignment of this argument on the stack.
static SDValue ConvertCarryFlagToCarryValue(EVT SumType, SDValue Flag, EVT CarryType, SelectionDAG &DAG, const PPCSubtarget &STI)
static bool haveEfficientBuildVectorPattern(BuildVectorSDNode *V, bool HasDirectMove, bool HasP8Vector)
Do we have an efficient pattern in a .td file for this node?
static SDValue getSToVPermuted(SDValue OrigSToV, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setUsesTOCBasePtr(MachineFunction &MF)
static SDValue combineXorSelectCC(SDNode *N, SelectionDAG &DAG)
static SDValue transformCallee(const SDValue &Callee, SelectionDAG &DAG, const SDLoc &dl, const PPCSubtarget &Subtarget)
static unsigned EnsureStackAlignment(const PPCFrameLowering *Lowering, unsigned NumBytes)
EnsureStackAlignment - Round stack frame size up from NumBytes to ensure minimum alignment required f...
static SDValue stripModuloOnShift(const TargetLowering &TLI, SDNode *N, SelectionDAG &DAG)
static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth)
static bool hasSameArgumentList(const Function *CallerFn, const CallBase &CB)
static cl::opt< bool > EnablePerfectShuffle("ppc-perfect-shuffle", cl::desc("enable vector permute decomposition"), cl::init(false), cl::Hidden)
static bool isFPExtLoad(SDValue Op)
static SDValue BuildIntrinsicOp(unsigned IID, SDValue Op, SelectionDAG &DAG, const SDLoc &dl, EVT DestVT=MVT::Other)
BuildIntrinsicOp - Return a unary operator intrinsic node with the specified intrinsic ID.
static bool isConsecutiveLSLoc(SDValue Loc, EVT VT, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static bool canConvertToVcmpequb(SDValue &LHS, SDValue &RHS, bool IsPPC64)
static void StoreTailCallArgumentsToStackSlot(SelectionDAG &DAG, SDValue Chain, const SmallVectorImpl< TailCallArgumentInfo > &TailCallArgs, SmallVectorImpl< SDValue > &MemOpChains, const SDLoc &dl)
StoreTailCallArgumentsToStackSlot - Stores arguments to their stack slot.
static cl::opt< bool > UseAbsoluteJumpTables("ppc-use-absolute-jumptables", cl::desc("use absolute jump tables on ppc"), cl::Hidden)
static void setXFormForUnalignedFI(SDValue N, unsigned Flags, PPC::AddrMode &Mode)
static cl::opt< unsigned > PPCMinimumBitTestCmps("ppc-min-bit-test-cmps", cl::init(3), cl::Hidden, cl::desc("Set minimum of largest number of comparisons to use bit test for " "switch on PPC."))
static CallInst * callIntrinsic(IRBuilderBase &Builder, Intrinsic::ID Id)
static void getMaxByValAlign(Type *Ty, Align &MaxAlign, Align MaxMaxAlign)
getMaxByValAlign - Helper for getByValTypeAlignment to determine the desired ByVal argument alignment...
static bool isConsecutiveLS(SDNode *N, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static bool isVMerge(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned LHSStart, unsigned RHSStart)
isVMerge - Common function, used to match vmrg* shuffles.
static void getLabelAccessInfo(bool IsPIC, const PPCSubtarget &Subtarget, unsigned &HiOpFlags, unsigned &LoOpFlags, const GlobalValue *GV=nullptr)
Return true if we should reference labels using a PICBase, set the HiOpFlags and LoOpFlags to the tar...
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 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 std::optional< LXVKQPattern > getPatternInfo(const APInt &FullVal)
static void fixupFuncForFI(SelectionDAG &DAG, int FrameIdx, EVT VT)
static SDValue ConvertSETCCToXori(SDNode *N, SelectionDAG &DAG)
static Intrinsic::ID getIntrinsicForAtomicRMWBinOp128(AtomicRMWInst::BinOp BinOp)
static SDValue convertFPToInt(SDValue Op, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static unsigned CalculateStackSlotSize(EVT ArgVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotSize - Calculates the size reserved for this argument on the stack.
static int CalculateTailCallSPDiff(SelectionDAG &DAG, bool isTailCall, unsigned ParamSize)
CalculateTailCallSPDiff - Get the amount the stack pointer has to be adjusted to accommodate the argu...
static void prepareIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, const SDLoc &dl)
static cl::opt< bool > EnableP10StoreForward("ppc-p10-store-forward", cl::desc("enable P10 store forward-friendly conversion"), cl::init(true), cl::Hidden)
static SDValue combineSELECT_CCBitFloor(SDNode *N, SelectionDAG &DAG)
Optimize the bitfloor(X) pattern for PowerPC.
static SDValue LowerLabelRef(SDValue HiPart, SDValue LoPart, bool isPIC, SelectionDAG &DAG)
static SDValue isScalarToVec(SDValue Op)
static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl)
bool isValidMtVsrBmi(APInt &BitMask, BuildVectorSDNode &BVN, bool IsLittleEndian)
static MachineBasicBlock * emitSelect(MachineInstr &MI, MachineBasicBlock *BB, const TargetInstrInfo *TII, const PPCSubtarget &Subtarget)
Emit SELECT instruction, using ISEL if available, otherwise use branch-based control flow.
static bool getVectorCompareInfo(SDValue Intrin, int &CompareOpc, bool &isDot, const PPCSubtarget &Subtarget)
getVectorCompareInfo - Given an intrinsic, return false if it is not a vector comparison.
static unsigned invertFMAOpcode(unsigned Opc)
static SDValue combineADDToSUB(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static const SDValue * getNormalLoadInput(const SDValue &Op, bool &IsPermuted)
static bool canConvertSETCCToXori(SDNode *N)
static cl::opt< unsigned > PPCMinimumJumpTableEntries("ppc-min-jump-table-entries", cl::init(64), cl::Hidden, cl::desc("Set minimum number of entries to use a jump table on PPC"))
static bool isValidSplatLoad(const PPCSubtarget &Subtarget, const SDValue &Op, unsigned &Opcode)
static SDValue ConvertCarryValueToCarryFlag(EVT SumType, SDValue Value, SelectionDAG &DAG, const PPCSubtarget &STI)
static SDValue convertIntToFP(SDValue Op, SDValue Src, SelectionDAG &DAG, const PPCSubtarget &Subtarget, SDValue Chain=SDValue())
cl::opt< bool > EnableAutoPairedVecSt("ppc-auto-paired-vec-st", cl::desc("enable automatically generated 32byte paired vector stores"), cl::init(false), cl::Hidden)
static cl::opt< bool > EnableSCO("ppc-sco", cl::desc("enable sibling call optimization on ppc"), cl::init(true), cl::Hidden)
static void PrepareTailCall(SelectionDAG &DAG, SDValue &InGlue, SDValue &Chain, const SDLoc &dl, int SPDiff, unsigned NumBytes, SDValue LROp, SDValue FPOp, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
static SDValue EmitTailCallStoreFPAndRetAddr(SelectionDAG &DAG, SDValue Chain, SDValue OldRetAddr, SDValue OldFP, int SPDiff, const SDLoc &dl)
EmitTailCallStoreFPAndRetAddr - Move the frame pointer and return address to the appropriate stack sl...
static SDValue BuildVSLDOI(SDValue LHS, SDValue RHS, unsigned Amt, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
BuildVSLDOI - Return a VECTOR_SHUFFLE that is a vsldoi of the specified amount.
static void createAtomicLoopBlocks(MachineFunction *F, MachineBasicBlock *BB, MachineBasicBlock *&loop1MBB, MachineBasicBlock *&loop2MBB, MachineBasicBlock *&exitMBB, MachineInstr &MI, MachineFunction::iterator It)
Helper function to create basic blocks for atomic compare-and-swap.
cl::opt< bool > EnablePPCGenScalarMASSEntries
static SDValue combineBVZEXTLOAD(SDNode *N, SelectionDAG &DAG)
static SDValue combineZextSetccWithZero(SDNode *N, SelectionDAG &DAG)
static SDValue truncateScalarIntegerArg(ISD::ArgFlagsTy Flags, EVT ValVT, SelectionDAG &DAG, SDValue ArgValue, MVT LocVT, const SDLoc &dl)
static void computeFlagsForAddressComputation(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Given a node, compute flags that are used for address computation when selecting load and store instr...
static MachineBasicBlock * emitAtomicCmpSwapHardware(MachineInstr &MI, MachineBasicBlock *BB, const TargetInstrInfo *TII, const PPCSubtarget &Subtarget)
Emit hardware-supported atomic compare-and-swap for I32/I64 and I8/I16 with partword atomic support.
SDValue convertTwoLoadsAndCmpToVCMPEQUB(SelectionDAG &DAG, SDNode *N, const SDLoc &DL)
static SDValue getOutputChainFromCallSeq(SDValue CallSeqStart)
static bool CalculateStackSlotUsed(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize, unsigned LinkageSize, unsigned ParamAreaSize, unsigned &ArgOffset, unsigned &AvailableFPRs, unsigned &AvailableVRs)
CalculateStackSlotUsed - Return whether this argument will use its stack slot (instead of being passe...
static void signExtendOperandIfUnknown(MachineInstr &MI, MachineBasicBlock *BB, unsigned OpIdx, bool IsByte, const PPCInstrInfo *TII)
static cl::opt< unsigned > PPCAIXTLSModelOptUseIEForLDLimit("ppc-aix-shared-lib-tls-model-opt-limit", cl::init(1), cl::Hidden, cl::desc("Set inclusive limit count of TLS local-dynamic access(es) in a " "function to use initial-exec"))
static unsigned getPPCStrictOpcode(unsigned Opc)
static void prepareDescriptorIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, SDValue CallSeqStart, const CallBase *CB, const SDLoc &dl, bool hasNest, const PPCSubtarget &Subtarget)
static bool isXXBRShuffleMaskHelper(ShuffleVectorSDNode *N, int Width)
static bool isFunctionGlobalAddress(const GlobalValue *CalleeGV)
static cl::opt< bool > EnablePPCPreinc("ppc-preinc", cl::desc("enable preincrement load/store generation on PPC"), cl::init(true), cl::Hidden)
static bool isSplatBV(SDValue Op)
static SDValue combineBVOfVecSExt(SDNode *N, SelectionDAG &DAG)
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 cl::opt< bool > EnablePPCUnaligned("ppc-unaligned", cl::desc("enable unaligned load/store generation on PPC"), cl::init(true), cl::Hidden)
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
SmallVector< MachineOperand, 4 > Cond
MachineRegisterInfo & MRI
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
SI optimize exec mask operations pre RA
static const MCExpr * MaskShift(const MCExpr *Val, uint32_t Mask, uint32_t Shift, MCContext &Ctx)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG, const SparcSubtarget *Subtarget)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
This file describes how to lower LLVM code to machine code.
static constexpr int TPOffset
static const fltSemantics & IEEEsingle()
static constexpr roundingMode rmTowardZero
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & PPCDoubleDouble()
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
APInt bitcastToAPInt() const
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) const
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
bool isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
uint64_t getZExtValue() const
Get zero extended value.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
APInt abs() const
Get the absolute value.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool ult(const APInt &RHS) const
Unsigned less than comparison.
bool isNegative() const
Determine sign of this APInt.
void clearAllBits()
Set every bit to 0.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
LLVM_ABI void insertBits(const APInt &SubBits, unsigned bitPosition)
Insert the bits from a smaller APInt starting at bitPosition.
bool getBoolValue() const
Convert APInt to a boolean value.
double bitsToDouble() const
Converts APInt bits to a double.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
LLVM_ABI APInt extractBits(unsigned numBits, unsigned bitPosition) const
Return an APInt with the extracted bits [bitPosition,bitPosition+numBits).
An arbitrary precision integer that knows its signedness.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
An instruction that atomically checks whether a specified value is in a memory location,...
Value * getNewValOperand()
an instruction that atomically reads a memory location, combines it with another value,...
BinOp
This enumeration lists the possible modifications atomicrmw can make.
@ USubCond
Subtract only if no unsigned overflow.
@ USubSat
*p = usub.sat(old, v) usub.sat matches the behavior of llvm.usub.sat.
@ UIncWrap
Increment one up to a maximum value.
@ UDecWrap
Decrement one until a minimum value or zero.
BinOp getOperation() const
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
LLVM Basic Block Representation.
int64_t getOffset() const
const BlockAddress * getBlockAddress() const
static constexpr BranchProbability getOne()
static constexpr BranchProbability getZero()
A "pseudo-class" with methods for operating on BUILD_VECTORs.
LLVM_ABI bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
CCState - This class holds information needed while lowering arguments and return values.
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP)
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
int64_t getLocMemOffset() const
unsigned getValNo() const
static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool isStrictFP() const
Determine if the call requires strict floating point semantics.
CallingConv::ID getCallingConv() const
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
Value * getCalledOperand() const
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
unsigned arg_size() const
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
This class represents a function call, abstracting a target machine's calling convention.
ConstantFP - Floating Point Values [float, double].
const Constant * getConstVal() const
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
int64_t getSExtValue() const
This is an important base class in LLVM.
uint64_t getNumOperands() const
A parsed version of the target data layout string in and methods for querying it.
bool isLittleEndian() const
Layout endianness...
LLVM_ABI unsigned getLargestLegalIntTypeSizeInBits() const
Returns the size of largest legal integer type size, or 0 if none are set.
LLVM_ABI IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
LLVM_ABI Align getABITypeAlign(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
LLVM_ABI TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
AttributeList getAttributes() const
Return the attribute list for this Function.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Type * getReturnType() const
Returns the type of the ret val.
const Argument * const_arg_iterator
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
int64_t getOffset() const
unsigned getTargetFlags() const
const GlobalValue * getGlobal() const
LLVM_ABI const GlobalObject * getAliaseeObject() const
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
void setThreadLocalMode(ThreadLocalMode Val)
bool hasHiddenVisibility() const
LLVM_ABI StringRef getSection() const
Module * getParent()
Get the module that this global value is contained inside of...
bool isStrongDefinitionForLinker() const
Returns true if this global's definition will be the one chosen by the linker.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
Type * getValueType() const
bool hasProtectedVisibility() const
Common base class shared among various IRBuilders.
LLVM_ABI bool hasAtomicLoad() const LLVM_READONLY
Return true if this atomic instruction loads from memory.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
This is an important class for using LLVM in a threaded context.
Base class for LoadSDNode and StoreSDNode.
Tracks which library functions to use for a particular subtarget or function.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
TypeSize getValue() const
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
Wrapper class representing physical registers. Should be passed by value.
MCSymbolXCOFF * getQualNameSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
@ INVALID_SIMPLE_VALUE_TYPE
uint64_t getScalarSizeInBits() const
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
void setCallFrameSize(unsigned N)
Set the call frame size on entry to this basic block.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
LLVM_ABI int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setHasTailCall(bool V=true)
void setReturnAddressIsTaken(bool s)
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool hasVAStart() const
Returns true if the function calls the llvm.va_start intrinsic.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
MCSymbol * getPICBaseSymbol() const
getPICBaseSymbol - Return a function-local symbol to represent the PIC base.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
@ EK_LabelDifference32
EK_LabelDifference32 - Each entry is the address of the block minus the address of the jump table.
A description of a memory reference used in the backend.
LocationSize getSize() const
Return the size in bytes of the memory reference.
AtomicOrdering getFailureOrdering() const
For cmpxchg atomic operations, return the atomic ordering requirements when store does not occur.
SyncScope::ID getSyncScopeID() const
Returns the synchronization scope ID for this memory operation.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
AtomicOrdering getSuccessOrdering() const
Return the atomic ordering requirements for this memory operation.
const MachinePointerInfo & getPointerInfo() const
Flags getFlags() const
Return the raw flags of the source value,.
LLVM_ABI Align getAlign() const
Return the minimum known alignment in bytes of the actual memory reference.
AAMDNodes getAAInfo() const
Return the AA tags for the memory reference.
MachineOperand class - Representation of each machine instruction operand.
static MachineOperand CreateImm(int64_t Val)
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI 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 the unique MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getBasePtr() const
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
unsigned getLinkageSize() const
getLinkageSize - Return the size of the PowerPC ABI linkage area.
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 isUsingPCRelativeCalls() const
const PPCRegisterInfo * getRegisterInfo() const override
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
CCAssignFn * ccAssignFnForCall(CallingConv::ID CC, bool Return, bool IsVarArg) const
bool isTruncateFree(Type *Ty1, Type *Ty2) const override
isTruncateFree - Return true if it's free to truncate a value of type Ty1 to type Ty2.
Value * emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI, Value *AlignedAddr, Value *Incr, Value *Mask, Value *ShiftAmt, AtomicOrdering Ord) const override
Perform a masked atomicrmw using a target-specific intrinsic.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
bool isFPExtFree(EVT DestVT, EVT SrcVT) const override
Return true if an fpext operation is free (for instance, because single-precision floating-point numb...
PPC::AddrMode SelectForceXFormMode(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
SelectForceXFormMode - Given the specified address, force it to be represented as an indexed [r+r] op...
Instruction * emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
TargetLowering::AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
bool hasInlineStackProbe(const MachineFunction &MF) const override
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
bool supportsTailCallFor(const CallBase *CB) const
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
MachineBasicBlock * emitProbedAlloca(MachineInstr &MI, MachineBasicBlock *MBB) const
bool isZExtFree(SDValue Val, EVT VT2) const override
Return true if zero-extending the specific node Val to type VT2 is free (either because it's implicit...
SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const override
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
bool SelectAddressRegImm(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign EncodingAlignment) const
SelectAddressRegImm - Returns true if the address N can be represented by a base register plus a sign...
SDValue expandVSXLoadForLE(SDNode *N, DAGCombinerInfo &DCI) const
bool splitValueIntoRegisterParts(SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts, unsigned NumParts, MVT PartVT, std::optional< CallingConv::ID > CC) const override
Target-specific splitting of values into parts that fit a register storing a legal type.
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
LowerAsmOperandForConstraint - Lower the specified operand into the Ops vector.
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
ReplaceNodeResults - Replace the results of node with an illegal result type with new values built ou...
bool hasMultipleConditionRegisters(EVT VT) const override
Does the target have multiple (allocatable) condition registers that can be used to store the results...
Align getByValTypeAlignment(Type *Ty, const DataLayout &DL) const override
getByValTypeAlignment - Return the desired alignment for ByVal aggregate function arguments in the ca...
bool SelectAddressRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG, MaybeAlign EncodingAlignment=std::nullopt) const
SelectAddressRegReg - Given the specified addressed, check to see if it can be more efficiently repre...
SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, SmallVectorImpl< SDNode * > &Created) const override
Targets may override this function to provide custom SDIV lowering for power-of-2 denominators.
Value * emitStoreConditional(IRBuilderBase &Builder, Value *Val, Value *Addr, AtomicOrdering Ord) const override
Perform a store-conditional operation to Addr.
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
bool SelectAddressRegRegOnly(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressRegRegOnly - Given the specified addressed, force it to be represented as an indexed [r+...
bool useSoftFloat() const override
SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const override
Returns relocation base for the given PIC jumptable.
Register getExceptionSelectorRegister(ExceptionHandling EH, const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
TargetLowering::AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(const AtomicCmpXchgInst *AI) const override
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
Value * emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder, AtomicCmpXchgInst *CI, Value *AlignedAddr, Value *CmpVal, Value *NewVal, Value *Mask, AtomicOrdering Ord) const override
Perform a masked cmpxchg using a target-specific intrinsic.
ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
bool enableAggressiveFMAFusion(EVT VT) const override
Return true if target always benefits from combining into FMA for a given value type.
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
bool decomposeMulByConstant(LLVMContext &Context, EVT VT, SDValue C) const override
Return true if it is profitable to transform an integer multiplication-by-constant into simpler opera...
void getTgtMemIntrinsic(SmallVectorImpl< IntrinsicInfo > &Infos, const CallBase &I, MachineFunction &MF, unsigned Intrinsic) const override
Given an intrinsic, checks if on the target the intrinsic will need to map to a MemIntrinsicNode (tou...
unsigned getJumpTableEncoding() const override
Return the entry encoding for a jump table in the current function.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
isLegalAddressingMode - Return true if the addressing mode represented by AM is legal for this target...
bool preferIncOfAddToSubOfNot(EVT VT) const override
These two forms are equivalent: sub y, (xor x, -1) add (add x, 1), y The variant with two add's is IR...
bool shouldConvertConstantLoadToIntImm(const APInt &Imm, Type *Ty) const override
Returns true if it is beneficial to convert a load of a constant to just the constant itself.
const MCPhysReg * getScratchRegisters(CallingConv::ID CC) const override
Returns a 0 terminated array of registers that can be safely used as scratch registers.
bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const override
getPreIndexedAddressParts - returns true by value, base pointer and offset pointer and addressing mod...
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo, const LibcallLoweringInfo *LibcallLowering) const override
createFastISel - This method returns a target-specific FastISel object, or null if the target does no...
bool isProfitableToHoist(Instruction *I) const override
isProfitableToHoist - Check if it is profitable to hoist instruction I to its dominator block.
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.
bool fenceClearsLoadLinkedReservation() const override
True unless the subtarget has FeatureFenceKeepsReservation.
const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const override
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
bool shallExtractConstSplatVectorElementToStore(Type *VectorTy, unsigned ElemSizeInBits, unsigned &Index) const override
Return true if the target shall perform extract vector element and store given that the vector is kno...
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op, const AttributeList &FuncAttributes) const override
It returns EVT::Other if the type should be determined using generic target-independent logic.
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
SDValue expandVSXStoreForLE(SDNode *N, DAGCombinerInfo &DCI) const
void CollectTargetIntrinsicOperands(const CallInst &I, SmallVectorImpl< SDValue > &Ops, SelectionDAG &DAG) const override
unsigned getStackProbeSize(const MachineFunction &MF) const
Register getExceptionPointerRegister(ExceptionHandling EH, const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
PPCTargetLowering(const PPCTargetMachine &TM, const PPCSubtarget &STI)
Align getPrefLoopAlignment(MachineLoop *ML, const MachineBasicBlock *BlockToAlign) const override
Return the preferred loop alignment.
bool useLoadStackGuardNode(const Module &M) const override
Override to support customized stack guard loading.
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster than a pair of fmul and fadd i...
MachineBasicBlock * EmitAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned BinOpcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const override
Is unaligned memory access allowed for the given type, and is it fast relative to software emulation.
bool shouldExpandBuildVectorWithShuffles(EVT VT, unsigned DefinedValues) const override
bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
Similar to the 16-bit case but for instructions that take a 34-bit displacement field (prefixed loads...
FPImmAction getFPImmAction(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns how the legalizer should materialize the specified FP immediate.
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
bool isJumpTableRelative() const override
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
PPC::AddrMode SelectOptimalAddrMode(const SDNode *Parent, SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign Align) const
SelectOptimalAddrMode - Based on a node N and it's Parent (a MemSDNode), compute the address flags of...
bool SelectAddressPCRel(SDValue N, SDValue &Base) const
SelectAddressPCRel - Represent the specified address as pc relative to be represented as [pc+imm].
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the ISD::SETCC ValueType
bool SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressEVXRegReg - Given the specified addressed, check to see if it can be more efficiently re...
bool isLegalICmpImmediate(int64_t Imm) const override
isLegalICmpImmediate - Return true if the specified immediate is legal icmp immediate,...
MachineBasicBlock * EmitPartwordAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned Opcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
bool isAccessedAsGotIndirect(SDValue N) const
bool shouldInlineQuadwordAtomics() const
Instruction * emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Inserts in the IR a target-specific intrinsic specifying a fence.
bool isLegalAddImmediate(int64_t Imm) const override
isLegalAddImmediate - Return true if the specified immediate is legal add immediate,...
Common code between 32-bit and 64-bit PowerPC targets.
static PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
Wrapper class representing virtual and physical registers.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
This class provides iterator support for SDUse operands that use a specific SDNode.
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
LLVM_ABI void dump() const
Dump this node, for debugging.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
iterator_range< value_op_iterator > op_values() const
iterator_range< use_iterator > uses()
SDNodeFlags getFlags() const
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
user_iterator user_begin() const
Provide iteration support to walk over all users of an SDNode.
static use_iterator use_end()
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node, in exactly one operand.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
bool isMachineOpcode() const
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
ISD::CondCode getOperandCondCode(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getMachineOpcode() const
unsigned getOpcode() const
unsigned getNumOperands() const
static SectionKind getMetadata()
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
LLVM_ABI SDValue getStackArgumentTokenFactor(SDValue Chain)
Compute a TokenFactor to force all the incoming stack arguments to be loaded from the stack.
const TargetSubtargetInfo & getSubtarget() const
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDValue getFreeze(SDValue V)
Return a freeze using the SDLoc of the value operand.
LLVM_ABI SDValue makeEquivalentMemoryOrdering(SDValue OldChain, SDValue NewMemOpChain)
If an existing load has uses of its chain, create a token factor node with that chain and the new mem...
LLVM_ABI bool areNonVolatileConsecutiveLoads(LoadSDNode *LD, LoadSDNode *Base, TypeSize Bytes, int Dist) const
Return true if loads are next to each other and can be merged.
LLVM_ABI SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, LocationSize Size=LocationSize::precise(0), const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false, SDNodeFlags Flags={})
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
bool willNotOverflowSub(bool IsSigned, SDValue N0, SDValue N1) const
Determine if the result of the sub of 2 nodes can never overflow.
LLVM_ABI Align getEVTAlign(EVT MemoryVT) const
Compute the default alignment value for the given type.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
LLVM_ABI SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align DstAlign, Align SrcAlign, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
const TargetLowering & getTargetLoweringInfo() const
static constexpr unsigned MaxRecursionDepth
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
LLVM_ABI bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
LLVM_ABI SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, SDValue Offset, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
LLVM_ABI SDValue getTokenFactor(const SDLoc &DL, SmallVectorImpl< SDValue > &Vals)
Creates a new TokenFactor containing Vals.
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI SDValue getMDNode(const MDNode *MD)
Return an MDNodeSDNode which holds an MDNode.
LLVM_ABI void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
LLVM_ABI SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV)
Returns an ISD::VECTOR_SHUFFLE node semantically equivalent to the shuffle node in input but with swa...
LLVM_ABI SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
LLVM_ABI bool SignBitIsZero(SDValue Op, unsigned Depth=0) const
Return true if the sign bit of Op is known to be zero.
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
LLVM_ABI SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI bool isKnownNeverZero(SDValue Op, unsigned Depth=0) const
Test whether the given SDValue is known to contain non-zero value(s).
LLVM_ABI SDValue getBoolExtOrTrunc(SDValue Op, const SDLoc &SL, EVT VT, EVT OpVT)
Convert Op, which must be of integer type, to the integer type VT, by using an extension appropriate ...
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
LLVM_ABI SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
LLVM_ABI SDValue getBoolConstant(bool V, const SDLoc &DL, EVT VT, EVT OpVT)
Create a true or false constant of type VT using the target's BooleanContent for type OpVT.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
LLVM_ABI bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
LLVM_ABI SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVM_ABI SDValue getCondCode(ISD::CondCode Cond)
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
LLVM_ABI SDValue getMCSymbol(MCSymbol *Sym, EVT VT)
LLVM_ABI SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
LLVM_ABI std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
LLVM_ABI SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
int getMaskElt(unsigned Idx) const
ArrayRef< int > getMask() const
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getValue() const
Represent a constant reference to a string, i.e.
constexpr size_t size() const
Get the string size.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
Class to represent struct types.
Information about stack frame layout on the target.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
virtual bool isShuffleMaskLegal(ArrayRef< int >, EVT) const
Targets can use this to indicate that they only support some VECTOR_SHUFFLE operations,...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual bool shouldExpandBuildVectorWithShuffles(EVT, unsigned DefinedValues) const
void setMinimumBitTestCmps(unsigned Val)
Set the minimum of largest of number of comparisons to generate BitTest.
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
MachineBasicBlock * emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const
Replace/modify any TargetFrameIndex operands with a targte-dependent sequence of memory operands that...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
virtual AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *RMW) const
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
virtual Align getPrefLoopAlignment(MachineLoop *ML=nullptr, const MachineBasicBlock *BlockToAlign=nullptr) const
Return the preferred loop alignment.
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.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
void setIndexedStoreAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed store does or does not work with the specified type and indicate ...
virtual bool isJumpTableRelative() const
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setMinimumJumpTableEntries(unsigned Val)
Indicate the minimum number of blocks to generate jump tables.
void setPartialReduceMLAAction(unsigned Opc, MVT AccVT, MVT InputVT, LegalizeAction Action)
Indicate how a PARTIAL_REDUCE_U/SMLA node with Acc type AccVT and Input type InputVT should be treate...
FPImmAction
How the legalizer should materialize a floating-point immediate.
@ ConstantPool
Load the immediate from the constant pool.
@ Legal
The target can instruction select the immediate natively.
@ Bitcast
Build the immediate as a bitcast of an integer constant with the same bits.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
unsigned MaxLoadsPerMemcmpOptSize
Likewise for functions with the OptSize attribute.
void setMinCmpXchgSizeInBits(unsigned SizeInBits)
Sets the minimum cmpxchg or ll/sc size supported by the backend.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
unsigned GatherAllAliasesMaxDepth
Depth that GatherAllAliases should continue looking for chain dependencies when trying to find a more...
NegatibleCost
Enum that specifies when a float negation is beneficial.
std::vector< ArgListEntry > ArgListTy
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
void setJumpIsExpensive(bool isExpensive=true)
Tells the code generator not to expand logic operations on comparison predicates into separate sequen...
virtual MCSymbol * getFunctionEntryPointSymbol(const GlobalValue *Func, const TargetMachine &TM) const
If supported, return the function entry point symbol.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
SDValue lowerCmpEqZeroToCtlzSrl(SDValue Op, SelectionDAG &DAG) const
void softenSetCCOperands(SelectionDAG &DAG, EVT VT, SDValue &NewLHS, SDValue &NewRHS, ISD::CondCode &CCCode, const SDLoc &DL, const SDValue OldLHS, const SDValue OldRHS) const
Soften the operands of a comparison.
SDValue getCheaperNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, unsigned Depth=0) const
This is the helper function to return the newly negated expression only when the cost is cheaper.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool isPositionIndependent() const
virtual SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const
Returns relocation base for the given PIC jumptable.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
TargetLowering(const TargetLowering &)=delete
virtual SDValue getSqrtResultForDenormInput(SDValue Operand, SelectionDAG &DAG) const
Return a target-dependent result if the input operand is not suitable for use with a square root esti...
virtual bool useLoadStackGuardNode(const Module &M) const
If this function returns true, SelectionDAGBuilder emits a LOAD_STACK_GUARD node when it is lowering ...
virtual unsigned combineRepeatedFPDivisors() const
Indicate whether this target prefers to combine FDIVs with the same divisor.
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
virtual SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG, const DenormalMode &Mode, SDNodeFlags Flags={}) const
Return a target-dependent comparison result if the input operand is suitable for use with a square ro...
virtual 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.
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
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
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 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)
bool isSized() const
Return true if it makes sense to take the size of this type.
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 isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isFunctionTy() const
True if this is an instance of FunctionType.
bool isIntegerTy() const
True if this is an instance of IntegerType.
A Use represents the edge between a Value definition and its users.
User * getUser() const
Returns the User that contains this Use.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI bool isConstantSplatVectorAllOnes(const SDNode *N, bool BuildVectorOnly=false)
Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where all of the elements are ~0 ...
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
@ PARTIAL_REDUCE_SMLA
PARTIAL_REDUCE_[U|S]MLA(Accumulator, Input1, Input2) The partial reduction nodes sign or zero extend ...
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ BSWAP
Byte Swap and Counting operators.
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ INIT_TRAMPOLINE
INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ SET_ROUNDING
Set rounding mode.
@ SIGN_EXTEND
Conversion operators.
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ BR
Control flow instructions. These all have token chains.
@ PREFETCH
PREFETCH - This corresponds to a prefetch intrinsic.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ SSUBO
Same for subtraction.
@ BR_JT
BR_JT - Jumptable branch.
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ GET_ROUNDING
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Same as FMINNUM/FMAXNUM, except that a signaling NaN operand deterministi...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
@ 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) ...
@ FMINNUM
FMINNUM/FMAXNUM - Same semantics as the llvm.minnum/maxnum intrinsics.
@ 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...
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ INLINEASM
INLINEASM - Represents an inline asm block.
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ CALLSEQ_START
CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of a call sequence,...
@ GET_DYNAMIC_AREA_OFFSET
GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of the most recent dynamic alloca.
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ ADJUST_TRAMPOLINE
ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
bool isEXTLoad(const SDNode *N)
Returns true if the specified node is a EXTLOAD.
LLVM_ABI bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
bool isSEXTLoad(const SDNode *N)
Returns true if the specified node is a SEXTLOAD.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
bool isUnsignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs an unsigned comparison when used with intege...
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
This namespace contains an enum with a value for every intrinsic/builtin function known by LLVM.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
@ MO_TLSLDM_FLAG
MO_TLSLDM_FLAG - on AIX the ML relocation type is only valid for a reference to a TOC symbol from the...
@ MO_PIC_LO_FLAG
MO_PIC_LO_FLAG = MO_PIC_FLAG | MO_LO.
@ MO_TPREL_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TPREL_FLAG.
@ MO_GOT_TPREL_PCREL_FLAG
MO_GOT_TPREL_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_GOT_PCREL_FLAG
MO_GOT_PCREL_FLAG = MO_PCREL_FLAG | MO_GOT_FLAG.
@ MO_TLSGDM_FLAG
MO_TLSGDM_FLAG - If this bit is set the symbol reference is relative to the region handle of TLS Gene...
@ MO_PCREL_FLAG
MO_PCREL_FLAG - If this bit is set, the symbol reference is relative to the current instruction addre...
@ MO_TLSLD_FLAG
MO_TLSLD_FLAG - If this bit is set the symbol reference is relative to TLS Local Dynamic model.
@ MO_TLS_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TLS.
@ MO_PLT
On PPC, the 12 bits are not enough for all target operand flags.
@ MO_TLS
Symbol for VK_TLS fixup attached to an ADD instruction.
@ MO_TPREL_FLAG
MO_TPREL_FLAG - If this bit is set, the symbol reference is relative to the thread pointer and the sy...
@ MO_LO
MO_LO, MO_HA - lo16(symbol) and ha16(symbol)
@ MO_GOT_TLSLD_PCREL_FLAG
MO_GOT_TLSLD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_HA_FLAG
MO_PIC_HA_FLAG = MO_PIC_FLAG | MO_HA.
@ MO_TLSGD_FLAG
MO_TLSGD_FLAG - If this bit is set the symbol reference is relative to TLS General Dynamic model for ...
@ MO_GOT_TLSGD_PCREL_FLAG
MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_FLAG
MO_PIC_FLAG - If this bit is set, the symbol reference is relative to the function's picbase,...
@ MFOCRF
R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
@ VADD_SPLAT
VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded during instruction selection to optimi...
@ PPC32_PICGOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
@ SRA_ADDZE
The combination of sra[wd]i and addze used to implemented signed integer division by a power of 2.
Define some predicates that are used for node matching.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
SDValue get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG)
get_VSPLTI_elt - If this is a build_vector of constants which can be formed by using a vspltis[bhw] i...
bool isXXBRDShuffleMask(ShuffleVectorSDNode *N)
isXXBRDShuffleMask - Return true if this is a shuffle mask suitable for a XXBRD instruction.
bool isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for a VRGH* instruction with the ...
bool isVPKUDUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUDUMShuffleMask - Return true if this is the shuffle mask for a VPKUDUM instruction.
bool isVMRGEOShuffleMask(ShuffleVectorSDNode *N, bool CheckEven, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGEOShuffleMask - Return true if this is a shuffle mask suitable for a VMRGEW or VMRGOW instructi...
bool isXXBRQShuffleMask(ShuffleVectorSDNode *N)
isXXBRQShuffleMask - Return true if this is a shuffle mask suitable for a XXBRQ instruction.
bool isXXBRWShuffleMask(ShuffleVectorSDNode *N)
isXXBRWShuffleMask - Return true if this is a shuffle mask suitable for a XXBRW instruction.
bool isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXPERMDIShuffleMask - Return true if this is a shuffle mask suitable for a XXPERMDI instruction.
bool isXXBRHShuffleMask(ShuffleVectorSDNode *N)
isXXBRHShuffleMask - Return true if this is a shuffle mask suitable for a XXBRH instruction.
unsigned getSplatIdxForPPCMnemonics(SDNode *N, unsigned EltSize, SelectionDAG &DAG)
getSplatIdxForPPCMnemonics - Return the splat index as a value that is appropriate for PPC mnemonics ...
bool isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXSLDWIShuffleMask - Return true if this is a shuffle mask suitable for a XXSLDWI instruction.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo, const LibcallLoweringInfo *LibcallLowering)
int isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift amount, otherwise return -1.
bool isVMRGLShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for a VRGL* instruction with the ...
bool isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, unsigned &InsertAtByte, bool &Swap, bool IsLE)
isXXINSERTWMask - Return true if this VECTOR_SHUFFLE can be handled by the XXINSERTW instruction intr...
bool isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize)
isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand specifies a splat of a singl...
bool isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a VPKUWUM instruction.
bool isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a VPKUHUM instruction.
Invariant opcodes: All instruction sets have these as their low opcodes.
@ XTY_ER
External reference.
initializer< Ty > init(const Ty &Val)
constexpr uint64_t PointerSize
aarch64 pointer size.
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
NodeAddr< NodeBase * > Node
NodeAddr< FuncNode * > Func
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
static bool isIndirectCall(const MachineInstr &MI)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool checkConvertToNonDenormSingle(APFloat &ArgAPFloat)
LLVM_ABI void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
RelativeUniformCounterPtr Values
@ Known
Known to have no common set bits.
LLVM_ABI SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
bool isIntS16Immediate(SDNode *N, int16_t &Imm)
isIntS16Immediate - This method tests to see if the node is either a 32-bit or 64-bit immediate,...
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
static bool isRunOfOnes64(uint64_t Val, unsigned &MB, unsigned &ME)
bool isa_and_nonnull(const Y &Val)
bool RetCC_PPC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
bool CC_PPC64_ELF(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
unsigned M1(unsigned Val)
bool isReleaseOrStronger(AtomicOrdering AO)
auto dyn_cast_or_null(const Y &Val)
constexpr bool has_single_bit(T Value) noexcept
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
bool convertToNonDenormSingle(APInt &ArgAPInt)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
bool CC_PPC32_SVR4_ByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
bool CC_PPC32_SVR4(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
constexpr RegState getDefRegState(bool B)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
bool RetCC_PPC_Cold(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
@ Success
The lock was released successfully.
LLVM_ABI bool isOneOrOneSplat(SDValue V, bool AllowUndefs=false)
Return true if the value is a constant 1 integer or a splatted vector of a constant 1 integer (with n...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
const unsigned PerfectShuffleTable[6561+1]
AtomicOrdering
Atomic ordering for LLVM's memory model.
bool isIntS34Immediate(SDNode *N, int64_t &Imm)
isIntS34Immediate - This method tests if value of node given can be accurately represented as a sign ...
To bit_cast(const From &from) noexcept
@ Mul
Product of integers.
@ Xor
Bitwise or logical XOR of integers.
@ And
Bitwise or logical AND of integers.
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
@ Fast
Assign the register banks as fast as possible (default).
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
LLVM_ABI bool isPhysRegUsedAfter(Register Reg, MachineBasicBlock::iterator MBI)
Check if physical register Reg is used after MBI.
unsigned M0(unsigned Val)
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
bool isAcquireOrStronger(AtomicOrdering AO)
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
constexpr unsigned BitWidth
bool CC_PPC32_SVR4_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME)
Returns true iff Val consists of one contiguous run of 1s with any number of 0s on either side.
@ Increment
Incrementally increasing token ID.
@ Enabled
Convert any .debug_str_offsets tables to DWARF64 if needed.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
@ End
Run the machine verifier once, at the end of the pipeline.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
MCRegisterClass TargetRegisterClass
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This is used by foldLoadsRecursive() to capture a Root Load node which is of type or(load,...
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Represent subnormal handling kind for floating point instruction inputs and outputs.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool bitsLT(EVT VT) const
Return true if this has less bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
unsigned getByValSize() const
void setByValSize(unsigned S)
Align getNonZeroByValAlign() const
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
bool isConstant() const
Returns true if we know the value of all bits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Structure that collects some common arguments that get passed around between the functions for call l...
const CallingConv::ID CallConv
These are IR-level optimization flags that may be propagated to SDNodes.
void setNoFPExcept(bool b)
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
CallLoweringInfo & setIsPostTypeLegalization(bool Value=true)
CallLoweringInfo & setLibCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setZExtResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setTailCall(bool Value=true)
CallLoweringInfo & setSExtResult(bool Value=true)
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
CallLoweringInfo & setChain(SDValue InChain)
bool isBeforeLegalizeOps() const
bool isAfterLegalizeDAG() const
LLVM_ABI void AddToWorklist(SDNode *N)
bool isBeforeLegalize() const
LLVM_ABI SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)
This structure is used to pass arguments to makeLibCall function.