69#include "llvm/IR/IntrinsicsPowerPC.h"
103#define DEBUG_TYPE "ppc-lowering"
106 "disable-p10-store-forward",
130 cl::desc(
"disable vector permute decomposition"),
134 "disable-auto-paired-vec-st",
135 cl::desc(
"disable automatically generated 32byte paired vector stores"),
140 cl::desc(
"Set minimum number of entries to use a jump table on PPC"));
144 cl::desc(
"Set minimum of largest number of comparisons to use bit test for "
149 cl::desc(
"max depth when checking alias info in GatherAllAliases()"));
153 cl::desc(
"Set inclusive limit count of TLS local-dynamic access(es) in a "
154 "function to use initial-exec"));
159 "Number of shuffles lowered to a VPERM or XXPERM");
160STATISTIC(NumDynamicAllocaProbed,
"Number of dynamic stack allocation probed");
167 unsigned OpIdx,
bool IsByte,
185 initializeAddrModeMap();
188 bool isPPC64 = Subtarget.isPPC64();
190 const MVT RegVT = Subtarget.getScalarIntVT();
198 if (!Subtarget.hasEFPU2())
215 if (!Subtarget.hasP10Vector()) {
244 if (Subtarget.isISA3_0()) {
277 if (!Subtarget.hasSPE()) {
284 if (Subtarget.useCRBits()) {
287 if (isPPC64 || Subtarget.hasFPCVT()) {
353 if (Subtarget.isISA3_0()) {
388 if (!Subtarget.hasSPE()) {
393 if (Subtarget.hasVSX()) {
398 if (Subtarget.hasFSQRT()) {
403 if (Subtarget.hasFPRND()) {
444 if (Subtarget.hasSPE()) {
454 if (Subtarget.hasSPE())
458 if (!Subtarget.hasFSQRT() && !(Subtarget.hasFRSQRTE() && Subtarget.hasFRE()))
461 if (!Subtarget.hasFSQRT() &&
462 !(Subtarget.hasFRSQRTES() && Subtarget.hasFRES()))
465 if (Subtarget.hasFCPSGN()) {
473 if (Subtarget.hasFPRND()) {
487 if (Subtarget.isISA3_1()) {
493 ((Subtarget.hasP8Vector()) && isPPC64) ?
Custom
498 if (Subtarget.isISA3_0()) {
518 if (!Subtarget.useCRBits()) {
531 if (!Subtarget.useCRBits())
534 if (Subtarget.hasFPU()) {
545 if (!Subtarget.useCRBits())
550 if (Subtarget.hasSPE()) {
574 if (Subtarget.hasDirectMove() && isPPC64) {
640 if (Subtarget.is64BitELFABI()) {
651 }
else if (Subtarget.is32BitELFABI()) {
659 if (Subtarget.is32BitELFABI())
675 if (Subtarget.isISA3_0() && isPPC64) {
703 if (Subtarget.hasSPE()) {
725 if (Subtarget.has64BitSupport()) {
740 if (Subtarget.hasLFIWAX() || isPPC64) {
746 if (Subtarget.hasSPE()) {
756 if (Subtarget.hasFPCVT()) {
757 if (Subtarget.has64BitSupport()) {
778 if (Subtarget.use64BitRegs()) {
796 if (Subtarget.has64BitSupport()) {
803 if (Subtarget.hasVSX()) {
816 if (Subtarget.hasAltivec()) {
817 for (
MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
834 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
847 if (Subtarget.hasVSX()) {
856 if (Subtarget.hasP8Altivec() && (VT.SimpleTy != MVT::v1i128)) {
866 if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
940 if (!Subtarget.hasP8Vector()) {
982 if (Subtarget.hasAltivec())
983 for (
auto VT : {MVT::v4i32, MVT::v8i16, MVT::v16i8})
986 if (Subtarget.hasP8Altivec())
997 if (Subtarget.hasVSX()) {
1003 if (Subtarget.hasP8Altivec())
1008 if (Subtarget.isISA3_1()) {
1054 if (Subtarget.hasVSX()) {
1057 if (Subtarget.hasP8Vector()) {
1061 if (Subtarget.hasDirectMove() && isPPC64) {
1110 if (Subtarget.hasP8Vector())
1119 if (Subtarget.hasP8Altivec()) {
1146 if (Subtarget.isISA3_1())
1249 if (Subtarget.hasP8Altivec()) {
1254 if (Subtarget.hasP9Vector()) {
1259 if (Subtarget.useCRBits()) {
1319 }
else if (Subtarget.hasVSX()) {
1344 for (
MVT VT : {MVT::f32, MVT::f64}) {
1363 if (Subtarget.hasP9Altivec()) {
1364 if (Subtarget.isISA3_1()) {
1387 if (Subtarget.hasP10Vector()) {
1402 if (Subtarget.pairedVectorMemops()) {
1407 if (Subtarget.hasMMA()) {
1408 if (Subtarget.isISAFuture()) {
1424 if (Subtarget.has64BitSupport())
1427 if (Subtarget.isISA3_1())
1445 if (Subtarget.hasAltivec()) {
1463 if (Subtarget.hasFPCVT())
1466 if (Subtarget.useCRBits())
1475 if (Subtarget.useCRBits()) {
1479 if (Subtarget.hasP8Vector())
1484 if (Subtarget.useCRBits()) {
1500 auto CPUDirective = Subtarget.getCPUDirective();
1501 switch (CPUDirective) {
1524 if (Subtarget.enableMachineScheduler())
1598void PPCTargetLowering::initializeAddrModeMap() {
1649 if (MaxAlign == MaxMaxAlign)
1652 if (MaxMaxAlign >= 32 &&
1653 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1654 MaxAlign =
Align(32);
1655 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1657 MaxAlign =
Align(16);
1661 if (EltAlign > MaxAlign)
1662 MaxAlign = EltAlign;
1664 for (
auto *EltTy : STy->elements()) {
1667 if (EltAlign > MaxAlign)
1668 MaxAlign = EltAlign;
1669 if (MaxAlign == MaxMaxAlign)
1682 if (Subtarget.hasAltivec())
1688 return Subtarget.useSoftFloat();
1692 return Subtarget.hasSPE();
1700 Type *VectorTy,
unsigned ElemSizeInBits,
unsigned &Index)
const {
1701 if (!Subtarget.isPPC64() || !Subtarget.hasVSX())
1705 if (VTy->getScalarType()->isIntegerTy()) {
1707 if (ElemSizeInBits == 32) {
1708 Index = Subtarget.isLittleEndian() ? 2 : 1;
1711 if (ElemSizeInBits == 64) {
1712 Index = Subtarget.isLittleEndian() ? 1 : 0;
1723 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1740 return CFP->getValueAPF().isZero();
1745 return CFP->getValueAPF().isZero();
1753 return Op < 0 ||
Op == Val;
1765 if (ShuffleKind == 0) {
1768 for (
unsigned i = 0; i != 16; ++i)
1771 }
else if (ShuffleKind == 2) {
1774 for (
unsigned i = 0; i != 16; ++i)
1777 }
else if (ShuffleKind == 1) {
1778 unsigned j = IsLE ? 0 : 1;
1779 for (
unsigned i = 0; i != 8; ++i)
1796 if (ShuffleKind == 0) {
1799 for (
unsigned i = 0; i != 16; i += 2)
1803 }
else if (ShuffleKind == 2) {
1806 for (
unsigned i = 0; i != 16; i += 2)
1810 }
else if (ShuffleKind == 1) {
1811 unsigned j = IsLE ? 0 : 2;
1812 for (
unsigned i = 0; i != 8; i += 2)
1833 if (!Subtarget.hasP8Vector())
1837 if (ShuffleKind == 0) {
1840 for (
unsigned i = 0; i != 16; i += 4)
1846 }
else if (ShuffleKind == 2) {
1849 for (
unsigned i = 0; i != 16; i += 4)
1855 }
else if (ShuffleKind == 1) {
1856 unsigned j = IsLE ? 0 : 4;
1857 for (
unsigned i = 0; i != 8; i += 4)
1874 unsigned LHSStart,
unsigned RHSStart) {
1875 if (
N->getValueType(0) != MVT::v16i8)
1877 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
1878 "Unsupported merge size!");
1880 for (
unsigned i = 0; i != 8/UnitSize; ++i)
1881 for (
unsigned j = 0; j != UnitSize; ++j) {
1883 LHSStart+j+i*UnitSize) ||
1885 RHSStart+j+i*UnitSize))
1900 if (ShuffleKind == 1)
1902 else if (ShuffleKind == 2)
1907 if (ShuffleKind == 1)
1909 else if (ShuffleKind == 0)
1925 if (ShuffleKind == 1)
1927 else if (ShuffleKind == 2)
1932 if (ShuffleKind == 1)
1934 else if (ShuffleKind == 0)
1984 unsigned RHSStartValue) {
1985 if (
N->getValueType(0) != MVT::v16i8)
1988 for (
unsigned i = 0; i < 2; ++i)
1989 for (
unsigned j = 0; j < 4; ++j)
1991 i*RHSStartValue+j+IndexOffset) ||
1993 i*RHSStartValue+j+IndexOffset+8))
2015 unsigned indexOffset = CheckEven ? 4 : 0;
2016 if (ShuffleKind == 1)
2018 else if (ShuffleKind == 2)
2024 unsigned indexOffset = CheckEven ? 0 : 4;
2025 if (ShuffleKind == 1)
2027 else if (ShuffleKind == 0)
2043 if (
N->getValueType(0) != MVT::v16i8)
2050 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2053 if (i == 16)
return -1;
2058 if (ShiftAmt < i)
return -1;
2063 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2065 for (++i; i != 16; ++i)
2068 }
else if (ShuffleKind == 1) {
2070 for (++i; i != 16; ++i)
2077 ShiftAmt = 16 - ShiftAmt;
2086 EVT VT =
N->getValueType(0);
2087 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2088 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2091 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2095 if (
N->getMaskElt(0) % EltSize != 0)
2100 unsigned ElementBase =
N->getMaskElt(0);
2103 if (ElementBase >= 16)
2108 for (
unsigned i = 1; i != EltSize; ++i)
2109 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2112 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2114 if (
N->getMaskElt(i) < 0) {
2115 for (
unsigned j = 1; j != EltSize; ++j)
2116 if (
N->getMaskElt(i + j) >= 0)
2119 for (
unsigned j = 0; j != EltSize; ++j)
2120 if (
N->getMaskElt(i + j) !=
N->getMaskElt(j))
2137 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2138 "Unexpected element width.");
2139 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2141 unsigned NumOfElem = 16 / Width;
2142 unsigned MaskVal[16];
2143 for (
unsigned i = 0; i < NumOfElem; ++i) {
2144 MaskVal[0] =
N->getMaskElt(i * Width);
2145 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2147 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2151 for (
unsigned int j = 1; j < Width; ++j) {
2152 MaskVal[j] =
N->getMaskElt(i * Width + j);
2153 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2163 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2168 unsigned M0 =
N->getMaskElt(0) / 4;
2169 unsigned M1 =
N->getMaskElt(4) / 4;
2170 unsigned M2 =
N->getMaskElt(8) / 4;
2171 unsigned M3 =
N->getMaskElt(12) / 4;
2172 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2173 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2178 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2179 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2180 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2181 InsertAtByte = IsLE ? 12 : 0;
2186 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2187 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2188 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2189 InsertAtByte = IsLE ? 8 : 4;
2194 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2195 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2196 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2197 InsertAtByte = IsLE ? 4 : 8;
2202 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2203 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2204 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2205 InsertAtByte = IsLE ? 0 : 12;
2212 if (
N->getOperand(1).isUndef()) {
2215 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2216 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2217 InsertAtByte = IsLE ? 12 : 0;
2220 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2221 InsertAtByte = IsLE ? 8 : 4;
2224 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2225 InsertAtByte = IsLE ? 4 : 8;
2228 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2229 InsertAtByte = IsLE ? 0 : 12;
2238 bool &Swap,
bool IsLE) {
2239 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2245 unsigned M0 =
N->getMaskElt(0) / 4;
2246 unsigned M1 =
N->getMaskElt(4) / 4;
2247 unsigned M2 =
N->getMaskElt(8) / 4;
2248 unsigned M3 =
N->getMaskElt(12) / 4;
2252 if (
N->getOperand(1).isUndef()) {
2253 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2254 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2257 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2263 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2267 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2272 ShiftElts = (8 -
M0) % 8;
2273 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2278 ShiftElts = (4 -
M0) % 4;
2283 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2288 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2300 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2305 for (
int i = 0; i < 16; i += Width)
2306 if (
N->getMaskElt(i) != i + Width - 1)
2337 bool &Swap,
bool IsLE) {
2338 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2344 unsigned M0 =
N->getMaskElt(0) / 8;
2345 unsigned M1 =
N->getMaskElt(8) / 8;
2346 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2350 if (
N->getOperand(1).isUndef()) {
2351 if ((
M0 |
M1) < 2) {
2352 DM = IsLE ? (((
~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2360 if (
M0 > 1 &&
M1 < 2) {
2370 DM = (((
~M1) & 1) << 1) + ((~
M0) & 1);
2375 }
else if (
M0 > 1 &&
M1 < 2) {
2383 DM = (
M0 << 1) + (
M1 & 1);
2398 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2403 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2419 unsigned EltSize = 16/
N->getNumOperands();
2420 if (EltSize < ByteSize) {
2421 unsigned Multiple = ByteSize/EltSize;
2423 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2426 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2427 if (
N->getOperand(i).isUndef())
continue;
2431 if (!UniquedVals[i&(Multiple-1)].
getNode())
2432 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2433 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2443 bool LeadingZero =
true;
2444 bool LeadingOnes =
true;
2445 for (
unsigned i = 0; i != Multiple-1; ++i) {
2446 if (!UniquedVals[i].
getNode())
continue;
2453 if (!UniquedVals[Multiple-1].
getNode())
2460 if (!UniquedVals[Multiple-1].
getNode())
2471 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2472 if (
N->getOperand(i).isUndef())
continue;
2474 OpVal =
N->getOperand(i);
2475 else if (OpVal !=
N->getOperand(i))
2481 unsigned ValSizeInBytes = EltSize;
2484 Value = CN->getZExtValue();
2486 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2493 if (ValSizeInBytes < ByteSize)
return SDValue();
2504 if (MaskVal == 0)
return SDValue();
2524 Imm = (int16_t)
N->getAsZExtVal();
2525 if (
N->getValueType(0) == MVT::i32)
2526 return Imm == (int32_t)
N->getAsZExtVal();
2528 return Imm == (int64_t)
N->getAsZExtVal();
2546 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2554 for (
SDNode *U :
N->users()) {
2556 if (Memop->getMemoryVT() == MVT::f64) {
2557 Base =
N.getOperand(0);
2558 Index =
N.getOperand(1);
2601 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2603 if (
N.getOperand(1).getOpcode() == PPCISD::Lo)
2606 Base =
N.getOperand(0);
2607 Index =
N.getOperand(1);
2609 }
else if (
N.getOpcode() ==
ISD::OR) {
2611 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2623 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2624 Base =
N.getOperand(0);
2625 Index =
N.getOperand(1);
2695 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2701 Base =
N.getOperand(0);
2704 }
else if (
N.getOperand(1).getOpcode() == PPCISD::Lo) {
2706 assert(!
N.getOperand(1).getConstantOperandVal(1) &&
2707 "Cannot handle constant offsets yet!");
2708 Disp =
N.getOperand(1).getOperand(0);
2713 Base =
N.getOperand(0);
2716 }
else if (
N.getOpcode() ==
ISD::OR) {
2719 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2733 Base =
N.getOperand(0);
2746 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm))) {
2749 CN->getValueType(0));
2754 if ((CN->getValueType(0) == MVT::i32 ||
2755 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2756 (!EncodingAlignment ||
2757 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2758 int Addr = (int)CN->getZExtValue();
2765 unsigned Opc = CN->getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2786 if (
N.getValueType() != MVT::i64)
2799 Base =
N.getOperand(0);
2815 Base =
N.getOperand(0);
2848 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2849 Base =
N.getOperand(0);
2850 Index =
N.getOperand(1);
2872 if (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR)
2893 EVT MemVT = LD->getMemoryVT();
2900 if (!ST.hasP8Vector())
2905 if (!ST.hasP9Vector())
2917 if (
Use.getResNo() == 0 &&
2919 Use.
getUser()->getOpcode() != PPCISD::SCALAR_TO_VECTOR_PERMUTED)
2939 Ptr = LD->getBasePtr();
2940 VT = LD->getMemoryVT();
2941 Alignment = LD->getAlign();
2943 Ptr = ST->getBasePtr();
2944 VT = ST->getMemoryVT();
2945 Alignment = ST->getAlign();
2984 if (VT != MVT::i64) {
2989 if (Alignment <
Align(4))
2999 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
3016 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3058 EVT VT = Subtarget.getScalarIntVT();
3060 : Subtarget.isAIXABI()
3065 PPCISD::TOC_ENTRY, dl, DAG.
getVTList(VT, MVT::Other),
Ops, VT,
3072 EVT PtrVT =
Op.getValueType();
3078 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3079 if (Subtarget.isUsingPCRelativeCalls()) {
3084 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, ConstPool);
3088 return getTOCEntry(DAG, SDLoc(CP), GA);
3091 unsigned MOHiFlag, MOLoFlag;
3095 if (IsPIC && Subtarget.isSVR4ABI()) {
3098 return getTOCEntry(DAG, SDLoc(CP), GA);
3121 if (Subtarget.isPPC64() || Subtarget.isAIXABI())
3128 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3145 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3158 EVT PtrVT =
Op.getValueType();
3176 return getTOCEntry(DAG,
SDLoc(JT), GA);
3179 unsigned MOHiFlag, MOLoFlag;
3183 if (IsPIC && Subtarget.isSVR4ABI()) {
3186 return getTOCEntry(DAG, SDLoc(GA), GA);
3196 EVT PtrVT =
Op.getValueType();
3201 if (Subtarget.isUsingPCRelativeCalls()) {
3212 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3215 return getTOCEntry(DAG, SDLoc(BASDN), GA);
3224 unsigned MOHiFlag, MOLoFlag;
3234 if (Subtarget.isAIXABI())
3235 return LowerGlobalTLSAddressAIX(
Op, DAG);
3237 return LowerGlobalTLSAddressLinux(
Op, DAG);
3259 if (
I.getOpcode() == Instruction::Call)
3261 if (
Function *CF = CI->getCalledFunction())
3262 if (CF->isDeclaration() &&
3263 CF->getIntrinsicID() == Intrinsic::threadlocal_address)
3271 unsigned TLSGVCnt = TLSGV.
size();
3281 <<
" function is using the TLS-IE model for TLS-LD access.\n");
3294 const GlobalValue *GV = GA->
getGlobal();
3296 bool Is64Bit = Subtarget.isPPC64();
3300 if (Subtarget.hasAIXShLibTLSModelOpt())
3310 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3311 bool HasAIXSmallTLSGlobalAttr =
false;
3314 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3318 if (GVar->hasAttribute(
"aix-small-tls"))
3319 HasAIXSmallTLSGlobalAttr =
true;
3338 if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) &&
3339 IsTLSLocalExecModel) {
3344 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA, TLSReg);
3354 TLSReg = DAG.
getNode(PPCISD::GET_TPOINTER, dl, PtrVT);
3359 if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr)
3361 "currently only supported on AIX (64-bit mode).");
3363 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, VariableOffset);
3367 bool HasAIXSmallLocalDynamicTLS = Subtarget.hasAIXSmallLocalDynamicTLS();
3371 if (!Is64Bit && HasAIXSmallLocalDynamicTLS)
3373 "currently only supported on AIX (64-bit mode).");
3381 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3384 GlobalVariable *TLSGV =
3388 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3391 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3393 DAG.
getNode(PPCISD::TLSLD_AIX, dl, PtrVT, ModuleHandleTOC);
3402 if (HasAIXSmallLocalDynamicTLS) {
3407 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA,
3411 return DAG.
getNode(
ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
3424 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3425 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3426 return DAG.
getNode(PPCISD::TLSGD_AIX, dl, PtrVT, VariableOffset,
3441 const GlobalValue *GV = GA->
getGlobal();
3443 bool is64bit = Subtarget.isPPC64();
3451 if (Subtarget.isUsingPCRelativeCalls()) {
3456 DAG.
getNode(PPCISD::TLS_LOCAL_EXEC_MAT_ADDR, dl, PtrVT, TGA);
3457 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, MatAddr);
3468 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, TGALo,
Hi);
3472 bool IsPCRel = Subtarget.isUsingPCRelativeCalls();
3479 SDValue MatPCRel = DAG.
getNode(PPCISD::MAT_PCREL_ADDR, dl, PtrVT, TGA);
3481 MachinePointerInfo());
3488 DAG.
getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl, PtrVT, GOTReg, TGA);
3490 if (!TM.isPositionIndependent())
3491 GOTPtr = DAG.
getNode(PPCISD::PPC32_GOT, dl, PtrVT);
3497 TPOffset = DAG.
getNode(PPCISD::LD_GOT_TPREL_L, dl, PtrVT, TGA, GOTPtr);
3499 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TPOffset, TGATLS);
3503 if (Subtarget.isUsingPCRelativeCalls()) {
3506 return DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3514 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSGD_HA, dl, PtrVT,
3522 return DAG.
getNode(PPCISD::ADDI_TLSGD_L_ADDR, dl, PtrVT,
3527 if (Subtarget.isUsingPCRelativeCalls()) {
3531 DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3532 return DAG.
getNode(PPCISD::PADDI_DTPREL, dl, PtrVT, MatPCRel, TGA);
3540 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSLD_HA, dl, PtrVT,
3549 PtrVT, GOTPtr, TGA, TGA);
3551 PtrVT, TLSAddr, TGA);
3552 return DAG.
getNode(PPCISD::ADDI_DTPREL_L, dl, PtrVT, DtvOffsetHi, TGA);
3560 EVT PtrVT =
Op.getValueType();
3563 const GlobalValue *GV = GSDN->
getGlobal();
3567 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3568 if (Subtarget.isUsingPCRelativeCalls()) {
3575 MachinePointerInfo());
3580 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, GA);
3585 return getTOCEntry(DAG,
DL, GA);
3588 unsigned MOHiFlag, MOLoFlag;
3592 if (IsPIC && Subtarget.isSVR4ABI()) {
3596 return getTOCEntry(DAG,
DL, GA);
3608 bool IsStrict =
Op->isStrictFPOpcode();
3614 EVT LHSVT =
LHS.getValueType();
3618 if (LHSVT == MVT::f128) {
3619 assert(!Subtarget.hasP9Vector() &&
3620 "SETCC for f128 is already legal under Power9!");
3631 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3633 if (
Op.getValueType() == MVT::v2i64) {
3636 if (
LHS.getValueType() == MVT::v2i64) {
3644 int ShuffV[] = {1, 0, 3, 2};
3649 dl, MVT::v4i32, Shuff, SetCC32));
3666 if (
C->isAllOnes() ||
C->isZero())
3676 EVT VT =
Op.getValueType();
3684 SDNode *
Node =
Op.getNode();
3685 EVT VT =
Node->getValueType(0);
3692 assert(!Subtarget.isPPC64() &&
"LowerVAARG is PPC32 only");
3696 VAListPtr, MachinePointerInfo(SV), MVT::i8);
3699 if (VT == MVT::i64) {
3718 FprPtr, MachinePointerInfo(SV), MVT::i8);
3729 DAG.
getLoad(MVT::i32, dl, InChain, OverflowAreaPtr, MachinePointerInfo());
3730 InChain = OverflowArea.
getValue(1);
3733 DAG.
getLoad(MVT::i32, dl, InChain, RegSaveAreaPtr, MachinePointerInfo());
3763 MachinePointerInfo(SV), MVT::i8);
3776 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3777 MachinePointerInfo(), MVT::i32);
3779 return DAG.
getLoad(VT, dl, InChain, Result, MachinePointerInfo());
3783 assert(!Subtarget.isPPC64() &&
"LowerVACOPY is PPC32 only");
3789 false,
true,
nullptr, std::nullopt,
3790 MachinePointerInfo(), MachinePointerInfo());
3795 return Op.getOperand(0);
3800 PPCFunctionInfo &MFI = *MF.
getInfo<PPCFunctionInfo>();
3804 "Expecting Inline ASM node.");
3814 if (
Op.getOperand(
NumOps - 1).getValueType() == MVT::Glue)
3819 const InlineAsm::Flag
Flags(
Op.getConstantOperandVal(i));
3820 unsigned NumVals =
Flags.getNumOperandRegisters();
3823 switch (
Flags.getKind()) {
3834 for (; NumVals; --NumVals, ++i) {
3836 if (
Reg != PPC::LR &&
Reg != PPC::LR8)
3859 if (Subtarget.isAIXABI()) {
3863 uint64_t
PointerSize = Subtarget.isPPC64() ? 8 : 4;
3864 MaybeAlign PointerAlign(PointerSize);
3865 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
3868 : MachineMemOperand::MONone;
3875 const Value *TrampolineAddr =
3885 DAG.
getLoad(PtrVT, dl, Chain, FPtr, MachinePointerInfo(Func, 0),
3886 PointerAlign, MMOFlags);
3888 OutChains[0] = DAG.
getStore(EPLoadChain, dl, LoadEntryPoint, Trmp,
3889 MachinePointerInfo(TrampolineAddr, 0));
3893 SDValue TOCFromDescriptorPtr =
3895 SDValue TOCReg = DAG.
getLoad(PtrVT, dl, Chain, TOCFromDescriptorPtr,
3896 MachinePointerInfo(Func, TOCPointerOffset),
3897 PointerAlign, MMOFlags);
3898 SDValue TrampolineTOCPointer =
3902 DAG.
getStore(TOCLoadChain, dl, TOCReg, TrampolineTOCPointer,
3903 MachinePointerInfo(TrampolineAddr, TOCPointerOffset));
3909 DAG.
getStore(Chain, dl, Nest, EnvPointer,
3910 MachinePointerInfo(TrampolineAddr, EnvPointerOffset));
3917 bool isPPC64 = (PtrVT == MVT::i64);
3921 Args.emplace_back(Trmp, IntPtrTy);
3924 DAG.
getConstant(isPPC64 ? 48 : 40, dl, Subtarget.getScalarIntVT()),
3926 Args.emplace_back(FPtr, IntPtrTy);
3927 Args.emplace_back(Nest, IntPtrTy);
3930 TargetLowering::CallLoweringInfo CLI(DAG);
3931 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3935 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
3936 return CallResult.second;
3941 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
3946 if (Subtarget.isPPC64() || Subtarget.isAIXABI()) {
3951 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
3952 MachinePointerInfo(SV));
3986 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
3989 uint64_t StackOffset = PtrVT.getSizeInBits()/8 - 1;
3992 uint64_t FPROffset = 1;
4000 MachinePointerInfo(SV), MVT::i8);
4001 uint64_t nextOffset = FPROffset;
4008 MachinePointerInfo(SV, nextOffset), MVT::i8);
4009 nextOffset += StackOffset;
4010 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
4013 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
4014 MachinePointerInfo(SV, nextOffset));
4015 nextOffset += FrameOffset;
4016 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
4019 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
4020 MachinePointerInfo(SV, nextOffset));
4025static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
4026 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
4027 PPC::F11, PPC::F12, PPC::F13};
4032 unsigned PtrByteSize) {
4034 if (Flags.isByVal())
4035 ArgSize = Flags.getByValSize();
4039 if (!Flags.isInConsecutiveRegs())
4040 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4049 unsigned PtrByteSize) {
4050 Align Alignment(PtrByteSize);
4053 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4054 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4055 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4056 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4057 Alignment =
Align(16);
4060 if (Flags.isByVal()) {
4061 auto BVAlign = Flags.getNonZeroByValAlign();
4062 if (BVAlign > PtrByteSize) {
4063 if (BVAlign.value() % PtrByteSize != 0)
4065 "ByVal alignment is not a multiple of the pointer size");
4067 Alignment = BVAlign;
4072 if (Flags.isInConsecutiveRegs()) {
4076 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4090 unsigned PtrByteSize,
unsigned LinkageSize,
4091 unsigned ParamAreaSize,
unsigned &ArgOffset,
4092 unsigned &AvailableFPRs,
4093 unsigned &AvailableVRs) {
4094 bool UseMemory =
false;
4099 ArgOffset =
alignTo(ArgOffset, Alignment);
4102 if (ArgOffset >= LinkageSize + ParamAreaSize)
4107 if (Flags.isInConsecutiveRegsLast())
4108 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4111 if (ArgOffset > LinkageSize + ParamAreaSize)
4116 if (!Flags.isByVal()) {
4117 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4118 if (AvailableFPRs > 0) {
4122 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4123 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4124 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4125 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4126 if (AvailableVRs > 0) {
4138 unsigned NumBytes) {
4142SDValue PPCTargetLowering::LowerFormalArguments(
4146 if (Subtarget.isAIXABI())
4147 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4149 if (Subtarget.is64BitELFABI())
4150 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4152 assert(Subtarget.is32BitELFABI());
4153 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4157SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4193 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4199 const Align PtrAlign(4);
4207 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4208 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4211 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4212 CCValAssign &VA = ArgLocs[i];
4216 const TargetRegisterClass *RC;
4224 RC = &PPC::GPRCRegClass;
4227 if (Subtarget.hasP8Vector())
4228 RC = &PPC::VSSRCRegClass;
4229 else if (Subtarget.hasSPE())
4230 RC = &PPC::GPRCRegClass;
4232 RC = &PPC::F4RCRegClass;
4235 if (Subtarget.hasVSX())
4236 RC = &PPC::VSFRCRegClass;
4237 else if (Subtarget.hasSPE())
4239 RC = &PPC::GPRCRegClass;
4241 RC = &PPC::F8RCRegClass;
4246 RC = &PPC::VRRCRegClass;
4249 RC = &PPC::VRRCRegClass;
4253 RC = &PPC::VRRCRegClass;
4260 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4261 assert(i + 1 < e &&
"No second half of double precision argument");
4266 if (!Subtarget.isLittleEndian())
4268 ArgValue = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64, ArgValueLo,
4273 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4274 if (ValVT == MVT::i1)
4289 ArgOffset += ArgSize - ObjSize;
4307 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4312 unsigned MinReservedArea = CCByValInfo.getStackSize();
4313 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4329 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4330 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4332 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4335 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4338 unsigned NumFPArgRegs = std::size(FPArgRegs);
4347 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4348 NumFPArgRegs * MVT(MVT::f64).getSizeInBits()/8;
4351 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4364 VReg = MF.
addLiveIn(GPArgReg, &PPC::GPRCRegClass);
4379 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4383 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4396 if (!MemOps.
empty())
4407 const SDLoc &dl)
const {
4411 else if (
Flags.isZExt())
4418SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4424 bool isELFv2ABI = Subtarget.isELFv2ABI();
4425 bool isLittleEndian = Subtarget.isLittleEndian();
4428 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4431 "fastcc not supported on varargs functions");
4437 unsigned PtrByteSize = 8;
4438 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4441 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4442 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4445 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4446 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4449 const unsigned Num_GPR_Regs = std::size(GPR);
4451 const unsigned Num_VR_Regs = std::size(VR);
4459 bool HasParameterArea = !isELFv2ABI || isVarArg;
4460 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4461 unsigned NumBytes = LinkageSize;
4462 unsigned AvailableFPRs = Num_FPR_Regs;
4463 unsigned AvailableVRs = Num_VR_Regs;
4464 for (
const ISD::InputArg &In : Ins) {
4465 if (
In.Flags.isNest())
4469 LinkageSize, ParamAreaSize, NumBytes,
4470 AvailableFPRs, AvailableVRs))
4471 HasParameterArea =
true;
4478 unsigned ArgOffset = LinkageSize;
4479 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4482 unsigned CurArgIdx = 0;
4483 for (
unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) {
4485 bool needsLoad =
false;
4486 EVT ObjectVT = Ins[ArgNo].VT;
4487 EVT OrigVT = Ins[ArgNo].ArgVT;
4489 unsigned ArgSize = ObjSize;
4490 ISD::ArgFlagsTy
Flags = Ins[ArgNo].Flags;
4491 if (Ins[ArgNo].isOrigArg()) {
4492 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4493 CurArgIdx = Ins[ArgNo].getOrigArgIndex();
4498 unsigned CurArgOffset;
4500 auto ComputeArgOffset = [&]() {
4504 ArgOffset =
alignTo(ArgOffset, Alignment);
4505 CurArgOffset = ArgOffset;
4512 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4513 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4518 if (
Flags.isByVal()) {
4519 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4525 ObjSize =
Flags.getByValSize();
4526 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4548 if (HasParameterArea ||
4549 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4556 if (ObjSize < PtrByteSize) {
4560 if (!isLittleEndian) {
4566 if (GPR_idx != Num_GPR_Regs) {
4573 MachinePointerInfo(&*FuncArg), ObjType);
4578 ArgOffset += PtrByteSize;
4587 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4588 if (GPR_idx == Num_GPR_Regs)
4599 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4603 MachinePointerInfo(&*FuncArg, j), ObjType);
4607 ArgOffset += ArgSize;
4616 if (
Flags.isNest()) {
4621 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4622 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4630 if (GPR_idx != Num_GPR_Regs) {
4635 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4638 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4644 ArgSize = PtrByteSize;
4655 if (FPR_idx != Num_FPR_Regs) {
4658 if (ObjectVT == MVT::f32)
4660 Subtarget.hasP8Vector()
4661 ? &PPC::VSSRCRegClass
4662 : &PPC::F4RCRegClass);
4665 ? &PPC::VSFRCRegClass
4666 : &PPC::F8RCRegClass);
4681 if (ObjectVT == MVT::f32) {
4682 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4700 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4701 ArgOffset += ArgSize;
4702 if (
Flags.isInConsecutiveRegsLast())
4703 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4717 if (VR_idx != Num_VR_Regs) {
4734 if (ObjSize < ArgSize && !isLittleEndian)
4735 CurArgOffset += ArgSize - ObjSize;
4738 ArgVal = DAG.
getLoad(ObjectVT, dl, Chain, FIN, MachinePointerInfo());
4745 unsigned MinReservedArea;
4746 if (HasParameterArea)
4747 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4749 MinReservedArea = LinkageSize;
4766 int Depth = ArgOffset;
4775 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4776 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4788 if (!MemOps.
empty())
4797 unsigned ParamSize) {
4799 if (!isTailCall)
return 0;
4803 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4805 if (SPDiff < FI->getTailCallSPDelta())
4821 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4880 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
4883 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4895 const unsigned PtrByteSize = 8;
4899 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4900 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4903 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4904 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4907 const unsigned NumGPRs = std::size(GPR);
4908 const unsigned NumFPRs = 13;
4909 const unsigned NumVRs = std::size(VR);
4910 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4912 unsigned NumBytes = LinkageSize;
4913 unsigned AvailableFPRs = NumFPRs;
4914 unsigned AvailableVRs = NumVRs;
4917 if (Param.Flags.isNest())
continue;
4920 LinkageSize, ParamAreaSize, NumBytes,
4921 AvailableFPRs, AvailableVRs))
4932 auto CalleeArgEnd = CB.
arg_end();
4935 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
4936 const Value* CalleeArg = *CalleeArgIter;
4937 const Value* CallerArg = &(*CallerArgIter);
4938 if (CalleeArg == CallerArg)
4964 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
4974bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
4979 bool isCalleeExternalSymbol)
const {
4982 if (
DisableSCO && !TailCallOpt)
return false;
4985 if (isVarArg)
return false;
4992 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5028 if (!Subtarget.isUsingPCRelativeCalls() &&
5033 if (!Subtarget.isUsingPCRelativeCalls() &&
5061bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5074 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5095 if (!
C)
return nullptr;
5097 int Addr =
C->getZExtValue();
5098 if ((Addr & 3) != 0 ||
5104 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5111struct TailCallArgumentInfo {
5116 TailCallArgumentInfo() =
default;
5126 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5127 SDValue Arg = TailCallArgs[i].Arg;
5128 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5129 int FI = TailCallArgs[i].FrameIdx;
5132 Chain, dl, Arg, FIN,
5141 int SPDiff,
const SDLoc &dl) {
5147 int SlotSize = Subtarget.isPPC64() ? 8 : 4;
5148 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5150 NewRetAddrLoc,
true);
5153 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5163 int SPDiff,
unsigned ArgOffset,
5165 int Offset = ArgOffset + SPDiff;
5168 EVT VT = IsPPC64 ? MVT::i64 : MVT::i32;
5170 TailCallArgumentInfo Info;
5172 Info.FrameIdxOp = FIN;
5180SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5185 LROpOut = getReturnAddrFrameIndex(DAG);
5186 LROpOut = DAG.
getLoad(Subtarget.getScalarIntVT(), dl, Chain, LROpOut,
5187 MachinePointerInfo());
5204 Chain, dl, Dst, Src, SizeNode, Flags.getNonZeroByValAlign(),
false,
false,
5212 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5236 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5246 if (!MemOpChains2.
empty())
5270SDValue PPCTargetLowering::LowerCallResult(
5278 CCRetInfo.AnalyzeCallResult(
5284 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5285 CCValAssign &VA = RVLocs[i];
5290 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5300 if (!Subtarget.isLittleEndian())
5302 Val = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64,
Lo,
Hi);
5368 bool IsStrictFPCall =
false) {
5370 return PPCISD::TC_RETURN;
5372 unsigned RetOpc = 0;
5383 if (Subtarget.usePointerGlueHelper())
5384 RetOpc = PPCISD::BL_LOAD_TOC;
5390 RetOpc = PPCISD::CALL_NOTOC;
5405 RetOpc = PPCISD::CALL;
5406 if (IsStrictFPCall) {
5410 case PPCISD::BCTRL_LOAD_TOC:
5411 RetOpc = PPCISD::BCTRL_LOAD_TOC_RM;
5414 RetOpc = PPCISD::BCTRL_RM;
5416 case PPCISD::BL_LOAD_TOC:
5417 RetOpc = PPCISD::BL_LOAD_TOC_RM;
5419 case PPCISD::CALL_NOTOC:
5420 RetOpc = PPCISD::CALL_NOTOC_RM;
5423 RetOpc = PPCISD::CALL_RM;
5425 case PPCISD::CALL_NOP:
5426 RetOpc = PPCISD::CALL_NOP_RM;
5440 auto isLocalCallee = [&]() {
5456 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5472 return getAIXFuncEntryPointSymbolSDNode(GV);
5479 const char *SymName = S->getSymbol();
5486 return getAIXFuncEntryPointSymbolSDNode(
F);
5492 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5500 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5507 assert(Callee.getNode() &&
"What no callee?");
5513 "Expected a CALLSEQ_STARTSDNode.");
5530 SDValue MTCTROps[] = {Chain, Callee, Glue};
5531 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5532 Chain = DAG.
getNode(PPCISD::MTCTR, dl, ReturnTypes,
5572 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5591 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5592 Alignment, MMOFlags);
5599 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5606 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5618 "Nest parameter is not supported on AIX.");
5633 const SDLoc &dl,
bool hasNest,
5643 Chain = MoveToPhysicalReg.
getValue(0);
5644 Glue = MoveToPhysicalReg.
getValue(1);
5651 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5654 const bool IsPPC64 = Subtarget.isPPC64();
5659 Ops.push_back(Chain);
5663 Ops.push_back(Callee);
5664 else if (Subtarget.usePointerGlueHelper()) {
5665 Ops.push_back(Callee);
5688 Ops.push_back(AddTOC);
5699 Ops.push_back(DAG.
getRegister(IsPPC64 ? PPC::CTR8 : PPC::CTR, RegVT));
5708 for (
const auto &[
Reg,
N] : RegsToPass)
5726 assert(Mask &&
"Missing call preserved mask for calling convention");
5731 Ops.push_back(Glue);
5734SDValue PPCTargetLowering::FinishCall(
5741 if ((Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls()) ||
5742 Subtarget.isAIXABI())
5749 if (!CFlags.IsIndirect)
5751 else if (Subtarget.usesFunctionDescriptors()) {
5752 if (Subtarget.usePointerGlueHelper()) {
5754 CFlags.HasNest, Subtarget);
5760 dl, CFlags.HasNest, Subtarget);
5772 if (CFlags.IsTailCall) {
5780 (CFlags.IsIndirect && Subtarget.isUsingPCRelativeCalls())) &&
5781 "Expecting a global address, external symbol, absolute value, "
5782 "register or an indirect tail call when PC Relative calls are "
5785 assert(CallOpc == PPCISD::TC_RETURN &&
5786 "Unexpected call opcode for a tail call.");
5793 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5794 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes,
Ops);
5806 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5809 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5829 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5830 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5834bool PPCTargetLowering::isEligibleForTCO(
5839 bool isCalleeExternalSymbol)
const {
5843 if (Subtarget.
isSVR4ABI() && Subtarget.isPPC64())
5844 return IsEligibleForTailCallOptimization_64SVR4(
5845 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5846 isCalleeExternalSymbol);
5848 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5876 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5891 "Callee should be an llvm::Function object.");
5894 <<
"\nTCO callee: ");
5901 "site marked musttail");
5908 Callee = LowerGlobalAddress(Callee, DAG);
5911 CallConv, isTailCall, isVarArg, isPatchPoint,
5914 Subtarget.is64BitELFABI() &&
5918 if (Subtarget.isAIXABI())
5919 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5922 assert(Subtarget.isSVR4ABI());
5923 if (Subtarget.isPPC64())
5924 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5926 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5930SDValue PPCTargetLowering::LowerCall_32SVR4(
5941 const bool IsVarArg = CFlags.IsVarArg;
5942 const bool IsTailCall = CFlags.IsTailCall;
5948 const Align PtrAlign(4);
5959 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
5967 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.
getContext());
5970 CCInfo.AllocateStack(Subtarget.getFrameLowering()->getLinkageSize(),
5977 unsigned NumArgs = Outs.
size();
5979 for (
unsigned i = 0; i != NumArgs; ++i) {
5980 MVT ArgVT = Outs[i].VT;
5981 ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
5986 Outs[i].OrigTy, CCInfo);
5989 ArgFlags, Outs[i].OrigTy, CCInfo);
5994 errs() <<
"Call operand #" << i <<
" has unhandled type "
6007 CCState CCByValInfo(CallConv, IsVarArg, MF, ByValArgLocs, *DAG.
getContext());
6010 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
6017 unsigned NumBytes = CCByValInfo.getStackSize();
6031 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6042 bool seenFloatArg =
false;
6047 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
6049 ++i, ++RealArgIdx) {
6050 CCValAssign &VA = ArgLocs[i];
6051 SDValue Arg = OutVals[RealArgIdx];
6052 ISD::ArgFlagsTy
Flags = Outs[RealArgIdx].Flags;
6054 if (
Flags.isByVal()) {
6059 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
6060 CCValAssign &ByValVA = ByValArgLocs[
j++];
6082 Chain = CallSeqStart = NewCallSeqStart;
6101 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6102 bool IsLE = Subtarget.isLittleEndian();
6103 SDValue SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6106 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6108 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6123 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()));
6132 if (!MemOpChains.
empty())
6138 for (
const auto &[
Reg,
N] : RegsToPass) {
6146 SDVTList VTs = DAG.
getVTList(MVT::Other, MVT::Glue);
6149 Chain = DAG.
getNode(seenFloatArg ? PPCISD::CR6SET : PPCISD::CR6UNSET, dl,
6159 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6160 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6165SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6177 return NewCallSeqStart;
6180SDValue PPCTargetLowering::LowerCall_64SVR4(
6187 bool isELFv2ABI = Subtarget.isELFv2ABI();
6188 bool isLittleEndian = Subtarget.isLittleEndian();
6190 bool IsSibCall =
false;
6194 unsigned PtrByteSize = 8;
6207 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
6209 assert(!(IsFastCall && CFlags.IsVarArg) &&
6210 "fastcc not supported on varargs functions");
6216 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
6217 unsigned NumBytes = LinkageSize;
6218 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6221 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6222 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6225 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6226 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6229 const unsigned NumGPRs = std::size(GPR);
6231 const unsigned NumVRs = std::size(VR);
6237 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6238 if (!HasParameterArea) {
6239 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6240 unsigned AvailableFPRs = NumFPRs;
6241 unsigned AvailableVRs = NumVRs;
6242 unsigned NumBytesTmp = NumBytes;
6243 for (
unsigned i = 0; i !=
NumOps; ++i) {
6244 if (Outs[i].
Flags.isNest())
continue;
6246 PtrByteSize, LinkageSize, ParamAreaSize,
6247 NumBytesTmp, AvailableFPRs, AvailableVRs))
6248 HasParameterArea =
true;
6254 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6259 HasParameterArea =
false;
6262 for (
unsigned i = 0; i !=
NumOps; ++i) {
6263 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6264 EVT ArgVT = Outs[i].VT;
6265 EVT OrigVT = Outs[i].ArgVT;
6271 if (
Flags.isByVal()) {
6272 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6273 if (NumGPRsUsed > NumGPRs)
6274 HasParameterArea =
true;
6281 if (++NumGPRsUsed <= NumGPRs)
6291 if (++NumVRsUsed <= NumVRs)
6295 if (++NumVRsUsed <= NumVRs)
6300 if (++NumFPRsUsed <= NumFPRs)
6304 HasParameterArea =
true;
6311 NumBytes =
alignTo(NumBytes, Alignement);
6314 if (
Flags.isInConsecutiveRegsLast())
6315 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6318 unsigned NumBytesActuallyUsed = NumBytes;
6328 if (HasParameterArea)
6329 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6331 NumBytes = LinkageSize;
6346 if (CFlags.IsTailCall)
6358 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6369 unsigned ArgOffset = LinkageSize;
6375 for (
unsigned i = 0; i !=
NumOps; ++i) {
6377 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6378 EVT ArgVT = Outs[i].VT;
6379 EVT OrigVT = Outs[i].ArgVT;
6388 auto ComputePtrOff = [&]() {
6392 ArgOffset =
alignTo(ArgOffset, Alignment);
6403 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6404 GPR_idx = std::min(GPR_idx, NumGPRs);
6411 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6417 if (
Flags.isByVal()) {
6435 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6436 if (GPR_idx != NumGPRs) {
6438 MachinePointerInfo(), VT);
6440 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6442 ArgOffset += PtrByteSize;
6447 if (GPR_idx == NumGPRs &&
Size < 8) {
6449 if (!isLittleEndian) {
6454 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6457 ArgOffset += PtrByteSize;
6466 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6467 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6472 if (
Size < 8 && GPR_idx != NumGPRs) {
6482 if (!isLittleEndian) {
6486 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6492 DAG.
getLoad(PtrVT, dl, Chain, PtrOff, MachinePointerInfo());
6494 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6497 ArgOffset += PtrByteSize;
6503 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6506 if (GPR_idx != NumGPRs) {
6507 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6510 MachinePointerInfo(), ObjType);
6513 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6514 ArgOffset += PtrByteSize;
6516 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6528 if (
Flags.isNest()) {
6530 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6537 if (GPR_idx != NumGPRs) {
6538 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6543 assert(HasParameterArea &&
6544 "Parameter area must exist to pass an argument in memory.");
6546 true, CFlags.IsTailCall,
false, MemOpChains,
6547 TailCallArguments, dl);
6549 ArgOffset += PtrByteSize;
6552 ArgOffset += PtrByteSize;
6565 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6566 bool NeededLoad =
false;
6569 if (FPR_idx != NumFPRs)
6570 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6573 if (!NeedGPROrStack)
6575 else if (GPR_idx != NumGPRs && !IsFastCall) {
6589 }
else if (!
Flags.isInConsecutiveRegs()) {
6595 }
else if (ArgOffset % PtrByteSize != 0) {
6599 if (!isLittleEndian)
6604 }
else if (
Flags.isInConsecutiveRegsLast()) {
6607 if (!isLittleEndian)
6617 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6625 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6630 assert(HasParameterArea &&
6631 "Parameter area must exist to pass an argument in memory.");
6633 true, CFlags.IsTailCall,
false, MemOpChains,
6634 TailCallArguments, dl);
6641 if (!IsFastCall || NeededLoad) {
6643 Flags.isInConsecutiveRegs()) ? 4 : 8;
6644 if (
Flags.isInConsecutiveRegsLast())
6645 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6665 if (CFlags.IsVarArg) {
6666 assert(HasParameterArea &&
6667 "Parameter area must exist if we have a varargs call.");
6671 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
6673 if (VR_idx != NumVRs) {
6675 DAG.
getLoad(MVT::v4f32, dl, Store, PtrOff, MachinePointerInfo());
6677 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6680 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6681 if (GPR_idx == NumGPRs)
6686 DAG.
getLoad(PtrVT, dl, Store, Ix, MachinePointerInfo());
6688 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6694 if (VR_idx != NumVRs) {
6695 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6700 assert(HasParameterArea &&
6701 "Parameter area must exist to pass an argument in memory.");
6703 true, CFlags.IsTailCall,
true, MemOpChains,
6704 TailCallArguments, dl);
6715 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6716 "mismatch in size of parameter area");
6717 (void)NumBytesActuallyUsed;
6719 if (!MemOpChains.
empty())
6725 if (CFlags.IsIndirect) {
6729 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6734 unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
6744 if (isELFv2ABI && !CFlags.IsPatchPoint)
6745 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6751 for (
const auto &[
Reg,
N] : RegsToPass) {
6756 if (CFlags.IsTailCall && !IsSibCall)
6760 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6761 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6768 "Required alignment greater than stack alignment.");
6788 return RequiredAlign <= 8;
6793 return RequiredAlign <= 4;
6801 State.getMachineFunction().getSubtarget());
6802 const bool IsPPC64 = Subtarget.isPPC64();
6803 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6804 const Align PtrAlign(PtrSize);
6805 const Align StackAlign(16);
6808 if (ValVT == MVT::f128)
6812 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6813 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6815 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6816 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6819 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6820 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6821 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6826 MCRegister EnvReg = State.AllocateReg(IsPPC64 ? PPC::X11 : PPC::R11);
6835 if (ByValAlign > StackAlign)
6837 "16 are not supported.");
6840 const Align ObjAlign = ByValAlign > PtrAlign ? ByValAlign : PtrAlign;
6844 if (ByValSize == 0) {
6846 State.getStackSize(), RegVT, LocInfo));
6851 unsigned NextReg = State.getFirstUnallocated(GPRs);
6852 while (NextReg != GPRs.
size() &&
6857 State.AllocateStack(PtrSize, PtrAlign);
6858 assert(
Reg &&
"Alocating register unexpectedly failed.");
6860 NextReg = State.getFirstUnallocated(GPRs);
6863 const unsigned StackSize =
alignTo(ByValSize, ObjAlign);
6864 unsigned Offset = State.AllocateStack(StackSize, ObjAlign);
6884 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6888 const unsigned Offset = State.AllocateStack(PtrSize, PtrAlign);
6907 State.AllocateStack(IsPPC64 ? 8 : StoreSize,
Align(4));
6913 for (
unsigned I = 0;
I < StoreSize;
I += PtrSize) {
6915 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
6916 if (State.isVarArg()) {
6948 const unsigned VecSize = 16;
6949 const Align VecAlign(VecSize);
6951 if (!State.isVarArg()) {
6954 if (
MCRegister VReg = State.AllocateReg(VR)) {
6961 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6966 unsigned NextRegIndex = State.getFirstUnallocated(GPRs);
6969 while (NextRegIndex != GPRs.
size() &&
6973 State.AllocateStack(PtrSize, PtrAlign);
6974 assert(
Reg &&
"Allocating register unexpectedly failed.");
6976 NextRegIndex = State.getFirstUnallocated(GPRs);
6984 if (
MCRegister VReg = State.AllocateReg(VR)) {
6987 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
6988 State.AllocateReg(GPRs);
6989 State.AllocateStack(VecSize, VecAlign);
6993 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6999 if (NextRegIndex == GPRs.
size()) {
7000 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7008 if (GPRs[NextRegIndex] == PPC::R9) {
7009 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7013 const MCRegister FirstReg = State.AllocateReg(PPC::R9);
7014 const MCRegister SecondReg = State.AllocateReg(PPC::R10);
7015 assert(FirstReg && SecondReg &&
7016 "Allocating R9 or R10 unexpectedly failed.");
7027 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7030 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
7032 assert(
Reg &&
"Failed to allocated register for vararg vector argument");
7047 assert((IsPPC64 || SVT != MVT::i64) &&
7048 "i64 should have been split for 32-bit codegen.");
7056 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7058 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
7060 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
7068 return &PPC::VRRCRegClass;
7081 else if (Flags.isZExt())
7093 "Reg must be a valid argument register!");
7094 return LASize + 4 * (
Reg - PPC::R3);
7099 "Reg must be a valid argument register!");
7100 return LASize + 8 * (
Reg - PPC::X3);
7146SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7153 "Unexpected calling convention!");
7161 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7163 const bool IsPPC64 = Subtarget.isPPC64();
7164 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7170 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
7171 CCState CCInfo(CallConv, isVarArg, MF, ArgLocs, *DAG.
getContext());
7175 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7176 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7177 uint64_t SaveStackPos = CCInfo.getStackSize();
7179 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7183 for (
size_t I = 0, End = ArgLocs.
size();
I != End; ) {
7184 CCValAssign &VA = ArgLocs[
I++];
7189 EVT ArgVT = Ins[VA.
getValNo()].ArgVT;
7190 bool ArgSignExt = Ins[VA.
getValNo()].Flags.isSExt();
7202 LocVT.
SimpleTy, IsPPC64, Subtarget.hasP8Vector(), Subtarget.hasVSX());
7204 MVT SaveVT = RegClass == &PPC::G8RCRegClass ? MVT::i64 : LocVT;
7210 MachinePointerInfo(),
Align(PtrByteSize));
7216 unsigned StoreSize =
7218 SaveStackPos =
alignTo(SaveStackPos + StoreSize, PtrByteSize);
7221 auto HandleMemLoc = [&]() {
7224 assert((ValSize <= LocSize) &&
7225 "Object size is larger than size of MemLoc");
7228 if (LocSize > ValSize)
7229 CurArgOffset += LocSize - ValSize;
7231 const bool IsImmutable =
7237 DAG.
getLoad(ValVT, dl, Chain, FIN, MachinePointerInfo());
7271 assert(isVarArg &&
"Only use custom memloc for vararg.");
7274 const unsigned OriginalValNo = VA.
getValNo();
7275 (void)OriginalValNo;
7277 auto HandleCustomVecRegLoc = [&]() {
7278 assert(
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7279 "Missing custom RegLoc.");
7282 "Unexpected Val type for custom RegLoc.");
7284 "ValNo mismatch between custom MemLoc and RegLoc.");
7288 Subtarget.hasVSX()));
7295 HandleCustomVecRegLoc();
7296 HandleCustomVecRegLoc();
7300 if (
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7302 "Only 2 custom RegLocs expected for 64-bit codegen.");
7303 HandleCustomVecRegLoc();
7304 HandleCustomVecRegLoc();
7348 const unsigned Size =
7360 if (
Flags.isByVal()) {
7364 const PPCFrameLowering *FL = Subtarget.getFrameLowering();
7366 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7374 const TargetRegisterClass *RegClass =
7375 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7377 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7390 CopyFrom.
getValue(1), dl, CopyFrom,
7400 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7403 "RegLocs should be for ByVal argument.");
7405 const CCValAssign RL = ArgLocs[
I++];
7410 if (
Offset != StackSize) {
7412 "Expected MemLoc for remaining bytes.");
7413 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7427 Subtarget.hasVSX()));
7444 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7446 unsigned CallerReservedArea = std::max<unsigned>(
7447 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7453 CallerReservedArea =
7458 int VAListIndex = 0;
7462 if (CCInfo.getStackSize() < (LinkageSize + MinParameterSaveArea)) {
7463 unsigned FixedStackSize =
7464 LinkageSize + MinParameterSaveArea - CCInfo.getStackSize();
7480 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7481 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7483 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7484 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7485 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7491 GPRIndex = (CCInfo.getStackSize() - LinkageSize) / PtrByteSize,
7493 GPRIndex < NumGPArgRegs; ++GPRIndex,
Offset += PtrByteSize) {
7496 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7497 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7500 MachinePointerInfo MPI =
7510 if (!MemOps.
empty())
7516SDValue PPCTargetLowering::LowerCall_AIX(
7529 "Unexpected calling convention!");
7531 if (CFlags.IsPatchPoint)
7534 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7538 CCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7545 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7546 const bool IsPPC64 = Subtarget.isPPC64();
7548 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7549 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7550 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7558 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7559 const unsigned NumBytes = std::max<unsigned>(
7560 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7576 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E;) {
7577 const unsigned ValNo = ArgLocs[
I].getValNo();
7579 ISD::ArgFlagsTy
Flags = Outs[ValNo].Flags;
7581 if (
Flags.isByVal()) {
7582 const unsigned ByValSize =
Flags.getByValSize();
7590 auto GetLoad = [&](EVT VT,
unsigned LoadOffset) {
7596 MachinePointerInfo(), VT);
7599 unsigned LoadOffset = 0;
7602 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7605 LoadOffset += PtrByteSize;
7606 const CCValAssign &ByValVA = ArgLocs[
I++];
7608 "Unexpected location for pass-by-value argument.");
7612 if (LoadOffset == ByValSize)
7616 assert(ArgLocs[
I].getValNo() == ValNo &&
7617 "Expected additional location for by-value argument.");
7619 if (ArgLocs[
I].isMemLoc()) {
7620 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7621 const CCValAssign &ByValVA = ArgLocs[
I++];
7622 ISD::ArgFlagsTy MemcpyFlags =
Flags;
7625 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7631 CallSeqStart, MemcpyFlags, DAG, dl);
7640 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7641 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7642 "Unexpected register residue for by-value argument.");
7644 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7648 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7658 "Unexpected load emitted during handling of pass-by-value "
7666 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7671 const CCValAssign &ByValVA = ArgLocs[
I++];
7676 CCValAssign &VA = ArgLocs[
I++];
7701 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7707 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
7709 const unsigned OriginalValNo = VA.
getValNo();
7711 unsigned LoadOffset = 0;
7712 auto HandleCustomVecRegLoc = [&]() {
7713 assert(
I !=
E &&
"Unexpected end of CCvalAssigns.");
7714 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7715 "Expected custom RegLoc.");
7716 CCValAssign RegVA = ArgLocs[
I++];
7718 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7724 LoadOffset += PtrByteSize;
7730 HandleCustomVecRegLoc();
7731 HandleCustomVecRegLoc();
7733 if (
I !=
E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7734 ArgLocs[
I].getValNo() == OriginalValNo) {
7736 "Only 2 custom RegLocs expected for 64-bit codegen.");
7737 HandleCustomVecRegLoc();
7738 HandleCustomVecRegLoc();
7749 DAG.
getStore(Chain, dl, Arg, PtrOff,
7751 Subtarget.getFrameLowering()->getStackAlign()));
7758 "Unexpected register handling for calling convention.");
7764 "Custom register handling only expected for VarArg.");
7769 if (Arg.getValueType().getStoreSize() == LocVT.
getStoreSize())
7773 else if (Arg.getValueType().getFixedSizeInBits() <
7781 assert(Arg.getValueType() == MVT::f64 && CFlags.IsVarArg && !IsPPC64 &&
7782 "Unexpected custom register for argument!");
7783 CCValAssign &GPR1 = VA;
7792 CCValAssign &PeekArg = ArgLocs[
I];
7795 CCValAssign &GPR2 = ArgLocs[
I++];
7803 if (!MemOpChains.
empty())
7808 if (CFlags.IsIndirect && !Subtarget.usePointerGlueHelper()) {
7809 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7810 const MCRegister TOCBaseReg = Subtarget.getTOCPointerRegister();
7811 const MCRegister StackPtrReg = Subtarget.getStackPointerRegister();
7812 const MVT PtrVT = Subtarget.getScalarIntVT();
7813 const unsigned TOCSaveOffset =
7814 Subtarget.getFrameLowering()->getTOCSaveOffset();
7829 for (
auto Reg : RegsToPass) {
7834 const int SPDiff = 0;
7835 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7836 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7844 const Type *RetTy)
const {
7846 CCState CCInfo(CallConv, isVarArg, MF, RVLocs,
Context);
7847 return CCInfo.CheckReturn(
7862 CCInfo.AnalyzeReturn(Outs,
7871 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7872 CCValAssign &VA = RVLocs[i];
7875 SDValue Arg = OutVals[RealResIdx];
7890 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7891 bool isLittleEndian = Subtarget.isLittleEndian();
7894 DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7898 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7913 RetOps.push_back(Glue);
7915 return DAG.
getNode(PPCISD::RET_GLUE, dl, MVT::Other, RetOps);
7919PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7924 EVT IntVT =
Op.getValueType();
7928 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7932 return DAG.
getNode(PPCISD::DYNAREAOFFSET, dl, VTs,
Ops);
7944 bool isPPC64 = Subtarget.isPPC64();
7945 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7954 DAG.
getLoad(PtrVT, dl, Chain, StackPtr, MachinePointerInfo());
7960 return DAG.
getStore(Chain, dl, LoadLinkSP, StackPtr, MachinePointerInfo());
7965 bool isPPC64 = Subtarget.isPPC64();
7970 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
7976 int LROffset = Subtarget.getFrameLowering()->getReturnSaveOffset();
7986PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
7988 bool isPPC64 = Subtarget.isPPC64();
7993 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
7999 int FPOffset = Subtarget.getFrameLowering()->getFramePointerSaveOffset();
8022 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
8024 SDVTList VTs = DAG.
getVTList(PtrVT, MVT::Other);
8026 return DAG.
getNode(PPCISD::PROBED_ALLOCA, dl, VTs,
Ops);
8027 return DAG.
getNode(PPCISD::DYNALLOC, dl, VTs,
Ops);
8034 bool isPPC64 = Subtarget.isPPC64();
8044 return DAG.
getNode(PPCISD::EH_SJLJ_SETJMP,
DL,
8046 Op.getOperand(0),
Op.getOperand(1));
8052 return DAG.
getNode(PPCISD::EH_SJLJ_LONGJMP,
DL, MVT::Other,
8053 Op.getOperand(0),
Op.getOperand(1));
8057 if (
Op.getValueType().isVector())
8058 return LowerVectorLoad(
Op, DAG);
8060 assert(
Op.getValueType() == MVT::i1 &&
8061 "Custom lowering only for i1 loads");
8070 MachineMemOperand *MMO =
LD->getMemOperand();
8074 BasePtr, MVT::i8, MMO);
8082 if (
Op.getOperand(1).getValueType().isVector())
8083 return LowerVectorStore(
Op, DAG);
8085 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
8086 "Custom lowering only for i1 stores");
8096 MachineMemOperand *MMO =
ST->getMemOperand();
8105 assert(
Op.getValueType() == MVT::i1 &&
8106 "Custom lowering only for i1 results");
8134 EVT TrgVT =
Op.getValueType();
8158 if (SrcSize == 256) {
8169 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8175 SmallVector<int, 16> ShuffV;
8176 if (Subtarget.isLittleEndian())
8177 for (
unsigned i = 0; i < TrgNumElts; ++i)
8180 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8184 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8197 EVT ResVT =
Op.getValueType();
8198 EVT CmpVT =
Op.getOperand(0).getValueType();
8200 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8206 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8219 SDNodeFlags
Flags =
Op.getNode()->getFlags();
8223 if (Subtarget.hasP9Vector() &&
LHS == TV &&
RHS == FV) {
8240 if (!
Flags.hasNoInfs() || !
Flags.hasNoNaNs() || ResVT == MVT::f128)
8253 if (
LHS.getValueType() == MVT::f32)
8255 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8258 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8266 if (
LHS.getValueType() == MVT::f32)
8268 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8275 if (
LHS.getValueType() == MVT::f32)
8277 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8289 if (
Cmp.getValueType() == MVT::f32)
8291 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8294 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8299 if (
Cmp.getValueType() == MVT::f32)
8301 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8305 if (
Cmp.getValueType() == MVT::f32)
8307 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8311 if (
Cmp.getValueType() == MVT::f32)
8313 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8317 if (
Cmp.getValueType() == MVT::f32)
8319 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8328 case PPCISD::FCTIDZ:
8329 return PPCISD::STRICT_FCTIDZ;
8330 case PPCISD::FCTIWZ:
8331 return PPCISD::STRICT_FCTIWZ;
8332 case PPCISD::FCTIDUZ:
8333 return PPCISD::STRICT_FCTIDUZ;
8334 case PPCISD::FCTIWUZ:
8335 return PPCISD::STRICT_FCTIWUZ;
8337 return PPCISD::STRICT_FCFID;
8338 case PPCISD::FCFIDU:
8339 return PPCISD::STRICT_FCFIDU;
8340 case PPCISD::FCFIDS:
8341 return PPCISD::STRICT_FCFIDS;
8342 case PPCISD::FCFIDUS:
8343 return PPCISD::STRICT_FCFIDUS;
8350 bool IsStrict =
Op->isStrictFPOpcode();
8359 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8361 MVT DestTy =
Op.getSimpleValueType();
8362 assert(Src.getValueType().isFloatingPoint() &&
8363 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8364 DestTy == MVT::i64) &&
8365 "Invalid FP_TO_INT types");
8366 if (Src.getValueType() == MVT::f32) {
8370 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8375 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8381 Opc = IsSigned ? PPCISD::FCTIWZ
8382 : (Subtarget.hasFPCVT() ? PPCISD::FCTIWUZ : PPCISD::FCTIDZ);
8385 assert((IsSigned || Subtarget.hasFPCVT()) &&
8386 "i64 FP_TO_UINT is supported only with FPCVT");
8387 Opc = IsSigned ? PPCISD::FCTIDZ : PPCISD::FCTIDUZ;
8389 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8401void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8403 const SDLoc &dl)
const {
8407 bool IsStrict =
Op->isStrictFPOpcode();
8410 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8411 (IsSigned || Subtarget.hasFPCVT());
8414 MachinePointerInfo MPI =
8422 Alignment =
Align(4);
8423 MachineMemOperand *MMO =
8429 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8433 if (
Op.getValueType() == MVT::i32 && !i32Stack &&
8434 !Subtarget.isLittleEndian()) {
8443 RLI.Alignment = Alignment;
8451 const SDLoc &dl)
const {
8454 if (
Op->isStrictFPOpcode())
8461 const SDLoc &dl)
const {
8462 bool IsStrict =
Op->isStrictFPOpcode();
8465 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8466 EVT SrcVT = Src.getValueType();
8467 EVT DstVT =
Op.getValueType();
8470 if (SrcVT == MVT::f128)
8471 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8475 if (SrcVT == MVT::ppcf128) {
8476 if (DstVT == MVT::i32) {
8481 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8492 {Op.getOperand(0), Lo, Hi}, Flags);
8495 {Res.getValue(1), Res}, Flags);
8501 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8525 {Chain, Src, FltOfs}, Flags);
8529 {Chain, Val}, Flags);
8532 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8550 if (Subtarget.hasDirectMove() && Subtarget.isPPC64())
8551 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8554 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8556 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8557 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8568bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8573 if (
Op->isStrictFPOpcode())
8578 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8582 Op.getOperand(0).getValueType())) {
8584 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8589 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8590 LD->isNonTemporal())
8592 if (
LD->getMemoryVT() != MemVT)
8602 RLI.Ptr =
LD->getBasePtr();
8603 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8605 "Non-pre-inc AM on PPC?");
8610 RLI.Chain =
LD->getChain();
8611 RLI.MPI =
LD->getPointerInfo();
8612 RLI.IsDereferenceable =
LD->isDereferenceable();
8613 RLI.IsInvariant =
LD->isInvariant();
8614 RLI.Alignment =
LD->getAlign();
8615 RLI.AAInfo =
LD->getAAInfo();
8616 RLI.Ranges =
LD->getRanges();
8618 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8625bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8626 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8633 if (!Subtarget.hasP9Vector() &&
8637 for (SDUse &Use : Origin->
uses()) {
8640 if (
Use.getResNo() != 0)
8667 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8668 unsigned ConvOpc = IsSingle ? (IsSigned ? PPCISD::FCFIDS : PPCISD::FCFIDUS)
8669 : (IsSigned ? PPCISD::FCFID : PPCISD::FCFIDU);
8670 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8671 if (
Op->isStrictFPOpcode()) {
8673 Chain =
Op.getOperand(0);
8675 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8677 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8685 const SDLoc &dl)
const {
8686 assert((
Op.getValueType() == MVT::f32 ||
8687 Op.getValueType() == MVT::f64) &&
8688 "Invalid floating point type as target of conversion");
8689 assert(Subtarget.hasFPCVT() &&
8690 "Int to FP conversions with direct moves require FPCVT");
8691 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8692 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8695 unsigned MovOpc = (WordInt && !
Signed) ? PPCISD::MTVSRZ : PPCISD::MTVSRA;
8714 for (
unsigned i = 1; i < NumConcat; ++i)
8721 const SDLoc &dl)
const {
8722 bool IsStrict =
Op->isStrictFPOpcode();
8723 unsigned Opc =
Op.getOpcode();
8724 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8727 "Unexpected conversion type");
8728 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8729 "Supports conversions to v2f64/v4f32 only.");
8733 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8736 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8741 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8743 SmallVector<int, 16> ShuffV;
8744 for (
unsigned i = 0; i < WideNumElts; ++i)
8747 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8748 int SaveElts = FourEltRes ? 4 : 2;
8749 if (Subtarget.isLittleEndian())
8750 for (
int i = 0; i < SaveElts; i++)
8751 ShuffV[i * Stride] = i;
8753 for (
int i = 1; i <= SaveElts; i++)
8754 ShuffV[i * Stride - 1] = i - 1;
8762 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8763 EVT ExtVT = Src.getValueType();
8764 if (Subtarget.hasP9Altivec())
8775 {Op.getOperand(0), Extend}, Flags);
8777 return DAG.
getNode(
Opc, dl,
Op.getValueType(), Extend);
8785 bool IsStrict =
Op->isStrictFPOpcode();
8786 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8791 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8793 EVT InVT = Src.getValueType();
8794 EVT OutVT =
Op.getValueType();
8797 return LowerINT_TO_FPVector(
Op, DAG, dl);
8800 if (
Op.getValueType() == MVT::f128)
8801 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8804 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8807 if (Src.getValueType() == MVT::i1) {
8819 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8820 Subtarget.isPPC64() && Subtarget.hasFPCVT())
8821 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8823 assert((IsSigned || Subtarget.hasFPCVT()) &&
8824 "UINT_TO_FP is supported only with FPCVT");
8826 if (Src.getValueType() == MVT::i64) {
8841 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT() &&
8842 !
Op->getFlags().hasApproximateFuncs()) {
8882 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8885 Bits = DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8886 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo,
nullptr);
8889 }
else if (Subtarget.hasLFIWAX() &&
8890 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8891 MachineMemOperand *MMO =
8893 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8897 Ops, MVT::i32, MMO);
8900 }
else if (Subtarget.hasFPCVT() &&
8901 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8902 MachineMemOperand *MMO =
8904 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8908 Ops, MVT::i32, MMO);
8911 }
else if (((Subtarget.hasLFIWAX() &&
8913 (Subtarget.hasFPCVT() &&
8928 "Expected an i32 store");
8934 RLI.Alignment =
Align(4);
8936 MachineMemOperand *MMO =
8938 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8941 PPCISD::LFIWZX : PPCISD::LFIWAX,
8942 dl, DAG.
getVTList(MVT::f64, MVT::Other),
8943 Ops, MVT::i32, MMO);
8944 Chain =
Bits.getValue(1);
8952 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8956 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)},
8965 assert(Src.getValueType() == MVT::i32 &&
8966 "Unhandled INT_TO_FP type in custom expander!");
8976 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
8979 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
8989 "Expected an i32 store");
8995 RLI.Alignment =
Align(4);
8998 MachineMemOperand *MMO =
9000 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
9006 if (ReusingLoad && RLI.ResChain) {
9010 assert(Subtarget.isPPC64() &&
9011 "i32->FP without LFIWAX supported only on PPC64");
9020 Chain, dl, Ext64, FIdx,
9026 MVT::f64, dl, Chain, FIdx,
9035 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
9039 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)}, Flags);
9056 uint64_t
Mode = CVal->getZExtValue();
9057 assert(
Mode < 4 &&
"Unsupported rounding mode!");
9058 unsigned InternalRnd =
Mode ^ (~(
Mode >> 1) & 1);
9059 if (Subtarget.isISA3_0())
9062 PPC::MFFSCRNI, Dl, {MVT::f64, MVT::Other},
9063 {DAG.getConstant(InternalRnd, Dl, MVT::i32, true), Chain}),
9066 (InternalRnd & 2) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9067 {DAG.
getConstant(30, Dl, MVT::i32,
true), Chain});
9069 (InternalRnd & 1) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9087 if (!Subtarget.isISA3_0()) {
9088 MFFS = DAG.
getNode(PPCISD::MFFS, Dl, {MVT::f64, MVT::Other}, Chain);
9092 if (Subtarget.isPPC64()) {
9093 if (Subtarget.isISA3_0()) {
9098 PPC::RLDIMI, Dl, MVT::i64,
9103 NewFPSCR =
SDValue(InsertRN, 0);
9110 SDValue Addr = Subtarget.isLittleEndian()
9114 if (Subtarget.isISA3_0()) {
9115 Chain = DAG.
getStore(Chain, Dl, DstFlag, Addr, MachinePointerInfo());
9117 Chain = DAG.
getStore(Chain, Dl, MFFS, StackSlot, MachinePointerInfo());
9119 DAG.
getLoad(MVT::i32, Dl, Chain, Addr, MachinePointerInfo());
9122 PPC::RLWIMI, Dl, MVT::i32,
9123 {Tmp, DstFlag, DAG.getTargetConstant(0, Dl, MVT::i32),
9124 DAG.getTargetConstant(30, Dl, MVT::i32),
9125 DAG.getTargetConstant(31, Dl, MVT::i32)}),
9127 Chain = DAG.
getStore(Chain, Dl, Tmp, Addr, MachinePointerInfo());
9130 DAG.
getLoad(MVT::f64, Dl, Chain, StackSlot, MachinePointerInfo());
9133 if (Subtarget.isISA3_0())
9139 PPC::MTFSF, Dl, MVT::Other,
9167 EVT VT =
Op.getValueType();
9172 SDValue MFFS = DAG.
getNode(PPCISD::MFFS, dl, {MVT::f64, MVT::Other}, Chain);
9183 Chain = DAG.
getStore(Chain, dl, MFFS, StackSlot, MachinePointerInfo());
9187 "Stack slot adjustment is valid only on big endian subtargets!");
9190 CWD = DAG.
getLoad(MVT::i32, dl, Chain, Addr, MachinePointerInfo());
9217 EVT VT =
Op.getValueType();
9221 VT ==
Op.getOperand(1).getValueType() &&
9241 SDValue OutOps[] = { OutLo, OutHi };
9246 EVT VT =
Op.getValueType();
9250 VT ==
Op.getOperand(1).getValueType() &&
9270 SDValue OutOps[] = { OutLo, OutHi };
9276 EVT VT =
Op.getValueType();
9279 VT ==
Op.getOperand(1).getValueType() &&
9299 SDValue OutOps[] = { OutLo, OutHi };
9306 EVT VT =
Op.getValueType();
9313 EVT AmtVT =
Z.getValueType();
9323 X = DAG.
getNode(PPCISD::SHL, dl, VT,
X, IsFSHL ? Z : SubZ);
9324 Y = DAG.
getNode(PPCISD::SRL, dl, VT,
Y, IsFSHL ? SubZ : Z);
9336 static const MVT VTys[] = {
9337 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9340 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9343 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9348 EVT CanonicalVT = VTys[SplatSize-1];
9361 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9362 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9371 EVT DestVT = MVT::Other) {
9372 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9381 EVT DestVT = MVT::Other) {
9384 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9396 for (
unsigned i = 0; i != 16; ++i)
9417 EVT VecVT = V->getValueType(0);
9418 bool RightType = VecVT == MVT::v2f64 ||
9419 (HasP8Vector && VecVT == MVT::v4f32) ||
9420 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9424 bool IsSplat =
true;
9425 bool IsLoad =
false;
9431 if (V->isConstant())
9433 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9434 if (V->getOperand(i).isUndef())
9438 if (V->getOperand(i).getOpcode() ==
ISD::LOAD ||
9440 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9442 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9444 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD))
9448 if (V->getOperand(i) != Op0 ||
9449 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9452 return !(IsSplat && IsLoad);
9462 (
Op.getValueType() != MVT::f128))
9467 if ((
Lo.getValueType() != MVT::i64) || (
Hi.getValueType() != MVT::i64))
9470 if (!Subtarget.isLittleEndian())
9473 return DAG.
getNode(PPCISD::BUILD_FP128, dl, MVT::f128,
Lo,
Hi);
9481 InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED) {
9482 IsPermuted = InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED;
9495 APFloat APFloatToConvert = ArgAPFloat;
9496 bool LosesInfo =
true;
9501 ArgAPFloat = APFloatToConvert;
9523 APFloat APFloatToConvert = ArgAPFloat;
9524 bool LosesInfo =
true;
9528 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9537 EVT Ty =
Op->getValueType(0);
9540 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9549 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9553 if (Ty == MVT::v2i64) {
9556 if (MemVT == MVT::i32) {
9558 Opcode = PPCISD::ZEXT_LD_SPLAT;
9560 Opcode = PPCISD::SEXT_LD_SPLAT;
9568 bool IsLittleEndian) {
9574 APInt ConstValue(VTSize, 0);
9578 unsigned BitPos = 0;
9586 ConstValue.
insertBits(CN->getAPIntValue().zextOrTrunc(EltWidth),
9587 IsLittleEndian ? BitPos : VTSize - EltWidth - BitPos);
9591 for (
unsigned J = 0; J < 16; ++J) {
9593 if (ExtractValue != 0x00 && ExtractValue != 0xFF)
9595 if (ExtractValue == 0xFF)
9610 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9612 if (Subtarget.hasP10Vector()) {
9613 APInt BitMask(32, 0);
9619 BitMask != 0 && BitMask != 0xffff) {
9621 MachineSDNode *MSDNode =
9633 if (
SDValue VecPat = combineBVLoadsSpecialValue(
Op, DAG))
9637 APInt APSplatBits, APSplatUndef;
9638 unsigned SplatBitSize = 0;
9640 bool BVNIsConstantSplat =
9642 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
9648 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9649 Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
9652 if ((
Op->getValueType(0) == MVT::v2f64) &&
9655 PPCISD::XXSPLTI_SP_TO_DP, dl, MVT::v2f64,
9671 PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9677 DAG.
getNode(PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9686 LowerVecSplatSmallFP(
Op, DAG, BVNIsConstantSplat, SplatBitSize))
9689 bool IsSplat64 =
false;
9690 uint64_t SplatBits = 0;
9691 int32_t SextVal = 0;
9692 if (BVNIsConstantSplat && SplatBitSize <= 64) {
9694 if (SplatBitSize <= 32) {
9696 }
else if (SplatBitSize == 64 && Subtarget.hasP8Altivec()) {
9697 int64_t Splat64Val =
static_cast<int64_t
>(SplatBits);
9698 bool P9Vector = Subtarget.hasP9Vector();
9699 int32_t
Hi = P9Vector ? 127 : 15;
9700 int32_t
Lo = P9Vector ? -128 : -16;
9701 IsSplat64 = Splat64Val >=
Lo && Splat64Val <=
Hi;
9702 SextVal =
static_cast<int32_t
>(SplatBits);
9706 if (!BVNIsConstantSplat || (SplatBitSize > 32 && !IsSplat64)) {
9707 unsigned NewOpcode = PPCISD::LD_SPLAT;
9713 const SDValue *InputLoad = &
Op.getOperand(0);
9718 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9719 unsigned ElementSize =
9720 MemorySize * ((NewOpcode == PPCISD::LD_SPLAT) ? 1 : 2);
9722 assert(((ElementSize == 2 * MemorySize)
9723 ? (NewOpcode == PPCISD::ZEXT_LD_SPLAT ||
9724 NewOpcode == PPCISD::SEXT_LD_SPLAT)
9725 : (NewOpcode == PPCISD::LD_SPLAT)) &&
9726 "Unmatched element size and opcode!\n");
9731 unsigned NumUsesOfInputLD = 128 / ElementSize;
9733 if (BVInOp.isUndef())
9748 if (NumUsesOfInputLD == 1 &&
9749 (
Op->getValueType(0) == MVT::v2i64 && NewOpcode != PPCISD::LD_SPLAT &&
9750 !Subtarget.isLittleEndian() && Subtarget.hasVSX() &&
9751 Subtarget.hasLFIWAX()))
9759 if (NumUsesOfInputLD == 1 && Subtarget.isLittleEndian() &&
9760 Subtarget.isISA3_1() && ElementSize <= 16)
9763 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9765 Subtarget.hasVSX()) {
9772 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other),
Ops,
9773 LD->getMemoryVT(),
LD->getMemOperand());
9785 if (Subtarget.hasVSX() && Subtarget.isPPC64() &&
9787 Subtarget.hasP8Vector()))
9793 unsigned SplatSize = SplatBitSize / 8;
9798 if (SplatBits == 0) {
9800 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9812 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 2)
9814 Op.getValueType(), DAG, dl);
9816 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 4)
9821 if (Subtarget.hasP9Vector() && SplatSize == 1)
9827 if (SextVal >= -16 && SextVal <= 15) {
9830 unsigned UseSize = SplatSize == 8 ? 4 : SplatSize;
9837 DAG.
getBitcast(MVT::v4i32, Res), DAG, dl, MVT::v2i64);
9843 if (Subtarget.hasP9Vector() && SextVal >= -128 && SextVal <= 127) {
9849 switch (SplatSize) {
9853 IID = Intrinsic::ppc_altivec_vupklsb;
9857 IID = Intrinsic::ppc_altivec_vextsb2w;
9861 IID = Intrinsic::ppc_altivec_vextsb2d;
9868 assert(!IsSplat64 &&
"Unhandled 64-bit splat pattern");
9877 if (SextVal >= -32 && SextVal <= 31) {
9882 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9883 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9886 if (VT ==
Op.getValueType())
9895 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9909 static const signed char SplatCsts[] = {
9910 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9911 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9914 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9917 int i = SplatCsts[idx];
9921 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9924 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9926 static const unsigned IIDs[] = {
9927 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9928 Intrinsic::ppc_altivec_vslw
9935 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9937 static const unsigned IIDs[] = {
9938 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9939 Intrinsic::ppc_altivec_vsrw
9946 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9947 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9949 static const unsigned IIDs[] = {
9950 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
9951 Intrinsic::ppc_altivec_vrlw
9958 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
9960 unsigned Amt = Subtarget.isLittleEndian() ? 15 : 1;
9964 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
9966 unsigned Amt = Subtarget.isLittleEndian() ? 14 : 2;
9970 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
9972 unsigned Amt = Subtarget.isLittleEndian() ? 13 : 3;
9985 unsigned OpNum = (PFEntry >> 26) & 0x0F;
9986 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
9987 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
10003 if (LHSID == (1*9+2)*9+3)
return LHS;
10004 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
10016 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
10017 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
10018 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
10019 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
10022 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
10023 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
10024 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
10025 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
10028 for (
unsigned i = 0; i != 16; ++i)
10029 ShufIdxs[i] = (i&3)+0;
10032 for (
unsigned i = 0; i != 16; ++i)
10033 ShufIdxs[i] = (i&3)+4;
10036 for (
unsigned i = 0; i != 16; ++i)
10037 ShufIdxs[i] = (i&3)+8;
10040 for (
unsigned i = 0; i != 16; ++i)
10041 ShufIdxs[i] = (i&3)+12;
10062 const unsigned BytesInVector = 16;
10063 bool IsLE = Subtarget.isLittleEndian();
10067 unsigned ShiftElts = 0, InsertAtByte = 0;
10071 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
10072 0, 15, 14, 13, 12, 11, 10, 9};
10073 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
10074 1, 2, 3, 4, 5, 6, 7, 8};
10076 ArrayRef<int>
Mask =
N->getMask();
10077 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
10089 bool FoundCandidate =
false;
10093 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
10096 for (
unsigned i = 0; i < BytesInVector; ++i) {
10097 unsigned CurrentElement =
Mask[i];
10100 if (V2.
isUndef() && CurrentElement != VINSERTBSrcElem)
10103 bool OtherElementsInOrder =
true;
10106 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
10113 (!V2.
isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
10114 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
10115 OtherElementsInOrder =
false;
10122 if (OtherElementsInOrder) {
10129 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
10130 : BigEndianShifts[CurrentElement & 0xF];
10131 Swap = CurrentElement < BytesInVector;
10133 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
10134 FoundCandidate =
true;
10139 if (!FoundCandidate)
10149 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10151 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8, V1, Shl,
10154 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8, V1, V2,
10163 const unsigned NumHalfWords = 8;
10164 const unsigned BytesInVector = NumHalfWords * 2;
10169 bool IsLE = Subtarget.isLittleEndian();
10173 unsigned ShiftElts = 0, InsertAtByte = 0;
10177 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
10178 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
10181 uint32_t OriginalOrderLow = 0x1234567;
10182 uint32_t OriginalOrderHigh = 0x89ABCDEF;
10185 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10186 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10203 bool FoundCandidate =
false;
10206 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10207 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10209 uint32_t MaskOtherElts = ~(0xF <<
MaskShift);
10210 uint32_t TargetOrder = 0x0;
10217 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
10218 TargetOrder = OriginalOrderLow;
10222 if (MaskOneElt == VINSERTHSrcElem &&
10223 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10224 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10225 FoundCandidate =
true;
10231 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
10233 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10235 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
10236 : BigEndianShifts[MaskOneElt & 0x7];
10237 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10238 Swap = MaskOneElt < NumHalfWords;
10239 FoundCandidate =
true;
10245 if (!FoundCandidate)
10257 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10260 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
10265 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
10280 auto ShuffleMask = SVN->
getMask();
10295 ShuffleMask = CommutedSV->
getMask();
10304 APInt APSplatValue, APSplatUndef;
10305 unsigned SplatBitSize;
10308 HasAnyUndefs, 0, !Subtarget.isLittleEndian()) ||
10320 bool IsLE = Subtarget.isLittleEndian();
10321 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
10322 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
10323 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
10325 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
10326 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
10327 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
10335 for (; SplatBitSize < 32; SplatBitSize <<= 1)
10336 SplatVal |= (SplatVal << SplatBitSize);
10339 PPCISD::XXSPLTI32DX,
DL, MVT::v2i64, DAG.
getBitcast(MVT::v2i64,
LHS),
10350 assert(
Op.getValueType() == MVT::v1i128 &&
10351 "Only set v1i128 as custom, other type shouldn't reach here!");
10356 if (SHLAmt % 8 == 0) {
10357 std::array<int, 16>
Mask;
10358 std::iota(
Mask.begin(),
Mask.end(), 0);
10359 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10388 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10393 V1 =
Op.getOperand(0);
10394 V2 =
Op.getOperand(1);
10396 EVT VT =
Op.getValueType();
10397 bool isLittleEndian = Subtarget.isLittleEndian();
10399 unsigned ShiftElts, InsertAtByte;
10405 bool IsPermutedLoad =
false;
10407 if (InputLoad && Subtarget.hasVSX() && V2.
isUndef() &&
10417 if (IsPermutedLoad) {
10418 assert((isLittleEndian || IsFourByte) &&
10419 "Unexpected size for permuted load on big endian target");
10420 SplatIdx += IsFourByte ? 2 : 1;
10421 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10422 "Splat of a value outside of the loaded memory");
10427 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10430 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10432 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10436 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10449 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10452 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10461 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10464 if (Subtarget.hasP9Vector() &&
10474 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv2, Conv2,
10476 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Shl,
10480 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Conv2,
10485 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
10487 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10488 return SplatInsertNode;
10491 if (Subtarget.hasP9Altivec()) {
10493 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10496 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10500 if (Subtarget.hasVSX() &&
10508 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv1, Conv2,
10513 if (Subtarget.hasVSX() &&
10521 SDValue PermDI = DAG.
getNode(PPCISD::XXPERMDI, dl, MVT::v2i64, Conv1, Conv2,
10526 if (Subtarget.hasP9Vector()) {
10546 if (Subtarget.hasVSX()) {
10559 SDValue Swap = DAG.
getNode(PPCISD::SWAP_NO_CHAIN, dl, MVT::v2f64, Conv);
10567 if (V2.isUndef()) {
10580 (Subtarget.hasP8Altivec() && (
10591 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10601 (Subtarget.hasP8Altivec() && (
10609 ArrayRef<int> PermMask = SVOp->
getMask();
10612 unsigned PFIndexes[4];
10613 bool isFourElementShuffle =
true;
10614 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10616 unsigned EltNo = 8;
10617 for (
unsigned j = 0;
j != 4; ++
j) {
10618 if (PermMask[i * 4 + j] < 0)
10621 unsigned ByteSource = PermMask[i * 4 +
j];
10622 if ((ByteSource & 3) != j) {
10623 isFourElementShuffle =
false;
10628 EltNo = ByteSource / 4;
10629 }
else if (EltNo != ByteSource / 4) {
10630 isFourElementShuffle =
false;
10634 PFIndexes[i] = EltNo;
10642 if (isFourElementShuffle) {
10644 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10645 PFIndexes[2] * 9 + PFIndexes[3];
10648 unsigned Cost = (PFEntry >> 30);
10668 if (V2.isUndef()) V2 = V1;
10670 return LowerVPERM(
Op, DAG, PermMask, VT, V1, V2);
10676 unsigned Opcode = PPCISD::VPERM;
10679 bool NeedSwap =
false;
10680 bool isLittleEndian = Subtarget.isLittleEndian();
10681 bool isPPC64 = Subtarget.isPPC64();
10683 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10685 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10686 "XXPERM instead\n");
10687 Opcode = PPCISD::XXPERM;
10695 NeedSwap = !NeedSwap;
10730 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10732 if (V1HasXXSWAPD) {
10735 else if (SrcElt < 16)
10738 if (V2HasXXSWAPD) {
10741 else if (SrcElt > 15)
10750 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10751 if (isLittleEndian)
10753 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10756 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10759 if (V1HasXXSWAPD) {
10763 if (V2HasXXSWAPD) {
10768 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10769 if (ValType != MVT::v2f64)
10775 ShufflesHandledWithVPERM++;
10779 if (Opcode == PPCISD::XXPERM) {
10780 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10782 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10785 dbgs() <<
"With the following permute control vector:\n";
10789 if (Opcode == PPCISD::XXPERM)
10790 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10794 if (isLittleEndian)
10800 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10812 switch (IntrinsicID) {
10816 case Intrinsic::ppc_altivec_vcmpbfp_p:
10820 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10824 case Intrinsic::ppc_altivec_vcmpequb_p:
10828 case Intrinsic::ppc_altivec_vcmpequh_p:
10832 case Intrinsic::ppc_altivec_vcmpequw_p:
10836 case Intrinsic::ppc_altivec_vcmpequd_p:
10837 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10843 case Intrinsic::ppc_altivec_vcmpneb_p:
10844 case Intrinsic::ppc_altivec_vcmpneh_p:
10845 case Intrinsic::ppc_altivec_vcmpnew_p:
10846 case Intrinsic::ppc_altivec_vcmpnezb_p:
10847 case Intrinsic::ppc_altivec_vcmpnezh_p:
10848 case Intrinsic::ppc_altivec_vcmpnezw_p:
10849 if (Subtarget.hasP9Altivec()) {
10850 switch (IntrinsicID) {
10853 case Intrinsic::ppc_altivec_vcmpneb_p:
10856 case Intrinsic::ppc_altivec_vcmpneh_p:
10859 case Intrinsic::ppc_altivec_vcmpnew_p:
10862 case Intrinsic::ppc_altivec_vcmpnezb_p:
10865 case Intrinsic::ppc_altivec_vcmpnezh_p:
10868 case Intrinsic::ppc_altivec_vcmpnezw_p:
10876 case Intrinsic::ppc_altivec_vcmpgefp_p:
10880 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10884 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10888 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10892 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10896 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10897 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10903 case Intrinsic::ppc_altivec_vcmpgtub_p:
10907 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10911 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10915 case Intrinsic::ppc_altivec_vcmpgtud_p:
10916 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10923 case Intrinsic::ppc_altivec_vcmpequq:
10924 case Intrinsic::ppc_altivec_vcmpgtsq:
10925 case Intrinsic::ppc_altivec_vcmpgtuq:
10926 if (!Subtarget.isISA3_1())
10928 switch (IntrinsicID) {
10931 case Intrinsic::ppc_altivec_vcmpequq:
10934 case Intrinsic::ppc_altivec_vcmpgtsq:
10937 case Intrinsic::ppc_altivec_vcmpgtuq:
10944 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10945 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10946 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10947 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10948 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10949 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10950 if (Subtarget.hasVSX()) {
10951 switch (IntrinsicID) {
10952 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10955 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10958 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10961 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10964 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10967 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10977 case Intrinsic::ppc_altivec_vcmpbfp:
10980 case Intrinsic::ppc_altivec_vcmpeqfp:
10983 case Intrinsic::ppc_altivec_vcmpequb:
10986 case Intrinsic::ppc_altivec_vcmpequh:
10989 case Intrinsic::ppc_altivec_vcmpequw:
10992 case Intrinsic::ppc_altivec_vcmpequd:
10993 if (Subtarget.hasP8Altivec())
10998 case Intrinsic::ppc_altivec_vcmpneb:
10999 case Intrinsic::ppc_altivec_vcmpneh:
11000 case Intrinsic::ppc_altivec_vcmpnew:
11001 case Intrinsic::ppc_altivec_vcmpnezb:
11002 case Intrinsic::ppc_altivec_vcmpnezh:
11003 case Intrinsic::ppc_altivec_vcmpnezw:
11004 if (Subtarget.hasP9Altivec())
11005 switch (IntrinsicID) {
11008 case Intrinsic::ppc_altivec_vcmpneb:
11011 case Intrinsic::ppc_altivec_vcmpneh:
11014 case Intrinsic::ppc_altivec_vcmpnew:
11017 case Intrinsic::ppc_altivec_vcmpnezb:
11020 case Intrinsic::ppc_altivec_vcmpnezh:
11023 case Intrinsic::ppc_altivec_vcmpnezw:
11030 case Intrinsic::ppc_altivec_vcmpgefp:
11033 case Intrinsic::ppc_altivec_vcmpgtfp:
11036 case Intrinsic::ppc_altivec_vcmpgtsb:
11039 case Intrinsic::ppc_altivec_vcmpgtsh:
11042 case Intrinsic::ppc_altivec_vcmpgtsw:
11045 case Intrinsic::ppc_altivec_vcmpgtsd:
11046 if (Subtarget.hasP8Altivec())
11051 case Intrinsic::ppc_altivec_vcmpgtub:
11054 case Intrinsic::ppc_altivec_vcmpgtuh:
11057 case Intrinsic::ppc_altivec_vcmpgtuw:
11060 case Intrinsic::ppc_altivec_vcmpgtud:
11061 if (Subtarget.hasP8Altivec())
11066 case Intrinsic::ppc_altivec_vcmpequq_p:
11067 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11068 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11069 if (!Subtarget.isISA3_1())
11071 switch (IntrinsicID) {
11074 case Intrinsic::ppc_altivec_vcmpequq_p:
11077 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11080 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11094 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
11100 auto MapNodeWithSplatVector =
11101 [&](
unsigned Opcode,
11102 std::initializer_list<SDValue> ExtraOps = {}) ->
SDValue {
11107 Ops.append(ExtraOps.begin(), ExtraOps.end());
11108 return DAG.
getNode(Opcode, dl, MVT::v16i8,
Ops);
11111 switch (IntrinsicID) {
11112 case Intrinsic::thread_pointer:
11114 if (Subtarget.isPPC64())
11118 case Intrinsic::ppc_rldimi: {
11119 assert(Subtarget.isPPC64() &&
"rldimi is only available in 64-bit!");
11121 APInt
Mask =
Op.getConstantOperandAPInt(4);
11123 return Op.getOperand(2);
11124 if (
Mask.isAllOnes())
11126 uint64_t SH =
Op.getConstantOperandVal(3);
11127 unsigned MB = 0, ME = 0;
11131 if (ME < 63 - SH) {
11134 }
else if (ME > 63 - SH) {
11140 {Op.getOperand(2), Src,
11141 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
11142 DAG.getTargetConstant(MB, dl, MVT::i32)}),
11146 case Intrinsic::ppc_rlwimi: {
11147 APInt
Mask =
Op.getConstantOperandAPInt(4);
11149 return Op.getOperand(2);
11150 if (
Mask.isAllOnes())
11153 unsigned MB = 0, ME = 0;
11157 PPC::RLWIMI, dl, MVT::i32,
11158 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
11159 DAG.getTargetConstant(MB, dl, MVT::i32),
11160 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11164 case Intrinsic::ppc_bcdshift:
11165 return MapNodeWithSplatVector(PPCISD::BCDSHIFT, {
Op.getOperand(3)});
11166 case Intrinsic::ppc_bcdshiftround:
11167 return MapNodeWithSplatVector(PPCISD::BCDSHIFTROUND, {
Op.getOperand(3)});
11168 case Intrinsic::ppc_bcdtruncate:
11169 return MapNodeWithSplatVector(PPCISD::BCDTRUNC, {
Op.getOperand(3)});
11170 case Intrinsic::ppc_bcdunsignedtruncate:
11171 return MapNodeWithSplatVector(PPCISD::BCDUTRUNC);
11172 case Intrinsic::ppc_bcdunsignedshift:
11173 return MapNodeWithSplatVector(PPCISD::BCDUSHIFT);
11175 case Intrinsic::ppc_rlwnm: {
11176 if (
Op.getConstantOperandVal(3) == 0)
11178 unsigned MB = 0, ME = 0;
11183 {Op.getOperand(1), Op.getOperand(2),
11184 DAG.getTargetConstant(MB, dl, MVT::i32),
11185 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11189 case Intrinsic::ppc_mma_disassemble_acc: {
11190 if (Subtarget.isISAFuture()) {
11191 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11202 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11203 Subtarget.isLittleEndian() ? Value2 :
Value,
11204 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11208 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11209 Subtarget.isLittleEndian() ? Value2 :
Value,
11210 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11214 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11215 Subtarget.isLittleEndian() ?
Value : Value2,
11216 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11220 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11221 Subtarget.isLittleEndian() ?
Value : Value2,
11222 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11229 case Intrinsic::ppc_vsx_disassemble_pair: {
11232 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
11234 WideVec = DAG.
getNode(PPCISD::XXMFACC, dl, MVT::v512i1, WideVec);
11237 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
11239 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8, WideVec,
11240 DAG.
getConstant(Subtarget.isLittleEndian() ? NumVecs - 1 - VecNo
11248 case Intrinsic::ppc_build_dmr: {
11251 for (
int i = 1; i < 9; i += 2) {
11259 DAG.
getNode(PPCISD::PAIR_BUILD, dl, MVT::v256i1, {Hi, Lo}));
11266 case Intrinsic::ppc_mma_dmxxextfdmr512: {
11267 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr512 requires ISA Future");
11269 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11270 "Specify P of 0 or 1 for lower or upper 512 bytes");
11271 unsigned HiLo = Idx->getSExtValue();
11275 Opcode = PPC::DMXXEXTFDMR512;
11276 Subx = PPC::sub_wacc_lo;
11278 Opcode = PPC::DMXXEXTFDMR512_HI;
11279 Subx = PPC::sub_wacc_hi;
11282 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
11286 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11290 case Intrinsic::ppc_mma_dmxxextfdmr256: {
11291 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr256 requires ISA Future");
11293 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11294 "Specify a dmr row pair 0-3");
11295 unsigned IdxVal = Idx->getSExtValue();
11299 Subx = PPC::sub_dmrrowp0;
11302 Subx = PPC::sub_dmrrowp1;
11305 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11308 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11312 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v256i1,
11318 DAG.
getMachineNode(PPC::DMXXEXTFDMR256, dl, MVT::v256i1, {Subreg, P}),
11322 case Intrinsic::ppc_mma_dmxxinstdmr512: {
11323 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr512 requires ISA Future");
11325 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11326 "Specify P of 0 or 1 for lower or upper 512 bytes");
11327 unsigned HiLo = Idx->getSExtValue();
11331 Opcode = PPCISD::INST512;
11332 Subx = PPC::sub_wacc_lo;
11334 Opcode = PPCISD::INST512HI;
11335 Subx = PPC::sub_wacc_hi;
11341 Op.getOperand(1), Wacc, SubReg),
11345 case Intrinsic::ppc_mma_dmxxinstdmr256: {
11346 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr256 requires ISA Future");
11348 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11349 "Specify a dmr row pair 0-3");
11350 unsigned IdxVal = Idx->getSExtValue();
11354 Subx = PPC::sub_dmrrowp0;
11357 Subx = PPC::sub_dmrrowp1;
11360 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11363 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11369 DAG.
getNode(PPCISD::INST256, dl, MVT::v256i1,
Op.getOperand(2),
P);
11371 Op.getOperand(1), DMRRowp, SubReg),
11375 case Intrinsic::ppc_mma_xxmfacc:
11376 case Intrinsic::ppc_mma_xxmtacc: {
11378 if (!Subtarget.isISAFuture())
11389 case Intrinsic::ppc_unpack_longdouble: {
11391 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11392 "Argument of long double unpack must be 0 or 1!");
11395 Idx->getValueType(0)));
11398 case Intrinsic::ppc_compare_exp_lt:
11399 case Intrinsic::ppc_compare_exp_gt:
11400 case Intrinsic::ppc_compare_exp_eq:
11401 case Intrinsic::ppc_compare_exp_uo: {
11403 switch (IntrinsicID) {
11404 case Intrinsic::ppc_compare_exp_lt:
11407 case Intrinsic::ppc_compare_exp_gt:
11410 case Intrinsic::ppc_compare_exp_eq:
11413 case Intrinsic::ppc_compare_exp_uo:
11419 PPC::SELECT_CC_I4, dl, MVT::i32,
11420 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
11421 Op.getOperand(1), Op.getOperand(2)),
11423 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11424 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
11427 case Intrinsic::ppc_test_data_class: {
11428 EVT OpVT =
Op.getOperand(1).getValueType();
11429 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
11430 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
11443 {Op.getOperand(2), Op.getOperand(1)}),
11445 if (Subtarget.isISA3_1()) {
11452 TestDataClass, SubRegIdx),
11455 return DAG.
getNode(PPCISD::SETBC, dl, MVT::i32, CRBit);
11461 {TestDataClass, DAG.getConstant(1, dl, MVT::i32),
11462 DAG.getConstant(0, dl, MVT::i32),
11463 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
11466 case Intrinsic::ppc_fnmsub: {
11467 EVT VT =
Op.getOperand(1).getValueType();
11468 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
11473 return DAG.
getNode(PPCISD::FNMSUB, dl, VT,
Op.getOperand(1),
11474 Op.getOperand(2),
Op.getOperand(3));
11476 case Intrinsic::ppc_convert_f128_to_ppcf128:
11477 case Intrinsic::ppc_convert_ppcf128_to_f128: {
11478 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
11479 ? RTLIB::CONVERT_PPCF128_F128
11480 : RTLIB::CONVERT_F128_PPCF128;
11482 std::pair<SDValue, SDValue>
Result =
11483 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
11487 case Intrinsic::ppc_maxfe:
11488 case Intrinsic::ppc_maxfl:
11489 case Intrinsic::ppc_maxfs:
11490 case Intrinsic::ppc_minfe:
11491 case Intrinsic::ppc_minfl:
11492 case Intrinsic::ppc_minfs: {
11493 EVT VT =
Op.getValueType();
11496 [VT](
const SDUse &Use) { return Use.getValueType() == VT; }) &&
11497 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
11500 if (IntrinsicID == Intrinsic::ppc_minfe ||
11501 IntrinsicID == Intrinsic::ppc_minfl ||
11502 IntrinsicID == Intrinsic::ppc_minfs)
11523 SDValue Tmp = DAG.
getNode(PPCISD::VCMP, dl,
Op.getOperand(2).getValueType(),
11524 Op.getOperand(1),
Op.getOperand(2),
11535 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11543 switch (
Op.getConstantOperandVal(1)) {
11548 Bitx = PPC::sub_eq;
11549 SetOp = PPCISD::SETBC;
11554 Bitx = PPC::sub_eq;
11555 SetOp = PPCISD::SETBCR;
11560 Bitx = PPC::sub_lt;
11561 SetOp = PPCISD::SETBC;
11566 Bitx = PPC::sub_lt;
11567 SetOp = PPCISD::SETBCR;
11572 if (Subtarget.isISA3_1()) {
11577 CR6Reg, SubRegIdx, GlueOp),
11579 return DAG.
getNode(SetOp, dl, MVT::i32, CRBit);
11607 switch (
Op.getConstantOperandVal(ArgStart)) {
11608 case Intrinsic::ppc_cfence: {
11609 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11610 SDValue Val =
Op.getOperand(ArgStart + 1);
11612 if (Ty == MVT::i128) {
11617 unsigned Opcode = Subtarget.isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11620 Opcode,
DL, MVT::Other,
11625 case Intrinsic::ppc_disassemble_dmr: {
11627 "llvm.ppc.disassemble.dmr must carry a chain argument.");
11628 return DAG.
getStore(
Op.getOperand(0),
DL,
Op.getOperand(ArgStart + 2),
11629 Op.getOperand(ArgStart + 1), MachinePointerInfo());
11640 if (!Subtarget.isPPC64())
11643 if (Subtarget.hasP9Vector()) {
11650 int VectorIndex = 0;
11651 if (Subtarget.isLittleEndian())
11661 auto CreateRotateInsert =
11662 [&](
unsigned Opcode, MVT VT,
SDValue Dest,
SDValue Src,
unsigned RotAmt,
11663 unsigned MaskBegin,
11664 std::optional<unsigned> MaskEnd = std::nullopt) ->
SDValue {
11668 if (MaskEnd.has_value())
11680 CreateRotateInsert(PPC::RLWIMI, MVT::i32, Rot, Val32, 24, 0, 7);
11682 return CreateRotateInsert(PPC::RLWIMI, MVT::i32, Swap, Val32, 24, 16, 23);
11695 return CreateRotateInsert(PPC::RLDIMI, MVT::i64, HiSwap, LoSwap, 32, 0);
11703 "Expecting an atomic compare-and-swap here.");
11706 EVT MemVT = AtomicNode->getMemoryVT();
11724 for (
int i = 0, e = AtomicNode->getNumOperands(); i < e; i++)
11725 Ops.push_back(AtomicNode->getOperand(i));
11727 MachineMemOperand *MMO = AtomicNode->getMemOperand();
11728 SDVTList Tys = DAG.
getVTList(MVT::i32, MVT::Other);
11730 (MemVT == MVT::i8) ? PPCISD::ATOMIC_CMP_SWAP_8 : PPCISD::ATOMIC_CMP_SWAP_16;
11737 EVT MemVT =
N->getMemoryVT();
11739 "Expect quadword atomic operations");
11741 unsigned Opc =
N->getOpcode();
11746 SDVTList Tys = DAG.
getVTList(MVT::i64, MVT::i64, MVT::Other);
11749 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11750 for (
int I = 1,
E =
N->getNumOperands();
I <
E; ++
I)
11751 Ops.push_back(
N->getOperand(
I));
11753 Ops, MemVT,
N->getMemOperand());
11760 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11767 SDVTList Tys = DAG.
getVTList(MVT::Other);
11770 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11776 Ops.push_back(ValLo);
11777 Ops.push_back(ValHi);
11778 Ops.push_back(
N->getOperand(2));
11780 N->getMemOperand());
11792 enum DataClassMask {
11794 DC_NEG_INF = 1 << 4,
11795 DC_POS_INF = 1 << 5,
11796 DC_NEG_ZERO = 1 << 2,
11797 DC_POS_ZERO = 1 << 3,
11798 DC_NEG_SUBNORM = 1,
11799 DC_POS_SUBNORM = 1 << 1,
11802 EVT VT =
Op.getValueType();
11804 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11805 : VT == MVT::f64 ? PPC::XSTSTDCDP
11816 return DAG.
getNOT(Dl, Rev, MVT::i1);
11823 TestOp, Dl, MVT::i32,
11825 DC_NEG_ZERO | DC_POS_ZERO |
11826 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11832 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11838 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11843 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11856 bool IsQuiet = Mask &
fcQNan;
11862 if (VT == MVT::f128) {
11866 QuietMask = 0x8000;
11867 }
else if (VT == MVT::f64) {
11868 if (Subtarget.isPPC64()) {
11879 QuietMask = 0x80000;
11880 }
else if (VT == MVT::f32) {
11882 QuietMask = 0x400000;
11898 unsigned NativeMask = 0;
11900 NativeMask |= DC_NAN;
11902 NativeMask |= DC_NEG_INF;
11904 NativeMask |= DC_POS_INF;
11906 NativeMask |= DC_NEG_ZERO;
11908 NativeMask |= DC_POS_ZERO;
11910 NativeMask |= DC_NEG_SUBNORM;
11912 NativeMask |= DC_POS_SUBNORM;
11915 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11917 TestOp, Dl, MVT::i32,
11926 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11928 uint64_t RHSC =
Op.getConstantOperandVal(1);
11931 if (
LHS.getValueType() == MVT::ppcf128) {
11955 bool Future = Subtarget.isISAFuture();
11958 "Mask predication not supported");
11961 unsigned IID = Future ? Intrinsic::ppc_vsx_lxvrl : Intrinsic::ppc_vsx_lxvl;
11962 unsigned EltBits =
Op->getValueType(0).getScalarType().getSizeInBits();
11966 SDVTList Tys = DAG.
getVTList(
Op->getValueType(0), MVT::Other);
11969 VPLD->getMemoryVT(), VPLD->getMemOperand());
11976 "Mask predication not supported");
11981 Op->getOperand(1).getValueType().getScalarType().getSizeInBits();
11982 bool Future = Subtarget.isISAFuture();
11983 unsigned IID = Future ? Intrinsic::ppc_vsx_stxvrl : Intrinsic::ppc_vsx_stxvl;
11986 VPST->getChain(), DAG.
getConstant(IID, dl, MVT::i32),
11989 SDVTList Tys = DAG.
getVTList(MVT::Other);
11992 VPST->getMemoryVT(), VPST->getMemOperand());
12003 "Unexpected partial reduction");
12026 unsigned EltSize =
Op.getValueType().getScalarSizeInBits();
12028 int64_t
IntVal =
Op.getConstantOperandVal(0);
12029 if (IntVal >= -16 && IntVal <= 15)
12035 if (Subtarget.hasLFIWAX() && Subtarget.hasVSX() &&
12040 MachineMemOperand *MMO =
12042 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
12045 PPCISD::LD_SPLAT, dl, DAG.
getVTList(MVT::v4i32, MVT::Other),
Ops,
12049 return Bits.getValue(0);
12065 !Subtarget.isLittleEndian() && ValVT.
isInteger() &&
12070 64 -
Op.getValueType().getScalarSizeInBits(), dl, ShiftAmountTy);
12077 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx,
12078 MachinePointerInfo());
12085 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx, MachinePointerInfo());
12091 "Should only be called for ISD::INSERT_VECTOR_ELT");
12095 EVT VT =
Op.getValueType();
12100 if (VT == MVT::v2f64 &&
C)
12103 if (Subtarget.hasP9Vector()) {
12112 if ((VT == MVT::v4f32) && (V2.
getValueType() == MVT::f32) &&
12118 BitcastLoad,
Op.getOperand(2));
12119 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
12123 if (Subtarget.isISA3_1()) {
12124 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.isPPC64())
12128 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
12129 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
12139 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
12142 unsigned InsertAtElement =
C->getZExtValue();
12143 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
12144 if (Subtarget.isLittleEndian()) {
12145 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
12147 return DAG.
getNode(PPCISD::VECINSERT, dl, VT, V1, Mtvsrz,
12159 EVT VT =
Op.getValueType();
12160 bool IsV1024i1 = VT == MVT::v1024i1;
12161 bool IsV2048i1 = VT == MVT::v2048i1;
12165 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12167 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12168 "Dense Math support required.");
12169 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12178 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12179 MachineMemOperand *NewMMO =
12187 DAG.
getVTList(MVT::v256i1, MVT::Other),
12188 LoadOps, MVT::v256i1, NewMMO);
12193 if (Subtarget.isLittleEndian()) {
12194 std::reverse(Loads.
begin(), Loads.
end());
12195 std::reverse(LoadChains.
begin(), LoadChains.
end());
12207 SDValue Dmr1Value = DMFInsert1024(MoreLoads, dl, DAG);
12213 const SDValue DmrPOps[] = {DmrPRC,
Value, Dmr0Sub, Dmr1Value, Dmr1Sub};
12216 DAG.
getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v2048i1, DmrPOps), 0);
12225 DAG.
getNode(PPCISD::INST512, dl, MVT::v512i1, Pairs[0], Pairs[1]);
12228 DAG.
getNode(PPCISD::INST512HI, dl, MVT::v512i1, Pairs[2], Pairs[3]);
12233 {RC, Lo, LoSub, Hi, HiSub}),
12243 EVT VT =
Op.getValueType();
12245 if (VT == MVT::v1024i1 || VT == MVT::v2048i1)
12246 return LowerDMFVectorLoad(
Op, DAG);
12248 if (VT != MVT::v256i1 && VT != MVT::v512i1)
12252 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
12253 "Type unsupported without MMA");
12254 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12255 "Type unsupported without paired vector support");
12259 if (VT == MVT::v256i1 && Subtarget.isISAFuture())
12268 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12270 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
12279 if (Subtarget.isLittleEndian()) {
12280 std::reverse(Loads.
begin(), Loads.
end());
12281 std::reverse(LoadChains.
begin(), LoadChains.
end());
12285 DAG.
getNode(VT == MVT::v512i1 ? PPCISD::ACC_BUILD : PPCISD::PAIR_BUILD,
12301 bool IsV1024i1 = VT == MVT::v1024i1;
12302 bool IsV2048i1 = VT == MVT::v2048i1;
12306 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12308 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12309 "Dense Math support required.");
12310 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12312 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12315 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12320 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12324 MachineSDNode *ExtNode =
12328 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes,
Hi);
12334 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12340 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12346 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12351 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12356 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12361 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12365 MachineSDNode *ExtNode =
12366 DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr0Lo);
12370 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr0Hi);
12373 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr1Lo);
12377 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr1Hi);
12382 if (Subtarget.isLittleEndian())
12383 std::reverse(Values.
begin(), Values.
end());
12385 SDVTList Tys = DAG.
getVTList(MVT::Other);
12387 StoreChain, DAG.
getConstant(Intrinsic::ppc_vsx_stxvp, dl, MVT::i32),
12391 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12392 MachineMemOperand *NewMMO =
12399 Ops[2] = Values[Idx];
12401 MVT::v256i1, NewMMO);
12417 EVT StoreVT =
Value.getValueType();
12419 if (StoreVT == MVT::v1024i1 || StoreVT == MVT::v2048i1)
12420 return LowerDMFVectorStore(
Op, DAG);
12422 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
12426 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
12427 "Type unsupported without MMA");
12428 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12429 "Type unsupported without paired vector support");
12433 if (StoreVT == MVT::v256i1 && Subtarget.isISAFuture() &&
12441 unsigned NumVecs = 2;
12442 if (StoreVT == MVT::v512i1) {
12443 if (Subtarget.isISAFuture()) {
12444 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12446 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
12449 Value2 =
SDValue(ExtNode, 1);
12454 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12455 unsigned VecNum = Subtarget.isLittleEndian() ? NumVecs - 1 - Idx : Idx;
12457 if (Subtarget.isISAFuture()) {
12458 VecNum = Subtarget.isLittleEndian() ? 1 - (Idx % 2) : (Idx % 2);
12459 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
12460 Idx > 1 ? Value2 :
Value,
12463 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
Value,
12467 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
12481 if (
Op.getValueType() == MVT::v4i32) {
12498 LHS,
RHS, DAG, dl, MVT::v4i32);
12501 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
12506 }
else if (
Op.getValueType() == MVT::v16i8) {
12508 bool isLittleEndian = Subtarget.isLittleEndian();
12512 LHS,
RHS, DAG, dl, MVT::v8i16);
12517 LHS,
RHS, DAG, dl, MVT::v8i16);
12525 for (
unsigned i = 0; i != 8; ++i) {
12526 if (isLittleEndian) {
12528 Ops[i*2+1] = 2*i+16;
12531 Ops[i*2+1] = 2*i+1+16;
12534 if (isLittleEndian)
12544 bool IsStrict =
Op->isStrictFPOpcode();
12545 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
12546 !Subtarget.hasP9Vector())
12556 "Should only be called for ISD::FP_EXTEND");
12560 if (
Op.getValueType() != MVT::v2f64 ||
12561 Op.getOperand(0).getValueType() != MVT::v2f32)
12573 "Node should have 2 operands with second one being a constant!");
12585 int DWord = Idx >> 1;
12588 if (Subtarget.isLittleEndian())
12591 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64,
12605 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12607 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12608 LD->getMemoryVT(),
LD->getMemOperand());
12613 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewOp,
12618 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12620 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12621 LD->getMemoryVT(),
LD->getMemOperand());
12622 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewLd,
12633 if (STI.useCRBits())
12650 PPCISD::ADDE,
DL, DAG.
getVTList(SumType, MVT::i32), Zero, Zero, Flag);
12651 if (STI.useCRBits())
12659 SDNode *
N =
Op.getNode();
12660 EVT VT =
N->getValueType(0);
12661 EVT CarryType =
N->getValueType(1);
12662 unsigned Opc =
N->getOpcode();
12664 Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12666 N->getOperand(0),
N->getOperand(1));
12678 SDNode *
N =
Op.getNode();
12679 unsigned Opc =
N->getOpcode();
12680 EVT VT =
N->getValueType(0);
12681 EVT CarryType =
N->getValueType(1);
12682 SDValue CarryOp =
N->getOperand(2);
12684 Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12690 Op.getOperand(0),
Op.getOperand(1), CarryOp);
12704 EVT VT =
Op.getNode()->getValueType(0);
12730 EVT VT =
Op.getNode()->getValueType(0);
12759 EVT OpVT =
A.getValueType();
12760 EVT ResVT =
Op.getValueType();
12766 SDVTList VTs = DAG.
getVTList(OpVT, MVT::i32);
12784 switch (
Op.getOpcode()) {
12804 return LowerSSUBO(
Op, DAG);
12806 return LowerSADDO(
Op, DAG);
12818 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
12839 return LowerSET_ROUNDING(
Op, DAG);
12846 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
12847 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
12859 return LowerFP_ROUND(
Op, DAG);
12873 return LowerINTRINSIC_VOID(
Op, DAG);
12875 return LowerBSWAP(
Op, DAG);
12877 return LowerATOMIC_CMP_SWAP(
Op, DAG);
12879 return LowerATOMIC_LOAD_STORE(
Op, DAG);
12881 return LowerIS_FPCLASS(
Op, DAG);
12884 return LowerADDSUBO(
Op, DAG);
12887 return LowerADDSUBO_CARRY(
Op, DAG);
12889 return LowerUCMP(
Op, DAG);
12895 if (
Op->getFlags().hasNoFPExcept())
12899 return LowerVP_LOAD(
Op, DAG);
12900 case ISD::VP_STORE:
12901 return LowerVP_STORE(
Op, DAG);
12903 return LowerPartialReduce(
Op, DAG);
12911 switch (
N->getOpcode()) {
12913 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
12930 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
12933 assert(
N->getValueType(0) == MVT::i1 &&
12934 "Unexpected result type for CTR decrement intrinsic");
12936 N->getValueType(0));
12946 switch (
N->getConstantOperandVal(0)) {
12947 case Intrinsic::ppc_pack_longdouble:
12949 N->getOperand(2),
N->getOperand(1)));
12951 case Intrinsic::ppc_maxfe:
12952 case Intrinsic::ppc_minfe:
12953 case Intrinsic::ppc_fnmsub:
12954 case Intrinsic::ppc_convert_f128_to_ppcf128:
12961 if (!Subtarget.isSVR4ABI() || Subtarget.isPPC64())
12964 EVT VT =
N->getValueType(0);
12966 if (VT == MVT::i64) {
12979 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
12983 Results.push_back(LoweredValue);
12984 if (
N->isStrictFPOpcode())
12989 if (!
N->getValueType(0).isVector())
13022 return Builder.CreateIntrinsic(Id, {});
13028 unsigned SZ = ValueTy->getPrimitiveSizeInBits();
13030 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
13031 "Only 8/16/32/64-bit atomic loads supported");
13037 IntID = Intrinsic::ppc_lbarx;
13038 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13041 IntID = Intrinsic::ppc_lharx;
13042 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13045 IntID = Intrinsic::ppc_lwarx;
13048 IntID = Intrinsic::ppc_ldarx;
13052 Builder.CreateIntrinsic(IntID, Addr,
nullptr,
"larx");
13054 return Builder.CreateTruncOrBitCast(
Call, ValueTy);
13065 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
13066 "Only 8/16/32/64-bit atomic loads supported");
13072 IntID = Intrinsic::ppc_stbcx;
13073 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13076 IntID = Intrinsic::ppc_sthcx;
13077 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13080 IntID = Intrinsic::ppc_stwcx;
13083 IntID = Intrinsic::ppc_stdcx;
13087 if (SZ == 8 || SZ == 16)
13088 Val = Builder.CreateZExt(Val, Builder.getInt32Ty());
13090 Value *
Call = Builder.CreateIntrinsic(IntID, {Addr, Val},
13092 return Builder.CreateXor(
Call, Builder.getInt32(1));
13115 return Builder.CreateIntrinsic(Intrinsic::ppc_cfence, {Inst->
getType()},
13125 unsigned BinOpcode,
13126 unsigned CmpOpcode,
13127 unsigned CmpPred)
const {
13132 unsigned AtomicSize =
MI.getOperand(3).getImm();
13134 auto LoadMnemonic = PPC::LDARX;
13135 auto StoreMnemonic = PPC::STDCX;
13136 switch (AtomicSize) {
13140 LoadMnemonic = PPC::LBARX;
13141 StoreMnemonic = PPC::STBCX;
13142 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13145 LoadMnemonic = PPC::LHARX;
13146 StoreMnemonic = PPC::STHCX;
13147 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13150 LoadMnemonic = PPC::LWARX;
13151 StoreMnemonic = PPC::STWCX;
13154 LoadMnemonic = PPC::LDARX;
13155 StoreMnemonic = PPC::STDCX;
13163 if (CmpOpcode == PPC::CMPW && (AtomicSize == 1 || AtomicSize == 2))
13174 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13176 F->insert(It, loopMBB);
13178 F->insert(It, loop2MBB);
13179 F->insert(It, exitMBB);
13185 Register TmpReg = (!BinOpcode) ? incr :
13186 RegInfo.createVirtualRegister( AtomicSize == 8 ? &PPC::G8RCRegClass
13187 : &PPC::GPRCRegClass);
13212 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
13217 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13219 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
13220 Register ExtReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13221 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
13251 switch(
MI.getOpcode()) {
13255 return TII->isSignExtended(
MI.getOperand(1).getReg(),
13256 &
MI.getMF()->getRegInfo());
13280 case PPC::EXTSB8_32_64:
13281 case PPC::EXTSB8_rec:
13282 case PPC::EXTSB_rec:
13285 case PPC::EXTSH8_32_64:
13286 case PPC::EXTSH8_rec:
13287 case PPC::EXTSH_rec:
13289 case PPC::EXTSWSLI:
13290 case PPC::EXTSWSLI_32_64:
13291 case PPC::EXTSWSLI_32_64_rec:
13292 case PPC::EXTSWSLI_rec:
13293 case PPC::EXTSW_32:
13294 case PPC::EXTSW_32_64:
13295 case PPC::EXTSW_32_64_rec:
13296 case PPC::EXTSW_rec:
13299 case PPC::SRAWI_rec:
13300 case PPC::SRAW_rec:
13310 unsigned OpIdx,
bool IsByte,
13315 bool IsSignExtended =
13318 if (!IsSignExtended) {
13319 Register ValueReg =
RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13321 TII->get(IsByte ? PPC::EXTSB : PPC::EXTSH), ValueReg)
13323 MI.getOperand(
OpIdx).setReg(ValueReg);
13329 unsigned CmpOpcode,
unsigned CmpPred)
const {
13333 assert(!Subtarget.hasPartwordAtomics() &&
13334 "Assumes that part-word atomics are not available");
13342 const bool is8bit =
MI.getOperand(3).getImm() == 1;
13343 if (CmpOpcode == PPC::CMPW)
13351 bool is64bit = Subtarget.isPPC64();
13352 bool isLittleEndian = Subtarget.isLittleEndian();
13353 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13364 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13366 F->insert(It, loopMBB);
13368 F->insert(It, loop2MBB);
13369 F->insert(It, exitMBB);
13375 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13378 Register PtrReg = RegInfo.createVirtualRegister(RC);
13379 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
13381 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
13382 Register Incr2Reg = RegInfo.createVirtualRegister(GPRC);
13383 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
13384 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
13385 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
13386 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
13387 Register Tmp3Reg = RegInfo.createVirtualRegister(GPRC);
13388 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
13389 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
13390 Register SrwDestReg = RegInfo.createVirtualRegister(GPRC);
13393 (!BinOpcode) ? Incr2Reg : RegInfo.createVirtualRegister(GPRC);
13420 if (ptrA != ZeroReg) {
13421 Ptr1Reg = RegInfo.createVirtualRegister(RC);
13422 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13430 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13431 .
addReg(Ptr1Reg, {}, is64bit ? PPC::sub_32 : 0)
13434 .
addImm(is8bit ? 28 : 27);
13435 if (!isLittleEndian)
13436 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13438 .
addImm(is8bit ? 24 : 16);
13440 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13445 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13455 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13459 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13464 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13468 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
13471 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13478 Register SReg = RegInfo.createVirtualRegister(GPRC);
13479 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13483 unsigned ValueReg = SReg;
13484 unsigned CmpReg = Incr2Reg;
13485 if (CmpOpcode == PPC::CMPW) {
13486 ValueReg = RegInfo.createVirtualRegister(GPRC);
13487 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
13490 Register ValueSReg = RegInfo.createVirtualRegister(GPRC);
13491 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
13493 ValueReg = ValueSReg;
13525 .
addImm(is8bit ? 24 : 16)
13546 Register DstReg =
MI.getOperand(0).getReg();
13548 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
13553 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13554 "Invalid Pointer Size!");
13603 Register BufReg =
MI.getOperand(1).getReg();
13605 if (Subtarget.is64BitELFABI()) {
13618 BaseReg = Subtarget.isPPC64() ? PPC::X1 : PPC::R1;
13620 BaseReg = Subtarget.isPPC64() ? PPC::BP8 : PPC::BP;
13623 TII->get(Subtarget.isPPC64() ? PPC::STD : PPC::STW))
13646 TII->get(Subtarget.isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
13649 if (Subtarget.isPPC64()) {
13667 TII->get(PPC::PHI), DstReg)
13671 MI.eraseFromParent();
13685 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13686 "Invalid Pointer Size!");
13689 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13692 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
13693 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
13707 Register BufReg =
MI.getOperand(0).getReg();
13712 if (PVT == MVT::i64) {
13724 if (PVT == MVT::i64) {
13736 if (PVT == MVT::i64) {
13748 if (PVT == MVT::i64) {
13760 if (PVT == MVT::i64 && Subtarget.isSVR4ABI()) {
13770 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
13773 MI.eraseFromParent();
13789 "Unexpected stack alignment");
13793 unsigned StackProbeSize =
13796 StackProbeSize &= ~(StackAlign - 1);
13797 return StackProbeSize ? StackProbeSize : StackAlign;
13809 const bool isPPC64 = Subtarget.isPPC64();
13841 MF->
insert(MBBIter, TestMBB);
13842 MF->
insert(MBBIter, BlockMBB);
13843 MF->
insert(MBBIter, TailMBB);
13848 Register DstReg =
MI.getOperand(0).getReg();
13849 Register NegSizeReg =
MI.getOperand(1).getReg();
13861 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
13867 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
13868 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
13870 .
addDef(ActualNegSizeReg)
13872 .
add(
MI.getOperand(2))
13873 .
add(
MI.getOperand(3));
13879 .
addReg(ActualNegSizeReg);
13882 int64_t NegProbeSize = -(int64_t)ProbeSize;
13888 .
addImm(NegProbeSize >> 16);
13892 .
addImm(NegProbeSize & 0xFFFF);
13901 .
addReg(ActualNegSizeReg)
13910 .
addReg(ActualNegSizeReg);
13920 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
13947 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
13948 MaxCallFrameSizeReg)
13949 .
add(
MI.getOperand(2))
13950 .
add(
MI.getOperand(3));
13951 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
13953 .
addReg(MaxCallFrameSizeReg);
13959 MBB->addSuccessor(TestMBB);
13962 MI.eraseFromParent();
13964 ++NumDynamicAllocaProbed;
13972static bool IsSelect(
unsigned Opcode,
bool CheckOnlyCC =
false) {
13975 case PPC::SELECT_CC_I4:
13976 case PPC::SELECT_CC_I8:
13977 case PPC::SELECT_CC_F4:
13978 case PPC::SELECT_CC_F8:
13979 case PPC::SELECT_CC_F16:
13980 case PPC::SELECT_CC_VRRC:
13981 case PPC::SELECT_CC_VSFRC:
13982 case PPC::SELECT_CC_VSSRC:
13983 case PPC::SELECT_CC_VSRC:
13984 case PPC::SELECT_CC_SPE4:
13985 case PPC::SELECT_CC_SPE:
13988 case PPC::SELECT_I4:
13989 case PPC::SELECT_I8:
13990 case PPC::SELECT_F4:
13991 case PPC::SELECT_F8:
13992 case PPC::SELECT_F16:
13993 case PPC::SELECT_SPE:
13994 case PPC::SELECT_SPE4:
13995 case PPC::SELECT_VRRC:
13996 case PPC::SELECT_VSFRC:
13997 case PPC::SELECT_VSSRC:
13998 case PPC::SELECT_VSRC:
13999 return !CheckOnlyCC;
14015 assert(
IsSelect(
MI.getOpcode()) &&
"Instruction must be a SELECT variant");
14018 if (Subtarget.hasISEL() &&
14019 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
14020 MI.getOpcode() == PPC::SELECT_CC_I8 ||
14021 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
14023 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
14024 MI.getOpcode() == PPC::SELECT_CC_I8)
14025 Cond.push_back(
MI.getOperand(4));
14028 Cond.push_back(
MI.getOperand(1));
14031 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
14032 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
14033 MI.eraseFromParent();
14046 F->insert(It, copy0MBB);
14047 F->insert(It, sinkMBB);
14055 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
14071 .
addImm(
MI.getOperand(4).getImm())
14072 .
addReg(
MI.getOperand(1).getReg())
14076 .
addReg(
MI.getOperand(1).getReg())
14086 .
addReg(
MI.getOperand(3).getReg())
14088 .
addReg(
MI.getOperand(2).getReg())
14090 MI.eraseFromParent();
14105 loop1MBB =
F->CreateMachineBasicBlock(LLVM_BB);
14106 loop2MBB =
F->CreateMachineBasicBlock(LLVM_BB);
14107 exitMBB =
F->CreateMachineBasicBlock(LLVM_BB);
14108 F->insert(It, loop1MBB);
14109 F->insert(It, loop2MBB);
14110 F->insert(It, exitMBB);
14145 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
14147 unsigned LoadMnemonic = PPC::LDARX;
14148 unsigned StoreMnemonic = PPC::STDCX;
14149 switch (
MI.getOpcode()) {
14152 case PPC::ATOMIC_CMP_SWAP_I8:
14153 LoadMnemonic = PPC::LBARX;
14154 StoreMnemonic = PPC::STBCX;
14155 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14157 case PPC::ATOMIC_CMP_SWAP_I16:
14158 LoadMnemonic = PPC::LHARX;
14159 StoreMnemonic = PPC::STHCX;
14160 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14162 case PPC::ATOMIC_CMP_SWAP_I32:
14163 LoadMnemonic = PPC::LWARX;
14164 StoreMnemonic = PPC::STWCX;
14166 case PPC::ATOMIC_CMP_SWAP_I64:
14167 LoadMnemonic = PPC::LDARX;
14168 StoreMnemonic = PPC::STDCX;
14176 Register oldval =
MI.getOperand(3).getReg();
14177 Register newval =
MI.getOperand(4).getReg();
14191 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
14259 bool is64bit = Subtarget.isPPC64();
14261 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
14266 Register oldval =
MI.getOperand(3).getReg();
14267 Register newval =
MI.getOperand(4).getReg();
14275 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
14280 return RegInfo.createVirtualRegister(RC);
14284 Register Shift1Reg = createVReg(GPRC);
14285 Register ShiftReg = isLittleEndian ? Shift1Reg : createVReg(GPRC);
14286 Register NewVal2Reg = createVReg(GPRC);
14287 Register NewVal3Reg = createVReg(GPRC);
14288 Register OldVal2Reg = createVReg(GPRC);
14289 Register OldVal3Reg = createVReg(GPRC);
14290 Register MaskReg = createVReg(GPRC);
14291 Register Mask2Reg = createVReg(GPRC);
14292 Register Mask3Reg = createVReg(GPRC);
14293 Register Tmp2Reg = createVReg(GPRC);
14294 Register Tmp4Reg = createVReg(GPRC);
14295 Register TmpDestReg = createVReg(GPRC);
14296 Register TmpReg = createVReg(GPRC);
14297 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
14298 Register CrReg = createVReg(&PPC::CRRCRegClass);
14302 if (ptrA != ZeroReg) {
14303 Ptr1Reg = createVReg(RC);
14304 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
14311 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
14312 .
addReg(Ptr1Reg, {}, is64bit ? PPC::sub_32 : 0)
14315 .
addImm(is8bit ? 28 : 27);
14316 if (!isLittleEndian)
14317 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
14319 .
addImm(is8bit ? 24 : 16);
14321 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
14326 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
14333 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
14336 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
14343 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
14347 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
14350 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
14353 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
14363 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
14384 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
14429 switch (
MI.getOpcode()) {
14430 case TargetOpcode::STACKMAP:
14432 case TargetOpcode::PATCHPOINT:
14438 if (Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls())
14442 case PPC::EH_SjLj_SetJmp32:
14443 case PPC::EH_SjLj_SetJmp64:
14446 case PPC::EH_SjLj_LongJmp32:
14447 case PPC::EH_SjLj_LongJmp64:
14450 case PPC::ReadTB: {
14466 F->insert(It, readMBB);
14467 F->insert(It, sinkMBB);
14478 Register ReadAgainReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
14486 Register CmpReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14488 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
14500 case PPC::ATOMIC_LOAD_ADD_NOWP:
14503 case PPC::ATOMIC_LOAD_ADD:
14506 case PPC::ATOMIC_LOAD_ADD_I64:
14509 case PPC::ATOMIC_LOAD_AND_NOWP:
14512 case PPC::ATOMIC_LOAD_AND:
14515 case PPC::ATOMIC_LOAD_AND_I64:
14518 case PPC::ATOMIC_LOAD_OR_NOWP:
14521 case PPC::ATOMIC_LOAD_OR:
14524 case PPC::ATOMIC_LOAD_OR_I64:
14527 case PPC::ATOMIC_LOAD_XOR_NOWP:
14530 case PPC::ATOMIC_LOAD_XOR:
14533 case PPC::ATOMIC_LOAD_XOR_I64:
14536 case PPC::ATOMIC_LOAD_NAND_NOWP:
14539 case PPC::ATOMIC_LOAD_NAND:
14542 case PPC::ATOMIC_LOAD_NAND_I64:
14545 case PPC::ATOMIC_LOAD_SUB_NOWP:
14548 case PPC::ATOMIC_LOAD_SUB:
14551 case PPC::ATOMIC_LOAD_SUB_I64:
14554 case PPC::ATOMIC_LOAD_MIN_NOWP:
14557 case PPC::ATOMIC_LOAD_MIN:
14560 case PPC::ATOMIC_LOAD_MIN_I64:
14563 case PPC::ATOMIC_LOAD_MAX_NOWP:
14566 case PPC::ATOMIC_LOAD_MAX:
14569 case PPC::ATOMIC_LOAD_MAX_I64:
14572 case PPC::ATOMIC_LOAD_UMIN_NOWP:
14575 case PPC::ATOMIC_LOAD_UMIN:
14578 case PPC::ATOMIC_LOAD_UMIN_I64:
14581 case PPC::ATOMIC_LOAD_UMAX_NOWP:
14584 case PPC::ATOMIC_LOAD_UMAX:
14587 case PPC::ATOMIC_LOAD_UMAX_I64:
14590 case PPC::ATOMIC_SWAP_NOWP:
14593 case PPC::ATOMIC_SWAP:
14594 case PPC::ATOMIC_SWAP_I64:
14597 case PPC::ATOMIC_CMP_SWAP_I32:
14598 case PPC::ATOMIC_CMP_SWAP_I64:
14599 case PPC::ATOMIC_CMP_SWAP_I8:
14600 case PPC::ATOMIC_CMP_SWAP_I16: {
14602 bool useHardware =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
14603 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
14604 (Subtarget.hasPartwordAtomics() &&
14605 (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
14606 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16));
14614 case PPC::FADDrtz: {
14624 Register MFFSReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14639 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
14649 case PPC::ANDI_rec_1_EQ_BIT:
14650 case PPC::ANDI_rec_1_GT_BIT:
14651 case PPC::ANDI_rec_1_EQ_BIT8:
14652 case PPC::ANDI_rec_1_GT_BIT8: {
14653 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14654 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
14657 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14658 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
14661 Register Dest = RegInfo.createVirtualRegister(
14662 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
14666 .
addReg(
MI.getOperand(1).getReg())
14669 MI.getOperand(0).getReg())
14670 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
14673 case PPC::TCHECK_RET: {
14676 Register CRReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14679 MI.getOperand(0).getReg())
14683 case PPC::TBEGIN_RET: {
14685 unsigned Imm =
MI.getOperand(1).getImm();
14688 MI.getOperand(0).getReg())
14692 case PPC::SETRNDi: {
14694 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14698 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14700 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14711 unsigned Mode =
MI.getOperand(1).getImm();
14712 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
14716 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
14721 case PPC::SETRND: {
14729 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
14730 if (Subtarget.hasDirectMove()) {
14731 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
14735 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
14738 if (RC == &PPC::F8RCRegClass) {
14740 assert((RegInfo.getRegClass(DestReg) == &PPC::G8RCRegClass) &&
14741 "Unsupported RegClass.");
14743 StoreOp = PPC::STFD;
14747 assert((RegInfo.getRegClass(SrcReg) == &PPC::G8RCRegClass) &&
14748 (RegInfo.getRegClass(DestReg) == &PPC::F8RCRegClass) &&
14749 "Unsupported RegClass.");
14782 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14785 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14797 Register OldFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14799 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
14801 Register ImDefReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14802 Register ExtSrcReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14807 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
14808 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
14813 Register NewFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14814 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
14820 Register NewFPSCRReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14821 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
14832 case PPC::SETFLM: {
14836 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14838 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14840 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14843 Register NewFPSCRReg =
MI.getOperand(1).getReg();
14851 case PPC::PROBED_ALLOCA_32:
14852 case PPC::PROBED_ALLOCA_64:
14855 case PPC::SPLIT_QUADWORD: {
14862 .
addUse(Src, {}, PPC::sub_gp8_x1);
14865 .
addUse(Src, {}, PPC::sub_gp8_x0);
14868 case PPC::LQX_PSEUDO:
14869 case PPC::STQX_PSEUDO: {
14875 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
14881 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
14882 :
TII->get(PPC::STQ))
14892 MI.eraseFromParent();
14905 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
14908 return RefinementSteps;
14915 EVT VT =
Op.getValueType();
14918 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
14942PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
14945 EVT VT =
Op.getValueType();
14946 if (VT != MVT::f64 &&
14947 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
14950 return DAG.
getNode(PPCISD::FSQRT, SDLoc(
Op), VT,
Op);
14954 int Enabled,
int &RefinementSteps,
14955 bool &UseOneConstNR,
14956 bool Reciprocal)
const {
14958 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
14959 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
14960 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14961 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14967 UseOneConstNR = !Subtarget.needsTwoConstNR();
14968 return DAG.
getNode(PPCISD::FRSQRTE, SDLoc(Operand), VT, Operand);
14975 int &RefinementSteps)
const {
14977 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
14978 (VT == MVT::f64 && Subtarget.hasFRE()) ||
14979 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14980 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14983 return DAG.
getNode(PPCISD::FRE, SDLoc(Operand), VT, Operand);
14999 switch (Subtarget.getCPUDirective()) {
15026 unsigned Bytes,
int Dist,
15040 if (FS != BFS || FS != (
int)Bytes)
return false;
15045 int64_t Offset1 = 0, Offset2 = 0;
15048 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
15058 if (isGA1 && isGA2 && GV1 == GV2)
15059 return Offset1 == (Offset2 + Dist*Bytes);
15066 unsigned Bytes,
int Dist,
15069 EVT VT = LS->getMemoryVT();
15076 switch (
N->getConstantOperandVal(1)) {
15077 default:
return false;
15078 case Intrinsic::ppc_altivec_lvx:
15079 case Intrinsic::ppc_altivec_lvxl:
15080 case Intrinsic::ppc_vsx_lxvw4x:
15081 case Intrinsic::ppc_vsx_lxvw4x_be:
15084 case Intrinsic::ppc_vsx_lxvd2x:
15085 case Intrinsic::ppc_vsx_lxvd2x_be:
15088 case Intrinsic::ppc_altivec_lvebx:
15091 case Intrinsic::ppc_altivec_lvehx:
15094 case Intrinsic::ppc_altivec_lvewx:
15104 switch (
N->getConstantOperandVal(1)) {
15105 default:
return false;
15106 case Intrinsic::ppc_altivec_stvx:
15107 case Intrinsic::ppc_altivec_stvxl:
15108 case Intrinsic::ppc_vsx_stxvw4x:
15111 case Intrinsic::ppc_vsx_stxvd2x:
15114 case Intrinsic::ppc_vsx_stxvw4x_be:
15117 case Intrinsic::ppc_vsx_stxvd2x_be:
15120 case Intrinsic::ppc_altivec_stvebx:
15123 case Intrinsic::ppc_altivec_stvehx:
15126 case Intrinsic::ppc_altivec_stvewx:
15143 SDValue Chain = LD->getChain();
15144 EVT VT = LD->getMemoryVT();
15153 while (!Queue.empty()) {
15154 SDNode *ChainNext = Queue.pop_back_val();
15155 if (!Visited.
insert(ChainNext).second)
15162 if (!Visited.
count(ChainLD->getChain().getNode()))
15163 Queue.push_back(ChainLD->getChain().getNode());
15165 for (
const SDUse &O : ChainNext->
ops())
15166 if (!Visited.
count(O.getNode()))
15167 Queue.push_back(O.getNode());
15169 LoadRoots.
insert(ChainNext);
15180 for (
SDNode *
I : LoadRoots) {
15181 Queue.push_back(
I);
15183 while (!Queue.empty()) {
15184 SDNode *LoadRoot = Queue.pop_back_val();
15185 if (!Visited.
insert(LoadRoot).second)
15197 Queue.push_back(U);
15230 auto Final = Shifted;
15241 DAGCombinerInfo &DCI)
const {
15244 SelectionDAG &DAG = DCI.DAG;
15249 if (!DCI.isAfterLegalizeDAG())
15254 for (
const SDNode *U :
N->users())
15259 auto OpSize =
N->getOperand(0).getValueSizeInBits();
15263 if (OpSize <
Size) {
15281 DAGCombinerInfo &DCI)
const {
15282 SelectionDAG &DAG = DCI.DAG;
15285 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
15296 N->getValueType(0) != MVT::i1)
15299 if (
N->getOperand(0).getValueType() != MVT::i32 &&
15300 N->getOperand(0).getValueType() != MVT::i64)
15310 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
15321 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
15344 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15345 N->getOperand(0).getOpcode() !=
ISD::OR &&
15346 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15356 N->getOperand(1).getOpcode() !=
ISD::AND &&
15357 N->getOperand(1).getOpcode() !=
ISD::OR &&
15358 N->getOperand(1).getOpcode() !=
ISD::XOR &&
15369 SmallPtrSet<SDNode *, 16> Visited;
15371 for (
unsigned i = 0; i < 2; ++i) {
15375 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
15387 while (!BinOps.
empty()) {
15395 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15429 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15433 for (
const SDNode *User : Inputs[i].
getNode()->
users()) {
15434 if (User !=
N && !Visited.
count(User))
15443 if (
User->getOperand(0) == Inputs[i])
15446 if (
User->getOperand(0) == Inputs[i] ||
15447 User->getOperand(1) == Inputs[i])
15453 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15454 for (
const SDNode *User : PromOps[i].
getNode()->
users()) {
15455 if (User !=
N && !Visited.
count(User))
15464 if (
User->getOperand(0) == PromOps[i])
15467 if (
User->getOperand(0) == PromOps[i] ||
15468 User->getOperand(1) == PromOps[i])
15475 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15484 std::list<HandleSDNode> PromOpHandles;
15485 for (
auto &PromOp : PromOps)
15486 PromOpHandles.emplace_back(PromOp);
15493 while (!PromOpHandles.empty()) {
15494 SDValue PromOp = PromOpHandles.back().getValue();
15495 PromOpHandles.pop_back();
15504 PromOpHandles.emplace_front(PromOp);
15518 default:
C = 0;
break;
15531 PromOpHandles.emplace_front(PromOp);
15538 for (
unsigned i = 0; i < 2; ++i)
15548 return N->getOperand(0);
15556 DAGCombinerInfo &DCI)
const {
15557 SelectionDAG &DAG = DCI.DAG;
15574 if (
N->getValueType(0) != MVT::i32 &&
15575 N->getValueType(0) != MVT::i64)
15578 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
15579 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.isPPC64())))
15582 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15583 N->getOperand(0).getOpcode() !=
ISD::OR &&
15584 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15591 SmallPtrSet<SDNode *, 16> Visited;
15595 while (!BinOps.
empty()) {
15603 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15629 DenseMap<SDNode *, EVT> SelectTruncOp[2];
15634 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15639 if (User !=
N && !Visited.
count(User))
15645 if (
User->getOperand(0) == Inputs[i])
15646 SelectTruncOp[0].
insert(std::make_pair(User,
15647 User->getOperand(0).getValueType()));
15649 if (
User->getOperand(0) == Inputs[i])
15650 SelectTruncOp[0].
insert(std::make_pair(User,
15651 User->getOperand(0).getValueType()));
15652 if (
User->getOperand(1) == Inputs[i])
15653 SelectTruncOp[1].
insert(std::make_pair(User,
15654 User->getOperand(1).getValueType()));
15659 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15661 if (User !=
N && !Visited.
count(User))
15667 if (
User->getOperand(0) == PromOps[i])
15668 SelectTruncOp[0].
insert(std::make_pair(User,
15669 User->getOperand(0).getValueType()));
15671 if (
User->getOperand(0) == PromOps[i])
15672 SelectTruncOp[0].
insert(std::make_pair(User,
15673 User->getOperand(0).getValueType()));
15674 if (
User->getOperand(1) == PromOps[i])
15675 SelectTruncOp[1].
insert(std::make_pair(User,
15676 User->getOperand(1).getValueType()));
15681 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
15682 bool ReallyNeedsExt =
false;
15686 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15691 Inputs[i].getOperand(0).getValueSizeInBits();
15692 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
15697 OpBits-PromBits))) ||
15700 (OpBits-(PromBits-1)))) {
15701 ReallyNeedsExt =
true;
15709 std::list<HandleSDNode> PromOpHandles;
15710 for (
auto &PromOp : PromOps)
15711 PromOpHandles.emplace_back(PromOp);
15715 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15722 SDValue InSrc = Inputs[i].getOperand(0);
15740 while (!PromOpHandles.empty()) {
15742 PromOpHandles.pop_back();
15746 default:
C = 0;
break;
15759 PromOpHandles.emplace_front(PromOp);
15769 (SelectTruncOp[1].count(PromOp.
getNode()) &&
15771 PromOpHandles.emplace_front(PromOp);
15779 for (
unsigned i = 0; i < 2; ++i) {
15797 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
15798 if (SI0 != SelectTruncOp[0].
end())
15800 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
15801 if (SI1 != SelectTruncOp[1].
end())
15810 if (!ReallyNeedsExt)
15811 return N->getOperand(0);
15818 N->getValueSizeInBits(0), PromBits),
15819 dl,
N->getValueType(0)));
15822 "Invalid extension type");
15825 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
15835 auto isValidForConvert = [IsPPC64](
SDValue &Operand) {
15844 const APInt &Val =
C->getAPIntValue();
15850 if (IsPPC64 && Val.
ult(1ULL << 16))
15864 if (LoadNode->isVolatile())
15885 return (isValidForConvert(
LHS) && isValidForConvert(
RHS));
15895 "CC mus be ISD::SETNE or ISD::SETEQ");
15897 auto getV16i8Load = [&](
const SDValue &Operand) {
15915 LoadNode->getBasePtr(), NewMMO);
15956 SDValue LHSVec = getV16i8Load(
N->getOperand(0));
15957 SDValue RHSVec = getV16i8Load(
N->getOperand(1));
15960 DAG.
getConstant(Intrinsic::ppc_altivec_vcmpequb_p,
DL, MVT::i32);
15963 IntrID, CRSel, LHSVec, RHSVec);
15966 return DAG.
getSetCC(
DL,
N->getValueType(0), PredResult,
15984 auto IsAndWithOne = [](
SDValue &V) {
15995 auto IsCompareWithZero = [](
SDValue &V) {
16002 return (IsAndWithOne(
LHS) && IsCompareWithZero(
RHS)) ||
16003 (IsAndWithOne(
RHS) && IsCompareWithZero(
LHS));
16020 auto MakeXor1 = [&](
SDValue V) {
16021 EVT VT = V.getValueType();
16028 return MakeXor1(
LHS);
16031 return MakeXor1(
RHS);
16048 DAGCombinerInfo &DCI)
const {
16049 if (Subtarget.isISA3_1())
16052 EVT VT =
N->getValueType(0);
16053 if (VT != MVT::i32 && VT != MVT::i64)
16069 SelectionDAG &DAG = DCI.DAG;
16071 EVT XVT =
X.getValueType();
16073 if ((XVT == MVT::i64 || VT == MVT::i64) && !Subtarget.isPPC64())
16079 if (XVT != MVT::i64 && Subtarget.isPPC64())
16083 EVT OpVT = Subtarget.isPPC64() ? MVT::i64 : MVT::i32;
16091 Addc, Addc, Carry);
16094 if (OpVT == MVT::i64 && VT == MVT::i32)
16101 DAGCombinerInfo &DCI)
const {
16103 "Should be called with a SETCC node");
16125 SelectionDAG &DAG = DCI.DAG;
16126 EVT VT =
N->getValueType(0);
16127 EVT OpVT =
LHS.getValueType();
16145 if (Subtarget.hasAltivec() &&
16150 return DAGCombineTruncBoolExt(
N, DCI);
16157 Op.getValueType() == MVT::f64;
16169combineElementTruncationToVectorTruncation(
SDNode *
N,
16170 DAGCombinerInfo &DCI)
const {
16172 "Should be called with a BUILD_VECTOR node");
16174 SelectionDAG &DAG = DCI.DAG;
16177 SDValue FirstInput =
N->getOperand(0);
16179 "The input operand must be an fp-to-int conversion.");
16184 if (FirstConversion == PPCISD::FCTIDZ ||
16185 FirstConversion == PPCISD::FCTIDUZ ||
16186 FirstConversion == PPCISD::FCTIWZ ||
16187 FirstConversion == PPCISD::FCTIWUZ) {
16188 bool IsSplat =
true;
16189 bool Is32Bit = FirstConversion == PPCISD::FCTIWZ ||
16190 FirstConversion == PPCISD::FCTIWUZ;
16193 EVT TargetVT =
N->getValueType(0);
16194 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
16195 SDValue NextOp =
N->getOperand(i);
16196 if (NextOp.
getOpcode() != PPCISD::MFVSR)
16199 if (NextConversion != FirstConversion)
16207 if (
N->getOperand(i) != FirstInput)
16218 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
16219 SDValue In =
N->getOperand(i).getOperand(0);
16229 Ops.push_back(Trunc);
16232 Ops.push_back(
In.isUndef() ? DAG.
getUNDEF(SrcVT) :
In.getOperand(0));
16236 if (FirstConversion == PPCISD::FCTIDZ ||
16237 FirstConversion == PPCISD::FCTIWZ)
16242 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
16244 return DAG.
getNode(Opcode, dl, TargetVT, BV);
16262 static const APInt BasePattern =
APInt(128, 0x8000000000000000ULL) << 64;
16266 if (FullVal == BasePattern)
16267 return std::make_tuple(Uim,
uint8_t{0});
16270 if (FullVal ==
APInt(128, 1))
16271 return std::make_tuple(Uim,
uint8_t{127});
16273 return std::nullopt;
16293 "Expected a BuildVectorSDNode in combineBVLoadsSpecialValue");
16297 EVT VT =
Op.getValueType();
16298 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
16312 for (
const SDValue &Operand :
Op.getNode()->op_values()) {
16322 for (
unsigned Index = 0;
Index < NumElems; ++
Index) {
16326 uint64_t ElemValue =
C->getZExtValue();
16330 ElemValue &= ((1ULL << ElemBits) - 1);
16334 (IsLittleEndian) ? (Index * ElemBits) : (128 - (
Index + 1) * ElemBits);
16337 APInt ElemAPInt(128, ElemValue);
16338 ElemAPInt <<= BitPos;
16341 FullVal |= ElemAPInt;
16348 const auto &[Uim, ShiftAmount] = *UIMOpt;
16352 if (ShiftAmount == 0) {
16357 <<
"combineBVLoadsSpecialValue: Instruction Emitted ";
16358 LxvkqInstr.
dump());
16362 assert(ShiftAmount == 127 &&
"Unexpected lxvkq shift amount value");
16374 DAG.
getMachineNode(PPC::VSRQ, Dl, VT, ShiftAmountVec, ShiftAmountVec),
16377 <<
"\n combineBVLoadsSpecialValue: Instruction Emitted ";
16393 "Should be called with a BUILD_VECTOR node");
16398 if (!
N->getValueType(0).getVectorElementType().isByteSized())
16401 bool InputsAreConsecutiveLoads =
true;
16402 bool InputsAreReverseConsecutive =
true;
16403 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
16404 SDValue FirstInput =
N->getOperand(0);
16405 bool IsRoundOfExtLoad =
false;
16415 N->getNumOperands() == 1)
16418 if (!IsRoundOfExtLoad)
16423 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
16425 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
16428 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
16434 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
16445 InputsAreConsecutiveLoads =
false;
16447 InputsAreReverseConsecutive =
false;
16450 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
16455 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
16456 "The loads cannot be both consecutive and reverse consecutive.");
16460 if (InputsAreConsecutiveLoads) {
16461 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
16465 ReturnSDVal = WideLoad;
16466 }
else if (InputsAreReverseConsecutive) {
16468 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
16473 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
16481 for (
auto *LD : InputLoads)
16483 return ReturnSDVal;
16494 unsigned NumElems =
Input.getValueType().getVectorNumElements();
16500 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16502 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
16504 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
16505 CorrectElems = CorrectElems >> 8;
16506 Elems = Elems >> 8;
16513 EVT VT =
N->getValueType(0);
16517 Input.getValueType().getVectorElementType(),
16551 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
16577 Elems = Elems << 8;
16586 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16587 if (!isSExtOfVecExtract(
N->getOperand(i))) {
16594 int TgtElemArrayIdx;
16595 int InputSize =
Input.getValueType().getScalarSizeInBits();
16596 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
16597 if (InputSize + OutputSize == 40)
16598 TgtElemArrayIdx = 0;
16599 else if (InputSize + OutputSize == 72)
16600 TgtElemArrayIdx = 1;
16601 else if (InputSize + OutputSize == 48)
16602 TgtElemArrayIdx = 2;
16603 else if (InputSize + OutputSize == 80)
16604 TgtElemArrayIdx = 3;
16605 else if (InputSize + OutputSize == 96)
16606 TgtElemArrayIdx = 4;
16610 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
16612 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
16613 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
16614 if (Elems != CorrectElems) {
16630 if (
N->getValueType(0) != MVT::v1i128)
16633 SDValue Operand =
N->getOperand(0);
16640 EVT MemoryType = LD->getMemoryVT();
16644 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
16645 MemoryType == MVT::i32 || MemoryType == MVT::i64;
16648 if (!ValidLDType ||
16654 LD->getChain(), LD->getBasePtr(),
16658 DAG.
getVTList(MVT::v1i128, MVT::Other),
16659 LoadOps, MemoryType, LD->getMemOperand());
16663 DAGCombinerInfo &DCI)
const {
16665 "Should be called with a BUILD_VECTOR node");
16667 SelectionDAG &DAG = DCI.DAG;
16670 if (!Subtarget.hasVSX())
16677 if (FirstInput.
getOpcode() == PPCISD::MFVSR) {
16678 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
16693 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
16702 if (Subtarget.isISA3_1()) {
16708 if (
N->getValueType(0) != MVT::v2f64)
16719 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
16730 if (!Ext1Op || !Ext2Op)
16739 if (FirstElem == 0 && SecondElem == 1)
16740 SubvecIdx = Subtarget.isLittleEndian() ? 1 : 0;
16741 else if (FirstElem == 2 && SecondElem == 3)
16742 SubvecIdx = Subtarget.isLittleEndian() ? 0 : 1;
16748 PPCISD::SINT_VEC_TO_FP : PPCISD::UINT_VEC_TO_FP;
16749 return DAG.
getNode(NodeType, dl, MVT::v2f64,
16754 DAGCombinerInfo &DCI)
const {
16757 "Need an int -> FP conversion node here");
16762 SelectionDAG &DAG = DCI.DAG;
16768 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
16770 if (!
Op.getOperand(0).getValueType().isSimple())
16772 if (
Op.getOperand(0).getValueType().getSimpleVT() <= MVT(MVT::i1) ||
16773 Op.getOperand(0).getValueType().getSimpleVT() > MVT(MVT::i64))
16776 SDValue FirstOperand(
Op.getOperand(0));
16777 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
16778 (FirstOperand.getValueType() == MVT::i8 ||
16779 FirstOperand.getValueType() == MVT::i16);
16780 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
16782 bool DstDouble =
Op.getValueType() == MVT::f64;
16783 unsigned ConvOp =
Signed ?
16784 (DstDouble ? PPCISD::FCFID : PPCISD::FCFIDS) :
16785 (DstDouble ? PPCISD::FCFIDU : PPCISD::FCFIDUS);
16790 SDValue Ops[] = { LDN->getChain(), LDN->getBasePtr(), WidthConst };
16793 Ops, MVT::i8, LDN->getMemOperand());
16798 SDValue ExtOps[] = { Ld, WidthConst };
16800 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
16802 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
16810 if (
Op.getOperand(0).getValueType() == MVT::i32)
16814 "UINT_TO_FP is supported only with FPCVT");
16818 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16823 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16830 Subtarget.hasFPCVT()) ||
16832 SDValue Src =
Op.getOperand(0).getOperand(0);
16833 if (Src.getValueType() == MVT::f32) {
16835 DCI.AddToWorklist(Src.getNode());
16836 }
else if (Src.getValueType() != MVT::f64) {
16848 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
16851 DCI.AddToWorklist(
FP.getNode());
16875 switch (
N->getOpcode()) {
16880 Chain = LD->getChain();
16881 Base = LD->getBasePtr();
16882 MMO = LD->getMemOperand();
16901 MVT VecTy =
N->getValueType(0).getSimpleVT();
16909 Chain = Load.getValue(1);
16911 PPCISD::XXSWAPD, dl, DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Load);
16915 if (VecTy != MVT::v2f64) {
16942 switch (
N->getOpcode()) {
16947 Chain = ST->getChain();
16948 Base = ST->getBasePtr();
16949 MMO = ST->getMemOperand();
16969 SDValue Src =
N->getOperand(SrcOpnd);
16970 MVT VecTy = Src.getValueType().getSimpleVT();
16973 if (VecTy != MVT::v2f64) {
16979 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
16985 StoreOps, VecTy, MMO);
16992 DAGCombinerInfo &DCI)
const {
16995 unsigned Opcode =
N->getOperand(1).getOpcode();
16997 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
17001 &&
"Not a FP_TO_INT Instruction!");
17004 EVT Op1VT =
N->getOperand(1).getValueType();
17007 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
17011 bool ValidTypeForStoreFltAsInt =
17012 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.isPPC64()) ||
17013 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
17016 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
17019 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
17027 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
17042 bool PrevElemFromFirstVec = Mask[0] < NumElts;
17043 for (
int i = 1, e = Mask.size(); i < e; i++) {
17044 if (PrevElemFromFirstVec && Mask[i] < NumElts)
17046 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
17048 PrevElemFromFirstVec = !PrevElemFromFirstVec;
17059 for (
int i = 0, e =
Op.getNumOperands(); i < e; i++) {
17060 FirstOp =
Op.getOperand(i);
17066 for (
int i = 1, e =
Op.getNumOperands(); i < e; i++)
17067 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
17077 Op =
Op.getOperand(0);
17093 int RHSFirstElt,
int RHSLastElt,
int HalfVec,
unsigned LHSNumValidElts,
17094 unsigned RHSNumValidElts,
const PPCSubtarget &Subtarget) {
17096 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - LHSNumValidElts;
17098 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - RHSNumValidElts;
17099 for (
int I = 0,
E = ShuffV.
size();
I <
E; ++
I) {
17100 int Idx = ShuffV[
I];
17101 if (Idx >= LHSFirstElt && Idx <= LHSLastElt)
17102 ShuffV[
I] += LHSEltFixup;
17103 else if (Idx >= RHSFirstElt && Idx <= RHSLastElt)
17104 ShuffV[
I] += RHSEltFixup;
17115 SDLoc dl(OrigSToV);
17118 "Expecting a SCALAR_TO_VECTOR here");
17131 "Cannot produce a permuted scalar_to_vector for one element vector");
17133 unsigned ResultInElt = NumElts / 2;
17139 return DAG.
getNode(PPCISD::SCALAR_TO_VECTOR_PERMUTED, dl, VT,
17144 int HalfVec,
int LHSLastElementDefined,
17145 int RHSLastElementDefined) {
17146 for (
int Index : ShuffV) {
17150 if ((LHSLastElementDefined >= 0) && (Index < HalfVec) &&
17151 (Index > LHSLastElementDefined))
17154 if ((RHSLastElementDefined >= 0) &&
17155 (Index > HalfVec + RHSLastElementDefined))
17162 int ScalarSize,
uint64_t ShuffleEltWidth,
unsigned &NumValidElts,
17163 int FirstElt,
int &LastElt,
SDValue VecShuffOperand,
SDValue SToVNode,
17179 LastElt = (
uint64_t)ScalarSize > ShuffleEltWidth
17180 ? ScalarSize / ShuffleEltWidth - 1 + FirstElt
17183 if (SToVPermuted.
getValueType() != VecShuffOperandType)
17184 SToVPermuted = DAG.
getBitcast(VecShuffOperandType, SToVPermuted);
17185 return SToVPermuted;
17205 int NumElts =
LHS.getValueType().getVectorNumElements();
17208 bool IsLittleEndian = Subtarget.isLittleEndian();
17215 if (!Subtarget.hasDirectMove())
17235 SmallVector<int, 16> ShuffV(Mask);
17238 if (SToVLHS || SToVRHS) {
17241 int ShuffleNumElts = ShuffV.
size();
17242 int HalfVec = ShuffleNumElts / 2;
17248 unsigned LHSNumValidElts = HalfVec;
17249 unsigned RHSNumValidElts = HalfVec;
17254 int LHSFirstElt = 0;
17255 int RHSFirstElt = ShuffleNumElts;
17256 int LHSLastElt = -1;
17257 int RHSLastElt = -1;
17265 int LHSScalarSize = 0;
17266 int RHSScalarSize = 0;
17269 if (!IsLittleEndian && LHSScalarSize >= 64)
17274 if (!IsLittleEndian && RHSScalarSize >= 64)
17277 if (LHSScalarSize != 0)
17279 LHSScalarSize, ShuffleEltWidth, LHSNumValidElts, LHSFirstElt,
17280 LHSLastElt,
LHS, SToVLHS, DAG, Subtarget);
17281 if (RHSScalarSize != 0)
17283 RHSScalarSize, ShuffleEltWidth, RHSNumValidElts, RHSFirstElt,
17284 RHSLastElt,
RHS, SToVRHS, DAG, Subtarget);
17295 ShuffV, LHSFirstElt, LHSLastElt, RHSFirstElt, RHSLastElt, HalfVec,
17296 LHSNumValidElts, RHSNumValidElts, Subtarget);
17322 if (IsLittleEndian) {
17325 if (Mask[0] < NumElts)
17326 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17330 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
17335 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17339 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
17344 if (Mask[0] < NumElts)
17345 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17349 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
17354 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17358 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
17368 if (IsLittleEndian)
17377 DAGCombinerInfo &DCI)
const {
17379 "Not a reverse memop pattern!");
17381 auto IsElementReverse = [](
const ShuffleVectorSDNode *SVN) ->
bool {
17384 auto I =
Mask.rbegin();
17385 auto E =
Mask.rend();
17387 for (;
I !=
E; ++
I) {
17395 SelectionDAG &DAG = DCI.DAG;
17398 if (!
isTypeLegal(VT) || !Subtarget.isLittleEndian() || !Subtarget.hasVSX())
17404 if (!Subtarget.hasP9Vector())
17407 if(!IsElementReverse(SVN))
17414 for (SDUse &Use : LSBase->
uses())
17415 if (
Use.getResNo() == 0 &&
17422 PPCISD::LOAD_VEC_BE, dl, DAG.
getVTList(VT, MVT::Other), LoadOps,
17437 PPCISD::STORE_VEC_BE, dl, DAG.
getVTList(MVT::Other), StoreOps,
17446 if (IntrinsicID == Intrinsic::ppc_stdcx)
17448 else if (IntrinsicID == Intrinsic::ppc_stwcx)
17450 else if (IntrinsicID == Intrinsic::ppc_sthcx)
17452 else if (IntrinsicID == Intrinsic::ppc_stbcx)
17461 if (
N->getOpcode() == PPCISD::ADDC &&
N->hasAnyUseOfValue(1)) {
17465 if (
LHS->getOpcode() == PPCISD::ADDE &&
17485 SDValue CmpLHS =
N->getOperand(0);
17486 SDValue CmpRHS =
N->getOperand(1);
17487 SDValue TrueVal =
N->getOperand(2);
17488 SDValue FalseVal =
N->getOperand(3);
17502 if (FalseVal.getOpcode() !=
ISD::SRL || !FalseVal.hasOneUse())
17505 SDValue ShiftVal = FalseVal.getOperand(0);
17506 SDValue ShiftAmt = FalseVal.getOperand(1);
17510 if (!ShiftConst || !ShiftConst->getAPIntValue().isMinSignedValue())
17537 if (CtlzArg != CmpLHS)
17545 DAG.
getNode(PPCISD::SRL,
DL, FalseVal.getValueType(), ShiftVal, ShiftAmt);
17592 auto isZeroOrOne = [=](
SDValue &V) {
17594 V.getConstantOperandVal(0) == Intrinsic::ppc_test_data_class)
17599 if (!isZeroOrOne(NonNullConstant))
17609 EVT VType =
N->getValueType(0);
17613 return NewNonNullConstant;
17632 EVT XorVT =
N->getValueType(0);
17633 if ((XorVT != MVT::i32 && XorVT != MVT::i64))
17641 if (!XorConst || !XorConst->
isOne()) {
17643 if (!XorConst || !XorConst->
isOne())
17650 if (!
LHS.hasOneUse())
17658 SelectNode =
LHS.getOperand(0);
17672 if (MachineOpc != PPC::SELECT_CC_I4 && MachineOpc != PPC::SELECT_CC_I8)
17682 if (!ConstOp1 || !ConstOp2)
17686 if (!((ConstOp1->
isOne() && ConstOp2->
isZero()) ||
17695 MachineOpc = (XorVT == MVT::i32) ? PPC::SELECT_CC_I4 : PPC::SELECT_CC_I8;
17697 bool ConstOp1IsOne = ConstOp1->
isOne();
17700 {SelectNode.getOperand(0),
17701 DAG.getConstant(ConstOp1IsOne ? 0 : 1, DL, XorVT),
17702 DAG.getConstant(ConstOp1IsOne ? 1 : 0, DL, XorVT),
17703 SelectNode.getOperand(3)}),
17711 switch (
N->getOpcode()) {
17714 return combineADD(
N, DCI);
17746 return combineSHL(
N, DCI);
17748 return combineSRA(
N, DCI);
17750 return combineSRL(
N, DCI);
17752 return combineMUL(
N, DCI);
17754 case PPCISD::FNMSUB:
17755 return combineFMALike(
N, DCI);
17758 return N->getOperand(0);
17762 return N->getOperand(0);
17768 return N->getOperand(0);
17772 if (
SDValue SECC = combineSignExtendSetCC(
N, DCI))
17780 return DAGCombineExtBoolTrunc(
N, DCI);
17782 return combineTRUNCATE(
N, DCI);
17784 if (
SDValue CSCC = combineSetCC(
N, DCI))
17790 return DAGCombineTruncBoolExt(
N, DCI);
17793 return combineFPToIntToFP(
N, DCI);
17802 EVT Op1VT =
N->getOperand(1).getValueType();
17803 unsigned Opcode =
N->getOperand(1).getOpcode();
17807 SDValue Val = combineStoreFPToInt(
N, DCI);
17821 N->getOperand(1).getNode()->hasOneUse() &&
17822 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
17823 (Subtarget.hasLDBRX() && Subtarget.isPPC64() && Op1VT == MVT::i64))) {
17831 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
17838 if (Op1VT.
bitsGT(mVT)) {
17843 if (Op1VT == MVT::i64)
17848 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
17868 ST->getBasePtr(), ST->getOffset(), MemVT,
17869 ST->getMemOperand(), ST->getAddressingMode(),
17873 return ST->isUnindexed()
17882 if (Subtarget.needsSwapsForVSXMemOps() &&
17883 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
17884 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
17891 EVT VT = LD->getValueType(0);
17897 if (Subtarget.needsSwapsForVSXMemOps() &&
17898 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
17899 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
17910 auto ReplaceTwoFloatLoad = [&]() {
17911 if (VT != MVT::i64)
17926 if (!LD->hasNUsesOfValue(2, 0))
17929 auto UI = LD->user_begin();
17930 while (UI.getUse().getResNo() != 0) ++UI;
17932 while (UI.getUse().getResNo() != 0) ++UI;
17933 SDNode *RightShift = *UI;
17941 if (RightShift->getOpcode() !=
ISD::SRL ||
17943 RightShift->getConstantOperandVal(1) != 32 ||
17944 !RightShift->hasOneUse())
17947 SDNode *Trunc2 = *RightShift->user_begin();
17957 Bitcast->getValueType(0) != MVT::f32)
17963 if (Subtarget.isLittleEndian())
17969 SDValue BasePtr = LD->getBasePtr();
17970 if (LD->isIndexed()) {
17972 "Non-pre-inc AM on PPC?");
17980 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
17981 LD->getPointerInfo(), LD->getAlign(),
17982 MMOFlags, LD->getAAInfo());
17988 LD->getPointerInfo().getWithOffset(4),
17991 if (LD->isIndexed()) {
18005 if (ReplaceTwoFloatLoad())
18008 EVT MemVT = LD->getMemoryVT();
18011 if (LD->isUnindexed() && VT.
isVector() &&
18014 !Subtarget.hasP8Vector() &&
18015 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
18016 VT == MVT::v4f32))) &&
18017 LD->getAlign() < ABIAlignment) {
18019 SDValue Chain = LD->getChain();
18020 SDValue Ptr = LD->getBasePtr();
18021 bool isLittleEndian = Subtarget.isLittleEndian();
18048 MVT PermCntlTy, PermTy, LDTy;
18049 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
18050 : Intrinsic::ppc_altivec_lvsl;
18051 IntrLD = Intrinsic::ppc_altivec_lvx;
18052 IntrPerm = Intrinsic::ppc_altivec_vperm;
18053 PermCntlTy = MVT::v16i8;
18054 PermTy = MVT::v4i32;
18073 SDValue BaseLoadOps[] = { Chain, LDXIntID, Ptr };
18077 BaseLoadOps, LDTy, BaseMMO);
18086 int IncValue = IncOffset;
18103 SDValue ExtraLoadOps[] = { Chain, LDXIntID, Ptr };
18107 ExtraLoadOps, LDTy, ExtraMMO);
18118 if (isLittleEndian)
18120 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
18123 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
18126 Perm = Subtarget.hasAltivec()
18141 bool isLittleEndian = Subtarget.isLittleEndian();
18142 unsigned IID =
N->getConstantOperandVal(0);
18143 Intrinsic::ID Intr = (isLittleEndian ? Intrinsic::ppc_altivec_lvsr
18144 : Intrinsic::ppc_altivec_lvsl);
18145 if (IID == Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
18152 .zext(
Add.getScalarValueSizeInBits()))) {
18153 SDNode *BasePtr =
Add->getOperand(0).getNode();
18154 for (
SDNode *U : BasePtr->users()) {
18156 U->getConstantOperandVal(0) == IID) {
18167 SDNode *BasePtr =
Add->getOperand(0).getNode();
18168 for (
SDNode *U : BasePtr->users()) {
18171 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
18177 V->getConstantOperandVal(0) == IID) {
18189 (IID == Intrinsic::ppc_altivec_vmaxsw ||
18190 IID == Intrinsic::ppc_altivec_vmaxsh ||
18191 IID == Intrinsic::ppc_altivec_vmaxsb)) {
18222 switch (
N->getConstantOperandVal(1)) {
18225 case Intrinsic::ppc_altivec_vsum4sbs:
18226 case Intrinsic::ppc_altivec_vsum4shs:
18227 case Intrinsic::ppc_altivec_vsum4ubs: {
18234 APInt APSplatBits, APSplatUndef;
18235 unsigned SplatBitSize;
18238 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
18239 !Subtarget.isLittleEndian());
18241 if (BVNIsConstantSplat && APSplatBits == 0)
18246 case Intrinsic::ppc_vsx_lxvw4x:
18247 case Intrinsic::ppc_vsx_lxvd2x:
18250 if (Subtarget.needsSwapsForVSXMemOps())
18258 if (Subtarget.needsSwapsForVSXMemOps()) {
18259 switch (
N->getConstantOperandVal(1)) {
18262 case Intrinsic::ppc_vsx_stxvw4x:
18263 case Intrinsic::ppc_vsx_stxvd2x:
18272 bool Is64BitBswapOn64BitTgt =
18273 Subtarget.isPPC64() &&
N->getValueType(0) == MVT::i64;
18275 N->getOperand(0).hasOneUse();
18276 if (IsSingleUseNormalLd &&
18277 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
18278 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
18289 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
18290 MVT::i64 : MVT::i32, MVT::Other),
18291 Ops, LD->getMemoryVT(), LD->getMemOperand());
18295 if (
N->getValueType(0) == MVT::i16)
18312 !IsSingleUseNormalLd)
18317 if (!LD->isSimple())
18319 SDValue BasePtr = LD->getBasePtr();
18321 LD->getPointerInfo(), LD->getAlign());
18326 LD->getMemOperand(), 4, 4);
18330 if (Subtarget.isLittleEndian())
18336 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
18345 if (!
N->getOperand(0).hasOneUse() &&
18346 !
N->getOperand(1).hasOneUse() &&
18347 !
N->getOperand(2).hasOneUse()) {
18350 SDNode *VCMPrecNode =
nullptr;
18352 SDNode *LHSN =
N->getOperand(0).getNode();
18354 if (
User->getOpcode() == PPCISD::VCMP_rec &&
18358 VCMPrecNode =
User;
18370 SDNode *FlagUser =
nullptr;
18372 FlagUser ==
nullptr; ++UI) {
18373 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
18386 return SDValue(VCMPrecNode, 0);
18397 SDValue LHS =
N->getOperand(2), RHS =
N->getOperand(3);
18408 auto RHSAPInt = RHS->getAsAPIntVal();
18409 if (!RHSAPInt.isIntN(64))
18412 unsigned Val = RHSAPInt.getZExtValue();
18413 auto isImpossibleCompare = [&]() {
18416 if (Val != 0 && Val != 1) {
18418 return N->getOperand(0);
18421 N->getOperand(0),
N->getOperand(4));
18426 unsigned StoreWidth = 0;
18429 if (
SDValue Impossible = isImpossibleCompare())
18441 SDValue Ops[] = {LHS.getOperand(0), LHS.getOperand(2), LHS.getOperand(3),
18445 PPCISD::STORE_COND, dl,
18447 MemNode->getMemoryVT(), MemNode->getMemOperand());
18451 if (
N->getOperand(0) == LHS.getValue(1))
18462 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other, InChain,
18464 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
18470 assert(isDot &&
"Can't compare against a vector result!");
18472 if (
SDValue Impossible = isImpossibleCompare())
18475 bool BranchOnWhenPredTrue = (CC ==
ISD::SETEQ) ^ (Val == 0);
18482 EVT VTs[] = { LHS.getOperand(2).getValueType(), MVT::Glue };
18487 switch (LHS.getConstantOperandVal(1)) {
18503 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other,
N->getOperand(0),
18506 N->getOperand(4), CompNode.
getValue(1));
18511 return DAGCombineBuildVector(
N, DCI);
18516 return DAGCombineBitcast(
N, DCI);
18527 EVT VT =
N->getValueType(0);
18528 if (VT == MVT::i64 && !Subtarget.isPPC64())
18530 if ((VT != MVT::i32 && VT != MVT::i64) ||
18538 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
18558 const APInt &DemandedElts,
18560 unsigned Depth)
const {
18562 switch (
Op.getOpcode()) {
18564 case PPCISD::LBRX: {
18567 Known.
Zero = 0xFFFF0000;
18570 case PPCISD::ADDE: {
18571 if (
Op.getResNo() == 0) {
18576 Known.
Zero = ~1ULL;
18581 switch (
Op.getConstantOperandVal(0)) {
18583 case Intrinsic::ppc_altivec_vcmpbfp_p:
18584 case Intrinsic::ppc_altivec_vcmpeqfp_p:
18585 case Intrinsic::ppc_altivec_vcmpequb_p:
18586 case Intrinsic::ppc_altivec_vcmpequh_p:
18587 case Intrinsic::ppc_altivec_vcmpequw_p:
18588 case Intrinsic::ppc_altivec_vcmpequd_p:
18589 case Intrinsic::ppc_altivec_vcmpequq_p:
18590 case Intrinsic::ppc_altivec_vcmpgefp_p:
18591 case Intrinsic::ppc_altivec_vcmpgtfp_p:
18592 case Intrinsic::ppc_altivec_vcmpgtsb_p:
18593 case Intrinsic::ppc_altivec_vcmpgtsh_p:
18594 case Intrinsic::ppc_altivec_vcmpgtsw_p:
18595 case Intrinsic::ppc_altivec_vcmpgtsd_p:
18596 case Intrinsic::ppc_altivec_vcmpgtsq_p:
18597 case Intrinsic::ppc_altivec_vcmpgtub_p:
18598 case Intrinsic::ppc_altivec_vcmpgtuh_p:
18599 case Intrinsic::ppc_altivec_vcmpgtuw_p:
18600 case Intrinsic::ppc_altivec_vcmpgtud_p:
18601 case Intrinsic::ppc_altivec_vcmpgtuq_p:
18608 switch (
Op.getConstantOperandVal(1)) {
18611 case Intrinsic::ppc_load2r:
18613 Known.
Zero = 0xFFFF0000;
18622 switch (Subtarget.getCPUDirective()) {
18644 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
18653 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
18655 LoopSize +=
TII->getInstSizeInBytes(J);
18660 if (LoopSize > 16 && LoopSize <= 32)
18674 if (Constraint.
size() == 1) {
18675 switch (Constraint[0]) {
18693 }
else if (Constraint ==
"wc") {
18695 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
18696 Constraint ==
"wf" || Constraint ==
"ws" ||
18697 Constraint ==
"wi" || Constraint ==
"ww") {
18710 Value *CallOperandVal =
info.CallOperandVal;
18713 if (!CallOperandVal)
18720 else if ((
StringRef(constraint) ==
"wa" ||
18732 switch (*constraint) {
18762std::pair<unsigned, const TargetRegisterClass *>
18766 if (Constraint.
size() == 1) {
18768 switch (Constraint[0]) {
18770 if (VT == MVT::i64 && Subtarget.isPPC64())
18771 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
18772 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
18774 if (VT == MVT::i64 && Subtarget.isPPC64())
18775 return std::make_pair(0U, &PPC::G8RCRegClass);
18776 return std::make_pair(0U, &PPC::GPRCRegClass);
18782 if (Subtarget.hasSPE()) {
18783 if (VT == MVT::f32 || VT == MVT::i32)
18784 return std::make_pair(0U, &PPC::GPRCRegClass);
18785 if (VT == MVT::f64 || VT == MVT::i64)
18786 return std::make_pair(0U, &PPC::SPERCRegClass);
18788 if (VT == MVT::f32 || VT == MVT::i32)
18789 return std::make_pair(0U, &PPC::F4RCRegClass);
18790 if (VT == MVT::f64 || VT == MVT::i64)
18791 return std::make_pair(0U, &PPC::F8RCRegClass);
18795 if (Subtarget.hasAltivec() && VT.
isVector())
18796 return std::make_pair(0U, &PPC::VRRCRegClass);
18797 else if (Subtarget.hasVSX())
18799 return std::make_pair(0U, &PPC::VFRCRegClass);
18802 return std::make_pair(0U, &PPC::CRRCRegClass);
18804 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
18806 return std::make_pair(0U, &PPC::CRBITRCRegClass);
18807 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
18808 Constraint ==
"wf" || Constraint ==
"wi") &&
18809 Subtarget.hasVSX()) {
18813 return std::make_pair(0U, &PPC::VSRCRegClass);
18814 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18815 return std::make_pair(0U, &PPC::VSSRCRegClass);
18816 return std::make_pair(0U, &PPC::VSFRCRegClass);
18817 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
18818 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18819 return std::make_pair(0U, &PPC::VSSRCRegClass);
18821 return std::make_pair(0U, &PPC::VSFRCRegClass);
18822 }
else if (Constraint ==
"lr") {
18823 if (VT == MVT::i64)
18824 return std::make_pair(0U, &PPC::LR8RCRegClass);
18826 return std::make_pair(0U, &PPC::LRRCRegClass);
18831 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
18835 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
18836 int VSNum = atoi(Constraint.
data() + 3);
18837 assert(VSNum >= 0 && VSNum <= 63 &&
18838 "Attempted to access a vsr out of range");
18840 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
18841 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
18846 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
18847 int RegNum = atoi(Constraint.
data() + 2);
18848 if (RegNum > 31 || RegNum < 0)
18850 if (VT == MVT::f32 || VT == MVT::i32)
18851 return Subtarget.hasSPE()
18852 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
18853 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
18854 if (VT == MVT::f64 || VT == MVT::i64)
18855 return Subtarget.hasSPE()
18856 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
18857 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
18861 std::pair<unsigned, const TargetRegisterClass *> R =
18870 if (R.first && VT == MVT::i64 && Subtarget.isPPC64() &&
18871 PPC::GPRCRegClass.contains(R.first))
18872 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
18873 PPC::sub_32, &PPC::G8RCRegClass),
18874 &PPC::G8RCRegClass);
18877 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
18878 R.first = PPC::CR0;
18879 R.second = &PPC::CRRCRegClass;
18883 if (Subtarget.isAIXABI() && !TM.getAIXExtendedAltivecABI()) {
18884 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
18885 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
18886 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
18887 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
18888 "default AIX AltiVec ABI and cannot be used\n";
18898 std::vector<SDValue> &
Ops,
18903 if (Constraint.
size() > 1)
18906 char Letter = Constraint[0];
18921 EVT TCVT = MVT::i64;
18962 if (Result.getNode()) {
18963 Ops.push_back(Result);
18974 if (
I.getNumOperands() <= 1)
18978 auto IntrinsicID =
Ops[1].getNode()->getAsZExtVal();
18979 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
18980 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
18983 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
18999 if (Ty->isVectorTy() && AM.
BaseOffs != 0 && !Subtarget.hasP9Vector())
19011 switch (AM.
Scale) {
19039 unsigned Depth =
Op.getConstantOperandVal(0);
19063 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
19071 unsigned Depth =
Op.getConstantOperandVal(0);
19078 bool isPPC64 = PtrVT == MVT::i64;
19084 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
19086 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
19092 FrameAddr, MachinePointerInfo());
19096#define GET_REGISTER_MATCHER
19097#include "PPCGenAsmMatcher.inc"
19101 bool IsPPC64 = Subtarget.isPPC64();
19113 if ((IsPPC64 && Reg == PPC::R2) || Reg == PPC::R0)
19119 Reg = Reg.id() - PPC::R0 + PPC::X0;
19126 if (Subtarget.is32BitELFABI())
19131 if (Subtarget.isAIXABI())
19145 return Subtarget.isGVIndirectSymbol(
G->getGlobal());
19161 case Intrinsic::ppc_atomicrmw_xchg_i128:
19162 case Intrinsic::ppc_atomicrmw_add_i128:
19163 case Intrinsic::ppc_atomicrmw_sub_i128:
19164 case Intrinsic::ppc_atomicrmw_nand_i128:
19165 case Intrinsic::ppc_atomicrmw_and_i128:
19166 case Intrinsic::ppc_atomicrmw_or_i128:
19167 case Intrinsic::ppc_atomicrmw_xor_i128:
19168 case Intrinsic::ppc_cmpxchg_i128:
19170 Info.memVT = MVT::i128;
19171 Info.ptrVal =
I.getArgOperand(0);
19173 Info.align =
Align(16);
19178 case Intrinsic::ppc_atomic_load_i128:
19180 Info.memVT = MVT::i128;
19181 Info.ptrVal =
I.getArgOperand(0);
19183 Info.align =
Align(16);
19187 case Intrinsic::ppc_atomic_store_i128:
19189 Info.memVT = MVT::i128;
19190 Info.ptrVal =
I.getArgOperand(2);
19192 Info.align =
Align(16);
19196 case Intrinsic::ppc_altivec_lvx:
19197 case Intrinsic::ppc_altivec_lvxl:
19198 case Intrinsic::ppc_altivec_lvebx:
19199 case Intrinsic::ppc_altivec_lvehx:
19200 case Intrinsic::ppc_altivec_lvewx:
19201 case Intrinsic::ppc_vsx_lxvd2x:
19202 case Intrinsic::ppc_vsx_lxvw4x:
19203 case Intrinsic::ppc_vsx_lxvd2x_be:
19204 case Intrinsic::ppc_vsx_lxvw4x_be:
19205 case Intrinsic::ppc_vsx_lxvl:
19206 case Intrinsic::ppc_vsx_lxvll: {
19209 case Intrinsic::ppc_altivec_lvebx:
19212 case Intrinsic::ppc_altivec_lvehx:
19215 case Intrinsic::ppc_altivec_lvewx:
19218 case Intrinsic::ppc_vsx_lxvd2x:
19219 case Intrinsic::ppc_vsx_lxvd2x_be:
19229 Info.ptrVal =
I.getArgOperand(0);
19232 Info.align =
Align(1);
19237 case Intrinsic::ppc_altivec_stvx:
19238 case Intrinsic::ppc_altivec_stvxl:
19239 case Intrinsic::ppc_altivec_stvebx:
19240 case Intrinsic::ppc_altivec_stvehx:
19241 case Intrinsic::ppc_altivec_stvewx:
19242 case Intrinsic::ppc_vsx_stxvd2x:
19243 case Intrinsic::ppc_vsx_stxvw4x:
19244 case Intrinsic::ppc_vsx_stxvd2x_be:
19245 case Intrinsic::ppc_vsx_stxvw4x_be:
19246 case Intrinsic::ppc_vsx_stxvl:
19247 case Intrinsic::ppc_vsx_stxvll: {
19250 case Intrinsic::ppc_altivec_stvebx:
19253 case Intrinsic::ppc_altivec_stvehx:
19256 case Intrinsic::ppc_altivec_stvewx:
19259 case Intrinsic::ppc_vsx_stxvd2x:
19260 case Intrinsic::ppc_vsx_stxvd2x_be:
19270 Info.ptrVal =
I.getArgOperand(1);
19273 Info.align =
Align(1);
19278 case Intrinsic::ppc_stdcx:
19279 case Intrinsic::ppc_stwcx:
19280 case Intrinsic::ppc_sthcx:
19281 case Intrinsic::ppc_stbcx: {
19283 auto Alignment =
Align(8);
19285 case Intrinsic::ppc_stdcx:
19288 case Intrinsic::ppc_stwcx:
19290 Alignment =
Align(4);
19292 case Intrinsic::ppc_sthcx:
19294 Alignment =
Align(2);
19296 case Intrinsic::ppc_stbcx:
19298 Alignment =
Align(1);
19303 Info.ptrVal =
I.getArgOperand(0);
19305 Info.align = Alignment;
19319 const AttributeList &FuncAttributes)
const {
19323 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
19324 if (
Op.isMemset() && Subtarget.hasVSX()) {
19329 if (TailSize > 2 && TailSize <= 4) {
19334 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
19339 if (Subtarget.isPPC64()) {
19350 assert(Ty->isIntegerTy());
19352 unsigned BitSize = Ty->getPrimitiveSizeInBits();
19353 return !(BitSize == 0 || BitSize > 64);
19361 return NumBits1 == 64 && NumBits2 == 32;
19369 return NumBits1 == 64 && NumBits2 == 32;
19376 EVT MemVT = LD->getMemoryVT();
19377 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
19378 (Subtarget.isPPC64() && MemVT == MVT::i32)) &&
19394 "invalid fpext types");
19396 if (DestVT == MVT::f128)
19411 unsigned *
Fast)
const {
19425 !Subtarget.allowsUnalignedFPAccess())
19429 if (Subtarget.hasVSX()) {
19430 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
19431 VT != MVT::v4f32 && VT != MVT::v4i32)
19438 if (VT == MVT::ppcf128)
19453 if (!ConstNode->getAPIntValue().isSignedIntN(64))
19461 int64_t Imm = ConstNode->getSExtValue();
19482 if (Subtarget.hasSPE() || Subtarget.useSoftFloat())
19484 switch (Ty->getScalarType()->getTypeID()) {
19489 return Subtarget.hasP9Vector();
19497 if (!
I->hasOneUse())
19501 assert(
User &&
"A single use instruction with no uses.");
19503 switch (
I->getOpcode()) {
19504 case Instruction::FMul: {
19506 if (
User->getOpcode() != Instruction::FSub &&
19507 User->getOpcode() != Instruction::FAdd)
19514 bool AllowContract =
I->getFastMathFlags().allowContract() &&
19515 User->getFastMathFlags().allowContract();
19521 case Instruction::Load: {
19534 if (
User->getOpcode() != Instruction::Store)
19554 static const MCPhysReg ScratchRegs[] = {
19555 PPC::X12, PPC::LR8, PPC::CTR8, 0
19558 return ScratchRegs;
19562 const Constant *PersonalityFn)
const {
19563 return Subtarget.isPPC64() ? PPC::X3 : PPC::R3;
19567 const Constant *PersonalityFn)
const {
19568 return Subtarget.isPPC64() ? PPC::X4 : PPC::R4;
19573 EVT VT ,
unsigned DefinedValues)
const {
19574 if (VT == MVT::v2i64)
19575 return Subtarget.hasDirectMove();
19577 if (Subtarget.hasVSX())
19604 return PPCISD::FNMSUB;
19605 case PPCISD::FNMSUB:
19611 bool LegalOps,
bool OptForSize,
19613 unsigned Depth)
const {
19617 unsigned Opc =
Op.getOpcode();
19618 EVT VT =
Op.getValueType();
19622 case PPCISD::FNMSUB:
19642 if (Flags.hasNoSignedZeros()) {
19646 N0Cost,
Depth + 1);
19650 N1Cost,
Depth + 1);
19652 if (NegN0 && N0Cost <= N1Cost) {
19653 Cost = std::min(N0Cost, N2Cost);
19655 }
else if (NegN1) {
19656 Cost = std::min(N1Cost, N2Cost);
19676 if (M.getStackProtectorGuard() ==
"tls" || Subtarget.isTargetLinux())
19682 bool ForCodeSize)
const {
19683 if (!VT.
isSimple() || !Subtarget.hasVSX())
19693 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
19698 APSInt IntResult(16,
false);
19703 if (IsExact && IntResult <= 15 && IntResult >= -16)
19705 return Imm.isZero();
19708 return Imm.isPosZero();
19720 unsigned Opcode =
N->getOpcode();
19740 if (Mask->getZExtValue() == OpSizeInBits - 1)
19747 DAGCombinerInfo &DCI)
const {
19748 EVT VT =
N->getValueType(0);
19751 unsigned Opc =
N->getOpcode();
19753 "Unexpected opcode.");
19760 if (EltTy != MVT::i64 && EltTy != MVT::i32)
19764 uint64_t SplatBits = 0;
19765 bool AddSplatCase =
false;
19769 AddSplatCase =
true;
19773 if (!AddSplatCase) {
19777 unsigned SplatBitSize;
19779 APInt APSplatBits, APSplatUndef;
19781 bool BVNIsConstantSplat =
19783 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
19784 if (!BVNIsConstantSplat || SplatBitSize != EltBits)
19795 if (SplatBits == (EltBits - 1)) {
19799 NewOpc = PPCISD::SHL;
19802 NewOpc = PPCISD::SRL;
19805 NewOpc = PPCISD::SRA;
19809 return DCI.DAG.getNode(NewOpc,
DL, VT, N0, SplatOnes);
19817 if (EltTy != MVT::i64 || SplatBits != 1)
19820 return DCI.DAG.getNode(
ISD::ADD, SDLoc(
N), VT, N0, N0);
19823SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19827 if (
N->getValueType(0).isVector())
19828 return combineVectorShift(
N, DCI);
19832 if (!Subtarget.isISA3_0() || !Subtarget.isPPC64() ||
19835 N->getValueType(0) != MVT::i64)
19850 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
19856SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19860 if (
N->getValueType(0).isVector())
19861 return combineVectorShift(
N, DCI);
19866SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19870 if (
N->getValueType(0).isVector())
19871 return combineVectorShift(
N, DCI);
19882 if (!Subtarget.isPPC64())
19888 auto isZextOfCompareWithConstant = [](
SDValue Op) {
19890 Op.getValueType() != MVT::i64)
19894 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
19895 Cmp.getOperand(0).getValueType() != MVT::i64)
19899 int64_t NegConstant = 0 -
Constant->getSExtValue();
19908 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
19909 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
19912 if (LHSHasPattern && !RHSHasPattern)
19914 else if (!LHSHasPattern && !RHSHasPattern)
19918 EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
19921 SDValue Z = Cmp.getOperand(0);
19923 int64_t NegConstant = 0 -
Constant->getSExtValue();
19936 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
19954 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
19984 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
19987 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
19995 if (!GSDN || !ConstNode)
20023 EVT VT =
N->getValueType(0);
20024 if (!Subtarget.hasVSX())
20028 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
20040 unsigned NumOfEles =
RHS.getNumOperands();
20041 for (
unsigned i = 0; i < NumOfEles; ++i) {
20043 if (!CN || CN->getSExtValue() != 1)
20058SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20080 DAGCombinerInfo &DCI)
const {
20082 if (Subtarget.useCRBits()) {
20084 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
20085 return CRTruncValue;
20092 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
20095 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
20105 EltToExtract = EltToExtract ? 0 : 1;
20115 return DCI.DAG.getNode(
20117 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
20122SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20123 SelectionDAG &DAG = DCI.DAG;
20126 if (!ConstOpOrElement)
20134 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne, EVT VT) ->
bool {
20135 switch (this->Subtarget.getCPUDirective()) {
20158 return IsAddOne && IsNeg ? VT.
isVector() :
true;
20162 EVT VT =
N->getValueType(0);
20167 APInt MulAmtAbs = MulAmt.
abs();
20169 if ((MulAmtAbs - 1).isPowerOf2()) {
20173 if (!IsProfitable(IsNeg,
true, VT))
20186 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
20190 if (!IsProfitable(IsNeg,
false, VT))
20211 DAGCombinerInfo &DCI)
const {
20215 SDNodeFlags
Flags =
N->getFlags();
20216 EVT VT =
N->getValueType(0);
20217 SelectionDAG &DAG = DCI.DAG;
20218 unsigned Opc =
N->getOpcode();
20220 bool LegalOps = !DCI.isBeforeLegalizeOps();
20228 if (!
Flags.hasNoSignedZeros())
20244bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
20246 if (!Subtarget.is64BitELFABI())
20256 if (!TM.Options.GuaranteedTailCallOpt &&
DisableSCO)
20261 if (!Callee ||
Callee->isVarArg())
20274bool PPCTargetLowering::
20275isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
20280 if (CI->getBitWidth() > 64)
20282 int64_t ConstVal = CI->getZExtValue();
20284 (
isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
20293PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
20299 if ((Flags & FlagSet) == FlagSet)
20302 if ((Flags & FlagSet) == FlagSet)
20305 if ((Flags & FlagSet) == FlagSet)
20308 if ((Flags & FlagSet) == FlagSet)
20329 if ((FrameIndexAlign % 4) != 0)
20330 FlagSet &=
~PPC::MOF_RPlusSImm16Mult4;
20331 if ((FrameIndexAlign % 16) != 0)
20332 FlagSet &=
~PPC::MOF_RPlusSImm16Mult16;
20336 if ((FrameIndexAlign % 4) == 0)
20338 if ((FrameIndexAlign % 16) == 0)
20351 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
20352 if ((Imm & 0x3) == 0)
20354 if ((Imm & 0xf) == 0)
20360 const APInt &ConstImm = CN->getAPIntValue();
20379 const APInt &ConstImm = CN->getAPIntValue();
20389 }
else if (
RHS.getOpcode() == PPCISD::Lo && !
RHS.getConstantOperandVal(1))
20400 return (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR ||
20409unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
20414 if (!Subtarget.hasP9Vector())
20419 if (Subtarget.hasPrefixInstrs())
20422 if (Subtarget.hasSPE())
20431 unsigned ParentOp = Parent->
getOpcode();
20435 if ((
ID == Intrinsic::ppc_vsx_lxvp) || (
ID == Intrinsic::ppc_vsx_stxvp)) {
20436 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
20448 if (LSB->isIndexed())
20454 assert(MN &&
"Parent should be a MemSDNode!");
20459 "Not expecting scalar integers larger than 16 bytes!");
20462 else if (
Size == 32)
20469 else if (
Size == 256) {
20470 assert(Subtarget.pairedVectorMemops() &&
20471 "256-bit vectors are only available when paired vector memops is "
20479 else if (MemVT == MVT::f128 || MemVT.
isVector())
20510 FlagSet &= ~PPC::MOF_NoExt;
20515 bool IsNonP1034BitConst =
20519 IsNonP1034BitConst)
20532 int16_t ForceXFormImm = 0;
20535 Disp =
N.getOperand(0);
20536 Base =
N.getOperand(1);
20547 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
20548 Disp =
N.getOperand(0);
20549 Base =
N.getOperand(1);
20554 Disp = DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20563 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
20569 if (PartVT == MVT::f64 &&
20570 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
20579SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
20583 EVT RetVT =
Op.getValueType();
20590 EVT ArgVT =
N.getValueType();
20594 Entry.IsZExt = !Entry.IsSExt;
20595 Args.push_back(Entry);
20603 (RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
20616SDValue PPCTargetLowering::lowerLibCallBasedOnType(
20617 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
20619 if (
Op.getValueType() == MVT::f32)
20620 return lowerToLibCall(LibCallFloatName,
Op, DAG);
20622 if (
Op.getValueType() == MVT::f64)
20623 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
20628bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
20629 SDNodeFlags
Flags =
Op.getNode()->getFlags();
20630 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
20634bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
20635 return Op.getNode()->getFlags().hasApproximateFuncs();
20638bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
20642SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
20643 const char *LibCallFloatName,
20644 const char *LibCallDoubleNameFinite,
20645 const char *LibCallFloatNameFinite,
20648 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
20651 if (!isLowringToMASSFiniteSafe(
Op))
20652 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
20655 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
20656 LibCallDoubleNameFinite,
Op, DAG);
20660 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
20661 "__xl_powf_finite",
Op, DAG);
20665 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
20666 "__xl_sinf_finite",
Op, DAG);
20670 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
20671 "__xl_cosf_finite",
Op, DAG);
20675 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
20676 "__xl_logf_finite",
Op, DAG);
20680 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
20681 "__xl_log10f_finite",
Op, DAG);
20685 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
20686 "__xl_expf_finite",
Op, DAG);
20711 unsigned Flags = computeMOFlags(Parent,
N, DAG);
20722 assert(Subtarget.isUsingPCRelativeCalls() &&
20723 "Must be using PC-Relative calls when a valid PC-Relative node is "
20753 Disp =
N.getOperand(1).getOperand(0);
20758 Base =
N.getOperand(0);
20766 EVT CNType = CN->getValueType(0);
20767 uint64_t CNImm = CN->getZExtValue();
20778 if ((CNType == MVT::i32 ||
isInt<32>(CNImm)) &&
20780 int32_t Addr = (int32_t)CNImm;
20785 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
20801 unsigned Opcode =
N.getOpcode();
20809 Base =
N.getOperand(0);
20828 Base = FI ?
N :
N.getOperand(1);
20829 Disp = FI ? DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20840 bool IsVarArg)
const {
20850 return Subtarget.isPPC64() && Subtarget.hasQuadwordAtomics();
20887 return Intrinsic::ppc_atomicrmw_xchg_i128;
20889 return Intrinsic::ppc_atomicrmw_add_i128;
20891 return Intrinsic::ppc_atomicrmw_sub_i128;
20893 return Intrinsic::ppc_atomicrmw_and_i128;
20895 return Intrinsic::ppc_atomicrmw_or_i128;
20897 return Intrinsic::ppc_atomicrmw_xor_i128;
20899 return Intrinsic::ppc_atomicrmw_nand_i128;
20907 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
20911 Value *IncrLo = Builder.CreateTrunc(Incr, Int64Ty,
"incr_lo");
20913 Builder.CreateTrunc(Builder.CreateLShr(Incr, 64), Int64Ty,
"incr_hi");
20914 Value *LoHi = Builder.CreateIntrinsic(
20916 {AlignedAddr, IncrLo, IncrHi});
20917 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
20918 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
20919 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
20920 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
20921 return Builder.CreateOr(
20922 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
20929 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
20935 Value *CmpLo = Builder.CreateTrunc(CmpVal, Int64Ty,
"cmp_lo");
20937 Builder.CreateTrunc(Builder.CreateLShr(CmpVal, 64), Int64Ty,
"cmp_hi");
20938 Value *NewLo = Builder.CreateTrunc(NewVal, Int64Ty,
"new_lo");
20940 Builder.CreateTrunc(Builder.CreateLShr(NewVal, 64), Int64Ty,
"new_hi");
20943 Builder.CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
20945 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
20946 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
20947 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
20948 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
20949 return Builder.CreateOr(
20950 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
20954 return Subtarget.useCRBits();
20959bool PPCTargetLowering::isShuffleMaskLegal(
ArrayRef<int> Mask,
EVT VT)
const {
20970 DAGCombinerInfo &DCI)
const {
20975 EVT ResVT =
N->getValueType(0);
20977 EVT SrcVT = Src.getValueType();
20982 if (ResVT != MVT::i16 && ResVT != MVT::i8)
20985 GenerateVBPERM(DAG, dl, Src, SrcVT, TruncResVT, IsLittleEndian);
20998 bool IsV16i8 = (ResVT == MVT::v16i1 && SrcVT == MVT::v16i8);
20999 bool IsV8i16 = (ResVT == MVT::v8i1 && SrcVT == MVT::v8i16);
21000 bool IsV8i8 = (ResVT == MVT::v8i1 && SrcVT == MVT::v8i8);
21002 if (!IsV16i8 && !IsV8i16 && !IsV8i8)
21010 SmallVector<int, 16> BitIndices(16, 128);
21014 BitIndices[Idx] = EltSize * (NumElts - Idx) - 1;
21015 if (IsV8i8 && IsLE)
21016 BitIndices[Idx] += 64;
21019 std::reverse(BitIndices.begin(), BitIndices.end());
21021 for (
auto Idx : BitIndices)
21026 DAG.
getConstant(Intrinsic::ppc_altivec_vbpermq, dl, MVT::i32),
21034 bool BVNIsConstantSplat,
21035 unsigned SplatBitSize)
const {
21037 if (!BVNIsConstantSplat || !Subtarget.hasVSX() || !Subtarget.hasP8Vector() ||
21038 Subtarget.hasP10Vector())
21041 EVT VT =
Op->getValueType(0);
21042 if (!((SplatBitSize == 64 && VT == MVT::v2f64) ||
21043 (SplatBitSize == 32 && VT == MVT::v4f32)))
21050 APFloat APFloatVal = CN->getValueAPF();
21052 APSInt IntResult(16,
false);
21055 if (!(IsExact && IntResult <= 15 && IntResult >= -16 && !APFloatVal.
isZero()))
21058 int64_t
IntVal = IntResult.getSExtValue();
21063 if (SplatBitSize == 64)
21066 DAG.
getConstant(Intrinsic::ppc_vsx_xvcvsxwdp, dl, MVT::i32), IntSplat);
21068 return DAG.
getNode(PPCISD::XVCVSXWSP, dl, MVT::v4f32, IntSplat);
static MCRegister MatchRegisterName(StringRef Name)
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall, std::optional< CallLowering::PtrAuthInfo > &PAI, MachineRegisterInfo &MRI)
static SDValue GeneratePerfectShuffle(unsigned ID, SDValue V1, SDValue V2, unsigned PFEntry, SDValue LHS, SDValue RHS, SelectionDAG &DAG, const SDLoc &DL)
GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit the specified operations t...
static bool isSignExtended(SDValue N, SelectionDAG &DAG)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
static std::pair< Register, unsigned > getBaseWithConstantOffset(MachineRegisterInfo &MRI, Register Reg)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
static bool isLoad(int Opcode)
static bool isFloatingPointZero(SDValue Op)
isFloatingPointZero - Return true if this is +0.0.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
Atomic ordering constants.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
const HexagonInstrInfo * TII
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, ISD::ArgFlagsTy Flags, SelectionDAG &DAG, const SDLoc &dl)
CreateCopyOfByValArgument - Make a copy of an aggregate at address specified by "Src" to address "Dst...
Module.h This file contains the declarations for the Module class.
This defines the Use class.
static Value * getOpcode(Value &V, Type &Ty, InstrumentationConfig &IConf, InstrumentorIRBuilderTy &IIRB)
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
static int getEstimateRefinementSteps(EVT VT, const LoongArchSubtarget &Subtarget)
static bool isSplat(Value *V)
Return true if V is a splat of a value (which is used when multiplying a matrix with a scalar).
Machine Check Debug Module
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static bool isConstantOrUndef(const SDValue Op)
MachineInstr unsigned OpIdx
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
cl::opt< bool > ANDIGlueBug("expose-ppc-andi-glue-bug", cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden)
static SDValue getCanonicalConstSplat(uint64_t Val, unsigned SplatSize, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
getCanonicalConstSplat - Build a canonical splat immediate of Val with an element size of SplatSize.
static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
static const TargetRegisterClass * getRegClassForSVT(MVT::SimpleValueType SVT, bool IsPPC64, bool HasP8Vector, bool HasVSX)
static bool isGPRShadowAligned(MCPhysReg Reg, Align RequiredAlign)
static SDValue DAGCombineAddc(SDNode *N, llvm::PPCTargetLowering::DAGCombinerInfo &DCI)
static bool needStackSlotPassParameters(const PPCSubtarget &Subtarget, const SmallVectorImpl< ISD::OutputArg > &Outs)
std::tuple< uint32_t, uint8_t > LXVKQPattern
static bool isAlternatingShuffMask(const ArrayRef< int > &Mask, int NumElts)
static bool isShuffleMaskInRange(const SmallVectorImpl< int > &ShuffV, int HalfVec, int LHSLastElementDefined, int RHSLastElementDefined)
static SDValue addShuffleForVecExtend(SDNode *N, SelectionDAG &DAG, SDValue Input, uint64_t Elems, uint64_t CorrectElems)
static cl::opt< bool > DisablePPCUnaligned("disable-ppc-unaligned", cl::desc("disable unaligned load/store generation on PPC"), cl::Hidden)
static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool findConsecutiveLoad(LoadSDNode *LD, SelectionDAG &DAG)
static SDValue generateEquivalentSub(SDNode *N, int Size, bool Complement, bool Swap, SDLoc &DL, SelectionDAG &DAG)
This function is called when we have proved that a SETCC node can be replaced by subtraction (and oth...
static unsigned mapArgRegToOffsetAIX(unsigned Reg, const PPCFrameLowering *FL)
static void CalculateTailCallArgDest(SelectionDAG &DAG, MachineFunction &MF, bool IsPPC64, SDValue Arg, int SPDiff, unsigned ArgOffset, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
CalculateTailCallArgDest - Remember Argument for later processing.
static MachineBasicBlock * emitAtomicCmpSwapSoftware(MachineInstr &MI, MachineBasicBlock *BB, const TargetInstrInfo *TII, const PPCSubtarget &Subtarget)
Emit software-emulated atomic compare-and-swap for I8/I16 without hardware partword atomic support.
static SDValue combineADDToMAT_PCREL_ADDR(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setAlignFlagsForFI(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Set alignment flags based on whether or not the Frame Index is aligned.
static bool isTOCSaveRestoreRequired(const PPCSubtarget &Subtarget)
static void updateForAIXShLibTLSModelOpt(TLSModel::Model &Model, SelectionDAG &DAG, const TargetMachine &TM)
updateForAIXShLibTLSModelOpt - Helper to initialize TLS model opt settings, and then apply the update...
static bool IsSelect(unsigned Opcode, bool CheckOnlyCC=false)
Check if the opcode is a SELECT or SELECT_CC variant.
static bool provablyDisjointOr(SelectionDAG &DAG, const SDValue &N)
Used when computing address flags for selecting loads and stores.
static bool callsShareTOCBase(const Function *Caller, const GlobalValue *CalleeGV, const TargetMachine &TM)
static void prepareOutOfLineGlueCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, SDValue CallSeqStart, const CallBase *CB, const SDLoc &dl, bool hasNest, const PPCSubtarget &Subtarget)
static SDValue generateSToVPermutedForVecShuffle(int ScalarSize, uint64_t ShuffleEltWidth, unsigned &NumValidElts, int FirstElt, int &LastElt, SDValue VecShuffOperand, SDValue SToVNode, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
constexpr uint64_t AIXSmallTlsPolicySizeLimit
static bool isPCRelNode(SDValue N)
static void LowerMemOpCallTo(SelectionDAG &DAG, MachineFunction &MF, SDValue Chain, SDValue Arg, SDValue PtrOff, int SPDiff, unsigned ArgOffset, bool isPPC64, bool isTailCall, bool isVector, SmallVectorImpl< SDValue > &MemOpChains, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments, const SDLoc &dl)
LowerMemOpCallTo - Store the argument to the stack or remember it in case of tail calls.
static cl::opt< unsigned > PPCGatherAllAliasesMaxDepth("ppc-gather-alias-max-depth", cl::init(18), cl::Hidden, cl::desc("max depth when checking alias info in GatherAllAliases()"))
static bool IsSelectCC(unsigned Opcode)
static bool areCallingConvEligibleForTCO_64SVR4(CallingConv::ID CallerCC, CallingConv::ID CalleeCC)
static const MCPhysReg FPR[]
FPR - The set of FP registers that should be allocated for arguments on Darwin and AIX.
static SDNode * isBLACompatibleAddress(SDValue Op, SelectionDAG &DAG)
isCallCompatibleAddress - Return the immediate to use if the specified 32-bit value is representable ...
static Align CalculateStackSlotAlignment(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotAlignment - Calculates the alignment of this argument on the stack.
static SDValue ConvertCarryFlagToCarryValue(EVT SumType, SDValue Flag, EVT CarryType, SelectionDAG &DAG, const PPCSubtarget &STI)
static bool haveEfficientBuildVectorPattern(BuildVectorSDNode *V, bool HasDirectMove, bool HasP8Vector)
Do we have an efficient pattern in a .td file for this node?
static SDValue getSToVPermuted(SDValue OrigSToV, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setUsesTOCBasePtr(MachineFunction &MF)
static SDValue combineXorSelectCC(SDNode *N, SelectionDAG &DAG)
static SDValue transformCallee(const SDValue &Callee, SelectionDAG &DAG, const SDLoc &dl, const PPCSubtarget &Subtarget)
static unsigned EnsureStackAlignment(const PPCFrameLowering *Lowering, unsigned NumBytes)
EnsureStackAlignment - Round stack frame size up from NumBytes to ensure minimum alignment required f...
static SDValue stripModuloOnShift(const TargetLowering &TLI, SDNode *N, SelectionDAG &DAG)
static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth)
static bool hasSameArgumentList(const Function *CallerFn, const CallBase &CB)
static bool isFPExtLoad(SDValue Op)
static SDValue BuildIntrinsicOp(unsigned IID, SDValue Op, SelectionDAG &DAG, const SDLoc &dl, EVT DestVT=MVT::Other)
BuildIntrinsicOp - Return a unary operator intrinsic node with the specified intrinsic ID.
static bool isConsecutiveLSLoc(SDValue Loc, EVT VT, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static bool canConvertToVcmpequb(SDValue &LHS, SDValue &RHS, bool IsPPC64)
static void StoreTailCallArgumentsToStackSlot(SelectionDAG &DAG, SDValue Chain, const SmallVectorImpl< TailCallArgumentInfo > &TailCallArgs, SmallVectorImpl< SDValue > &MemOpChains, const SDLoc &dl)
StoreTailCallArgumentsToStackSlot - Stores arguments to their stack slot.
static cl::opt< bool > UseAbsoluteJumpTables("ppc-use-absolute-jumptables", cl::desc("use absolute jump tables on ppc"), cl::Hidden)
static void setXFormForUnalignedFI(SDValue N, unsigned Flags, PPC::AddrMode &Mode)
static cl::opt< unsigned > PPCMinimumBitTestCmps("ppc-min-bit-test-cmps", cl::init(3), cl::Hidden, cl::desc("Set minimum of largest number of comparisons to use bit test for " "switch on PPC."))
static void getMaxByValAlign(Type *Ty, Align &MaxAlign, Align MaxMaxAlign)
getMaxByValAlign - Helper for getByValTypeAlignment to determine the desired ByVal argument alignment...
static bool isConsecutiveLS(SDNode *N, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static bool isVMerge(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned LHSStart, unsigned RHSStart)
isVMerge - Common function, used to match vmrg* shuffles.
static void getLabelAccessInfo(bool IsPIC, const PPCSubtarget &Subtarget, unsigned &HiOpFlags, unsigned &LoOpFlags, const GlobalValue *GV=nullptr)
Return true if we should reference labels using a PICBase, set the HiOpFlags and LoOpFlags to the tar...
cl::opt< bool > DisableAutoPairedVecSt("disable-auto-paired-vec-st", cl::desc("disable automatically generated 32byte paired vector stores"), cl::init(true), cl::Hidden)
static void buildCallOperands(SmallVectorImpl< SDValue > &Ops, PPCTargetLowering::CallFlags CFlags, const SDLoc &dl, SelectionDAG &DAG, SmallVector< std::pair< unsigned, SDValue >, 8 > &RegsToPass, SDValue Glue, SDValue Chain, SDValue &Callee, int SPDiff, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableInnermostLoopAlign32("disable-ppc-innermost-loop-align32", cl::desc("don't always align innermost loop to 32 bytes on ppc"), cl::Hidden)
static bool usePartialVectorLoads(SDNode *N, const PPCSubtarget &ST)
Returns true if we should use a direct load into vector instruction (such as lxsd or lfd),...
static SDValue getDataClassTest(SDValue Op, FPClassTest Mask, const SDLoc &Dl, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void fixupShuffleMaskForPermutedSToV(SmallVectorImpl< int > &ShuffV, int LHSFirstElt, int LHSLastElt, int RHSFirstElt, int RHSLastElt, int HalfVec, unsigned LHSNumValidElts, unsigned RHSNumValidElts, const PPCSubtarget &Subtarget)
static SDValue AdjustLength(SDValue Val, unsigned Bits, bool Left, SelectionDAG &DAG)
static cl::opt< bool > DisableSCO("disable-ppc-sco", cl::desc("disable sibling call optimization on ppc"), cl::Hidden)
static std::optional< LXVKQPattern > getPatternInfo(const APInt &FullVal)
static void fixupFuncForFI(SelectionDAG &DAG, int FrameIdx, EVT VT)
static cl::opt< bool > DisablePPCPreinc("disable-ppc-preinc", cl::desc("disable preincrement load/store generation on PPC"), cl::Hidden)
static SDValue ConvertSETCCToXori(SDNode *N, SelectionDAG &DAG)
static Intrinsic::ID getIntrinsicForAtomicRMWBinOp128(AtomicRMWInst::BinOp BinOp)
static SDValue convertFPToInt(SDValue Op, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static unsigned CalculateStackSlotSize(EVT ArgVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotSize - Calculates the size reserved for this argument on the stack.
static int CalculateTailCallSPDiff(SelectionDAG &DAG, bool isTailCall, unsigned ParamSize)
CalculateTailCallSPDiff - Get the amount the stack pointer has to be adjusted to accommodate the argu...
static Instruction * callIntrinsic(IRBuilderBase &Builder, Intrinsic::ID Id)
static void prepareIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, const SDLoc &dl)
static SDValue combineSELECT_CCBitFloor(SDNode *N, SelectionDAG &DAG)
Optimize the bitfloor(X) pattern for PowerPC.
static SDValue LowerLabelRef(SDValue HiPart, SDValue LoPart, bool isPIC, SelectionDAG &DAG)
static SDValue isScalarToVec(SDValue Op)
static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl)
static cl::opt< bool > DisablePerfectShuffle("ppc-disable-perfect-shuffle", cl::desc("disable vector permute decomposition"), cl::init(true), cl::Hidden)
bool isValidMtVsrBmi(APInt &BitMask, BuildVectorSDNode &BVN, bool IsLittleEndian)
static MachineBasicBlock * emitSelect(MachineInstr &MI, MachineBasicBlock *BB, const TargetInstrInfo *TII, const PPCSubtarget &Subtarget)
Emit SELECT instruction, using ISEL if available, otherwise use branch-based control flow.
static bool getVectorCompareInfo(SDValue Intrin, int &CompareOpc, bool &isDot, const PPCSubtarget &Subtarget)
getVectorCompareInfo - Given an intrinsic, return false if it is not a vector comparison.
static unsigned invertFMAOpcode(unsigned Opc)
static SDValue combineADDToSUB(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static const SDValue * getNormalLoadInput(const SDValue &Op, bool &IsPermuted)
static bool canConvertSETCCToXori(SDNode *N)
static cl::opt< unsigned > PPCMinimumJumpTableEntries("ppc-min-jump-table-entries", cl::init(64), cl::Hidden, cl::desc("Set minimum number of entries to use a jump table on PPC"))
static bool isValidSplatLoad(const PPCSubtarget &Subtarget, const SDValue &Op, unsigned &Opcode)
static SDValue ConvertCarryValueToCarryFlag(EVT SumType, SDValue Value, SelectionDAG &DAG, const PPCSubtarget &STI)
static SDValue convertIntToFP(SDValue Op, SDValue Src, SelectionDAG &DAG, const PPCSubtarget &Subtarget, SDValue Chain=SDValue())
static void PrepareTailCall(SelectionDAG &DAG, SDValue &InGlue, SDValue &Chain, const SDLoc &dl, int SPDiff, unsigned NumBytes, SDValue LROp, SDValue FPOp, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
static SDValue EmitTailCallStoreFPAndRetAddr(SelectionDAG &DAG, SDValue Chain, SDValue OldRetAddr, SDValue OldFP, int SPDiff, const SDLoc &dl)
EmitTailCallStoreFPAndRetAddr - Move the frame pointer and return address to the appropriate stack sl...
static SDValue BuildVSLDOI(SDValue LHS, SDValue RHS, unsigned Amt, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
BuildVSLDOI - Return a VECTOR_SHUFFLE that is a vsldoi of the specified amount.
static void createAtomicLoopBlocks(MachineFunction *F, MachineBasicBlock *BB, MachineBasicBlock *&loop1MBB, MachineBasicBlock *&loop2MBB, MachineBasicBlock *&exitMBB, MachineInstr &MI, MachineFunction::iterator It)
Helper function to create basic blocks for atomic compare-and-swap.
static SDValue combineBVZEXTLOAD(SDNode *N, SelectionDAG &DAG)
static SDValue combineZextSetccWithZero(SDNode *N, SelectionDAG &DAG)
static SDValue truncateScalarIntegerArg(ISD::ArgFlagsTy Flags, EVT ValVT, SelectionDAG &DAG, SDValue ArgValue, MVT LocVT, const SDLoc &dl)
static void computeFlagsForAddressComputation(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Given a node, compute flags that are used for address computation when selecting load and store instr...
static MachineBasicBlock * emitAtomicCmpSwapHardware(MachineInstr &MI, MachineBasicBlock *BB, const TargetInstrInfo *TII, const PPCSubtarget &Subtarget)
Emit hardware-supported atomic compare-and-swap for I32/I64 and I8/I16 with partword atomic support.
SDValue convertTwoLoadsAndCmpToVCMPEQUB(SelectionDAG &DAG, SDNode *N, const SDLoc &DL)
static SDValue getOutputChainFromCallSeq(SDValue CallSeqStart)
static bool CalculateStackSlotUsed(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize, unsigned LinkageSize, unsigned ParamAreaSize, unsigned &ArgOffset, unsigned &AvailableFPRs, unsigned &AvailableVRs)
CalculateStackSlotUsed - Return whether this argument will use its stack slot (instead of being passe...
static void signExtendOperandIfUnknown(MachineInstr &MI, MachineBasicBlock *BB, unsigned OpIdx, bool IsByte, const PPCInstrInfo *TII)
static cl::opt< unsigned > PPCAIXTLSModelOptUseIEForLDLimit("ppc-aix-shared-lib-tls-model-opt-limit", cl::init(1), cl::Hidden, cl::desc("Set inclusive limit count of TLS local-dynamic access(es) in a " "function to use initial-exec"))
static unsigned getPPCStrictOpcode(unsigned Opc)
static void prepareDescriptorIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, SDValue CallSeqStart, const CallBase *CB, const SDLoc &dl, bool hasNest, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableP10StoreForward("disable-p10-store-forward", cl::desc("disable P10 store forward-friendly conversion"), cl::Hidden, cl::init(false))
static bool isXXBRShuffleMaskHelper(ShuffleVectorSDNode *N, int Width)
static bool isFunctionGlobalAddress(const GlobalValue *CalleeGV)
static bool isSplatBV(SDValue Op)
static SDValue combineBVOfVecSExt(SDNode *N, SelectionDAG &DAG)
static cl::opt< bool > DisableILPPref("disable-ppc-ilp-pref", cl::desc("disable setting the node scheduling preference to ILP on PPC"), cl::Hidden)
static bool isNByteElemShuffleMask(ShuffleVectorSDNode *, unsigned, int)
Check that the mask is shuffling N byte elements.
static SDValue combineBVOfConsecutiveLoads(SDNode *N, SelectionDAG &DAG)
Reduce the number of loads when building a vector.
static bool isValidPCRelNode(SDValue N)
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
pre isel intrinsic Pre ISel Intrinsic Lowering
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
SI optimize exec mask operations pre RA
static const MCExpr * MaskShift(const MCExpr *Val, uint32_t Mask, uint32_t Shift, MCContext &Ctx)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG, const SparcSubtarget *Subtarget)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
This file describes how to lower LLVM code to machine code.
static 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 BranchProbability getOne()
static BranchProbability getZero()
A "pseudo-class" with methods for operating on BUILD_VECTORs.
LLVM_ABI bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
CCState - This class holds information needed while lowering arguments and return values.
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP)
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
int64_t getLocMemOffset() const
unsigned getValNo() const
static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool isStrictFP() const
Determine if the call requires strict floating point semantics.
CallingConv::ID getCallingConv() const
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
Value * getCalledOperand() const
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
unsigned arg_size() const
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
This class represents a function call, abstracting a target machine's calling convention.
ConstantFP - Floating Point Values [float, double].
const Constant * getConstVal() const
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
int64_t getSExtValue() const
This is an important base class in LLVM.
uint64_t getNumOperands() const
A parsed version of the target data layout string in and methods for querying it.
bool isLittleEndian() const
Layout endianness...
LLVM_ABI unsigned getLargestLegalIntTypeSizeInBits() const
Returns the size of largest legal integer type size, or 0 if none are set.
LLVM_ABI IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
LLVM_ABI Align getABITypeAlign(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
LLVM_ABI TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
AttributeList getAttributes() const
Return the attribute list for this Function.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Type * getReturnType() const
Returns the type of the ret val.
const Argument * const_arg_iterator
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
int64_t getOffset() const
unsigned getTargetFlags() const
const GlobalValue * getGlobal() const
LLVM_ABI const GlobalObject * getAliaseeObject() const
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
void setThreadLocalMode(ThreadLocalMode Val)
bool hasHiddenVisibility() const
LLVM_ABI StringRef getSection() const
Module * getParent()
Get the module that this global value is contained inside of...
bool isStrongDefinitionForLinker() const
Returns true if this global's definition will be the one chosen by the linker.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
Type * getValueType() const
bool hasProtectedVisibility() const
Common base class shared among various IRBuilders.
LLVM_ABI bool hasAtomicLoad() const LLVM_READONLY
Return true if this atomic instruction loads from memory.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
This is an important class for using LLVM in a threaded context.
Base class for LoadSDNode and StoreSDNode.
Tracks which library functions to use for a particular subtarget.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
TypeSize getValue() const
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
Wrapper class representing physical registers. Should be passed by value.
MCSymbolXCOFF * getQualNameSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
@ INVALID_SIMPLE_VALUE_TYPE
uint64_t getScalarSizeInBits() const
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
void setCallFrameSize(unsigned N)
Set the call frame size on entry to this basic block.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
LLVM_ABI int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setHasTailCall(bool V=true)
void setReturnAddressIsTaken(bool s)
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool hasVAStart() const
Returns true if the function calls the llvm.va_start intrinsic.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
MCSymbol * getPICBaseSymbol() const
getPICBaseSymbol - Return a function-local symbol to represent the PIC base.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
@ EK_LabelDifference32
EK_LabelDifference32 - Each entry is the address of the block minus the address of the jump table.
A description of a memory reference used in the backend.
LocationSize getSize() const
Return the size in bytes of the memory reference.
AtomicOrdering getFailureOrdering() const
For cmpxchg atomic operations, return the atomic ordering requirements when store does not occur.
SyncScope::ID getSyncScopeID() const
Returns the synchronization scope ID for this memory operation.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
AtomicOrdering getSuccessOrdering() const
Return the atomic ordering requirements for this memory operation.
const MachinePointerInfo & getPointerInfo() const
Flags getFlags() const
Return the raw flags of the source value,.
LLVM_ABI Align getAlign() const
Return the minimum known alignment in bytes of the actual memory reference.
AAMDNodes getAAInfo() const
Return the AA tags for the memory reference.
MachineOperand class - Representation of each machine instruction operand.
static MachineOperand CreateImm(int64_t Val)
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLVM_ABI Register getLiveInVirtReg(MCRegister PReg) const
getLiveInVirtReg - If PReg is a live-in physical register, return the corresponding live-in virtual r...
bool use_empty(Register RegNo) const
use_empty - Return true if there are no instructions using the specified register.
This SDNode is used for target intrinsics that touch memory and need an associated MachineMemOperand.
This is an abstract virtual class for memory operations.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getBasePtr() const
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
uint64_t getReturnSaveOffset() const
getReturnSaveOffset - Return the previous frame offset to save the return address.
unsigned getLinkageSize() const
getLinkageSize - Return the size of the PowerPC ABI linkage area.
uint64_t getTOCSaveOffset() const
getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
void setVarArgsNumFPR(unsigned Num)
void setReturnAddrSaveIndex(int idx)
bool isAIXFuncUseTLSIEForLD() const
int getReturnAddrSaveIndex() const
unsigned getVarArgsNumFPR() const
void setAIXFuncUseTLSIEForLD()
int getFramePointerSaveIndex() const
void setVarArgsNumGPR(unsigned Num)
void appendParameterType(ParamType Type)
int getVarArgsFrameIndex() const
void setLRStoreRequired()
bool isAIXFuncTLSModelOptInitDone() const
void setTailCallSPDelta(int size)
void setAIXFuncTLSModelOptInitDone()
bool isLRStoreRequired() const
void setMinReservedArea(unsigned size)
unsigned getVarArgsNumGPR() const
unsigned getMinReservedArea() const
void setVarArgsStackOffset(int Offset)
void setVarArgsFrameIndex(int Index)
void addLiveInAttr(Register VReg, ISD::ArgFlagsTy Flags)
This function associates attributes for each live-in virtual register.
int getVarArgsStackOffset() const
void setFramePointerSaveIndex(int Idx)
static bool hasPCRelFlag(unsigned TF)
bool is32BitELFABI() const
unsigned descriptorTOCAnchorOffset() const
MVT getScalarIntVT() const
MCRegister getGlueCodeDescriptorRegister() const
const PPCFrameLowering * getFrameLowering() const override
bool isUsingPCRelativeCalls() const
bool usesFunctionDescriptors() const
True if the ABI is descriptor based.
MCRegister getEnvironmentPointerRegister() const
bool isLittleEndian() const
MCRegister getTOCPointerRegister() const
MCRegister getStackPointerRegister() const
bool is64BitELFABI() const
const PPCTargetMachine & getTargetMachine() const
const PPCRegisterInfo * getRegisterInfo() const override
unsigned descriptorEnvironmentPointerOffset() const
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
CCAssignFn * ccAssignFnForCall(CallingConv::ID CC, bool Return, bool IsVarArg) const
bool isTruncateFree(Type *Ty1, Type *Ty2) const override
isTruncateFree - Return true if it's free to truncate a value of type Ty1 to type Ty2.
Value * emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI, Value *AlignedAddr, Value *Incr, Value *Mask, Value *ShiftAmt, AtomicOrdering Ord) const override
Perform a masked atomicrmw using a target-specific intrinsic.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
bool isFPExtFree(EVT DestVT, EVT SrcVT) const override
Return true if an fpext operation is free (for instance, because single-precision floating-point numb...
PPC::AddrMode SelectForceXFormMode(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
SelectForceXFormMode - Given the specified address, force it to be represented as an indexed [r+r] op...
Instruction * emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
TargetLowering::AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
bool hasInlineStackProbe(const MachineFunction &MF) const override
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
bool supportsTailCallFor(const CallBase *CB) const
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
MachineBasicBlock * emitProbedAlloca(MachineInstr &MI, MachineBasicBlock *MBB) const
bool isZExtFree(SDValue Val, EVT VT2) const override
Return true if zero-extending the specific node Val to type VT2 is free (either because it's implicit...
SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const override
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
bool SelectAddressRegImm(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign EncodingAlignment) const
SelectAddressRegImm - Returns true if the address N can be represented by a base register plus a sign...
SDValue expandVSXLoadForLE(SDNode *N, DAGCombinerInfo &DCI) const
bool splitValueIntoRegisterParts(SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts, unsigned NumParts, MVT PartVT, std::optional< CallingConv::ID > CC) const override
Target-specific splitting of values into parts that fit a register storing a legal type.
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
LowerAsmOperandForConstraint - Lower the specified operand into the Ops vector.
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
ReplaceNodeResults - Replace the results of node with an illegal result type with new values built ou...
bool hasMultipleConditionRegisters(EVT VT) const override
Does the target have multiple (allocatable) condition registers that can be used to store the results...
Align getByValTypeAlignment(Type *Ty, const DataLayout &DL) const override
getByValTypeAlignment - Return the desired alignment for ByVal aggregate function arguments in the ca...
bool SelectAddressRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG, MaybeAlign EncodingAlignment=std::nullopt) const
SelectAddressRegReg - Given the specified addressed, check to see if it can be more efficiently repre...
SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, SmallVectorImpl< SDNode * > &Created) const override
Targets may override this function to provide custom SDIV lowering for power-of-2 denominators.
Value * emitStoreConditional(IRBuilderBase &Builder, Value *Val, Value *Addr, AtomicOrdering Ord) const override
Perform a store-conditional operation to Addr.
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
bool SelectAddressRegRegOnly(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressRegRegOnly - Given the specified addressed, force it to be represented as an indexed [r+...
bool useSoftFloat() const override
SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const override
Returns relocation base for the given PIC jumptable.
TargetLowering::AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(const AtomicCmpXchgInst *AI) const override
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
Value * emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder, AtomicCmpXchgInst *CI, Value *AlignedAddr, Value *CmpVal, Value *NewVal, Value *Mask, AtomicOrdering Ord) const override
Perform a masked cmpxchg using a target-specific intrinsic.
ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
bool enableAggressiveFMAFusion(EVT VT) const override
Return true if target always benefits from combining into FMA for a given value type.
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
bool decomposeMulByConstant(LLVMContext &Context, EVT VT, SDValue C) const override
Return true if it is profitable to transform an integer multiplication-by-constant into simpler opera...
void getTgtMemIntrinsic(SmallVectorImpl< IntrinsicInfo > &Infos, const CallBase &I, MachineFunction &MF, unsigned Intrinsic) const override
Given an intrinsic, checks if on the target the intrinsic will need to map to a MemIntrinsicNode (tou...
unsigned getJumpTableEncoding() const override
Return the entry encoding for a jump table in the current function.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
isLegalAddressingMode - Return true if the addressing mode represented by AM is legal for this target...
bool preferIncOfAddToSubOfNot(EVT VT) const override
These two forms are equivalent: sub y, (xor x, -1) add (add x, 1), y The variant with two add's is IR...
bool shouldConvertConstantLoadToIntImm(const APInt &Imm, Type *Ty) const override
Returns true if it is beneficial to convert a load of a constant to just the constant itself.
const MCPhysReg * getScratchRegisters(CallingConv::ID CC) const override
Returns a 0 terminated array of registers that can be safely used as scratch registers.
bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const override
getPreIndexedAddressParts - returns true by value, base pointer and offset pointer and addressing mod...
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo, const LibcallLoweringInfo *LibcallLowering) const override
createFastISel - This method returns a target-specific FastISel object, or null if the target does no...
bool isProfitableToHoist(Instruction *I) const override
isProfitableToHoist - Check if it is profitable to hoist instruction I to its dominator block.
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
Value * emitLoadLinked(IRBuilderBase &Builder, Type *ValueTy, Value *Addr, AtomicOrdering Ord) const override
Perform a load-linked operation on Addr, returning a "Value *" with the corresponding pointee type.
ConstraintType getConstraintType(StringRef Constraint) const override
getConstraintType - Given a constraint, return the type of constraint it is for this target.
const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const override
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
bool shallExtractConstSplatVectorElementToStore(Type *VectorTy, unsigned ElemSizeInBits, unsigned &Index) const override
Return true if the target shall perform extract vector element and store given that the vector is kno...
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op, const AttributeList &FuncAttributes) const override
It returns EVT::Other if the type should be determined using generic target-independent logic.
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
SDValue expandVSXStoreForLE(SDNode *N, DAGCombinerInfo &DCI) const
void CollectTargetIntrinsicOperands(const CallInst &I, SmallVectorImpl< SDValue > &Ops, SelectionDAG &DAG) const override
unsigned getStackProbeSize(const MachineFunction &MF) const
PPCTargetLowering(const PPCTargetMachine &TM, const PPCSubtarget &STI)
bool useLoadStackGuardNode(const Module &M) const override
Override to support customized stack guard loading.
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster than a pair of fmul and fadd i...
MachineBasicBlock * EmitAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned BinOpcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const override
Is unaligned memory access allowed for the given type, and is it fast relative to software emulation.
bool shouldExpandBuildVectorWithShuffles(EVT VT, unsigned DefinedValues) const override
bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
Similar to the 16-bit case but for instructions that take a 34-bit displacement field (prefixed loads...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
bool isJumpTableRelative() const override
Register getExceptionPointerRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
PPC::AddrMode SelectOptimalAddrMode(const SDNode *Parent, SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign Align) const
SelectOptimalAddrMode - Based on a node N and it's Parent (a MemSDNode), compute the address flags of...
bool SelectAddressPCRel(SDValue N, SDValue &Base) const
SelectAddressPCRel - Represent the specified address as pc relative to be represented as [pc+imm].
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the ISD::SETCC ValueType
bool SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressEVXRegReg - Given the specified addressed, check to see if it can be more efficiently re...
bool isLegalICmpImmediate(int64_t Imm) const override
isLegalICmpImmediate - Return true if the specified immediate is legal icmp immediate,...
MachineBasicBlock * EmitPartwordAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned Opcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
bool isAccessedAsGotIndirect(SDValue N) const
Align getPrefLoopAlignment(MachineLoop *ML) const override
Return the preferred loop alignment.
bool shouldInlineQuadwordAtomics() const
Instruction * emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Inserts in the IR a target-specific intrinsic specifying a fence.
bool isLegalAddImmediate(int64_t Imm) const override
isLegalAddImmediate - Return true if the specified immediate is legal add immediate,...
Common code between 32-bit and 64-bit PowerPC targets.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Wrapper class representing virtual and physical registers.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
This class provides iterator support for SDUse operands that use a specific SDNode.
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
LLVM_ABI void dump() const
Dump this node, for debugging.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
iterator_range< value_op_iterator > op_values() const
iterator_range< use_iterator > uses()
SDNodeFlags getFlags() const
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
user_iterator user_begin() const
Provide iteration support to walk over all users of an SDNode.
static use_iterator use_end()
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
bool isMachineOpcode() const
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getMachineOpcode() const
unsigned getOpcode() const
unsigned getNumOperands() const
static SectionKind getMetadata()
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
LLVM_ABI SDValue getStackArgumentTokenFactor(SDValue Chain)
Compute a TokenFactor to force all the incoming stack arguments to be loaded from the stack.
const TargetSubtargetInfo & getSubtarget() const
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDValue getFreeze(SDValue V)
Return a freeze using the SDLoc of the value operand.
LLVM_ABI SDValue makeEquivalentMemoryOrdering(SDValue OldChain, SDValue NewMemOpChain)
If an existing load has uses of its chain, create a token factor node with that chain and the new mem...
LLVM_ABI SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, LocationSize Size=LocationSize::precise(0), const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
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...
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
LLVM_ABI Align getEVTAlign(EVT MemoryVT) const
Compute the default alignment value for the given type.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
LLVM_ABI SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
static constexpr unsigned MaxRecursionDepth
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
LLVM_ABI bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
LLVM_ABI SDValue getTokenFactor(const SDLoc &DL, SmallVectorImpl< SDValue > &Vals)
Creates a new TokenFactor containing Vals.
LLVM_ABI bool areNonVolatileConsecutiveLoads(LoadSDNode *LD, LoadSDNode *Base, unsigned Bytes, int Dist) const
Return true if loads are next to each other and can be merged.
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
LLVM_ABI SDValue getMDNode(const MDNode *MD)
Return an MDNodeSDNode which holds an MDNode.
LLVM_ABI void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
LLVM_ABI SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV)
Returns an ISD::VECTOR_SHUFFLE node semantically equivalent to the shuffle node in input but with swa...
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
LLVM_ABI SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
LLVM_ABI SDValue getBoolExtOrTrunc(SDValue Op, const SDLoc &SL, EVT VT, EVT OpVT)
Convert Op, which must be of integer type, to the integer type VT, by using an extension appropriate ...
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
LLVM_ABI SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
LLVM_ABI SDValue getBoolConstant(bool V, const SDLoc &DL, EVT VT, EVT OpVT)
Create a true or false constant of type VT using the target's BooleanContent for type OpVT.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
LLVM_ABI bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
LLVM_ABI SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVM_ABI SDValue getCondCode(ISD::CondCode Cond)
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
LLVM_ABI SDValue getMCSymbol(MCSymbol *Sym, EVT VT)
LLVM_ABI SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
LLVM_ABI std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
LLVM_ABI SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
int getMaskElt(unsigned Idx) const
ArrayRef< int > getMask() const
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getValue() const
Represent a constant reference to a string, i.e.
constexpr size_t size() const
Get the string size.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
Class to represent struct types.
Information about stack frame layout on the target.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
virtual bool isShuffleMaskLegal(ArrayRef< int >, EVT) const
Targets can use this to indicate that they only support some VECTOR_SHUFFLE operations,...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual bool shouldExpandBuildVectorWithShuffles(EVT, unsigned DefinedValues) const
void setMinimumBitTestCmps(unsigned Val)
Set the minimum of largest of number of comparisons to generate BitTest.
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
MachineBasicBlock * emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const
Replace/modify any TargetFrameIndex operands with a targte-dependent sequence of memory operands that...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
virtual AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *RMW) const
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
void setMinStackArgumentAlignment(Align Alignment)
Set the minimum stack alignment of an argument.
MVT getVectorIdxTy(const DataLayout &DL) const
Returns the type to be used for the index operand of: ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT...
const TargetMachine & getTargetMachine() const
unsigned MaxLoadsPerMemcmp
Specify maximum number of load instructions per memcmp call.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
void setIndexedLoadAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed load does or does not work with the specified type and indicate w...
void setPrefLoopAlignment(Align Alignment)
Set the target's preferred loop alignment.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Sched::Preference getSchedulingPreference() const
Return target scheduling preference.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
bool isOperationCustom(unsigned Op, EVT VT) const
Return true if the operation uses custom lowering, regardless of whether the type is legal or not.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
bool hasBigEndianPartOrdering(EVT VT, const DataLayout &DL) const
When splitting a value of the specified type into parts, does the Lo or Hi part come first?
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL) const
Returns the type for the shift amount of a shift opcode.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
virtual Align getPrefLoopAlignment(MachineLoop *ML=nullptr) const
Return the preferred loop alignment.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
void setIndexedStoreAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed store does or does not work with the specified type and indicate ...
virtual bool isJumpTableRelative() const
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setMinimumJumpTableEntries(unsigned Val)
Indicate the minimum number of blocks to generate jump tables.
void setPartialReduceMLAAction(unsigned Opc, MVT AccVT, MVT InputVT, LegalizeAction Action)
Indicate how a PARTIAL_REDUCE_U/SMLA node with Acc type AccVT and Input type InputVT should be treate...
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
unsigned MaxLoadsPerMemcmpOptSize
Likewise for functions with the OptSize attribute.
void setMinCmpXchgSizeInBits(unsigned SizeInBits)
Sets the minimum cmpxchg or ll/sc size supported by the backend.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
unsigned GatherAllAliasesMaxDepth
Depth that GatherAllAliases should continue looking for chain dependencies when trying to find a more...
NegatibleCost
Enum that specifies when a float negation is beneficial.
virtual bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const
Returns true if arguments should be sign-extended in lib calls.
std::vector< ArgListEntry > ArgListTy
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
void setJumpIsExpensive(bool isExpensive=true)
Tells the code generator not to expand logic operations on comparison predicates into separate sequen...
virtual MCSymbol * getFunctionEntryPointSymbol(const GlobalValue *Func, const TargetMachine &TM) const
If supported, return the function entry point symbol.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
SDValue lowerCmpEqZeroToCtlzSrl(SDValue Op, SelectionDAG &DAG) const
void softenSetCCOperands(SelectionDAG &DAG, EVT VT, SDValue &NewLHS, SDValue &NewRHS, ISD::CondCode &CCCode, const SDLoc &DL, const SDValue OldLHS, const SDValue OldRHS) const
Soften the operands of a comparison.
SDValue getCheaperNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, unsigned Depth=0) const
This is the helper function to return the newly negated expression only when the cost is cheaper.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool isPositionIndependent() const
virtual SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const
Returns relocation base for the given PIC jumptable.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
TargetLowering(const TargetLowering &)=delete
bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node, SDValue &Chain) const
Check whether a given call node is in tail position within its function.
virtual SDValue getSqrtResultForDenormInput(SDValue Operand, SelectionDAG &DAG) const
Return a target-dependent result if the input operand is not suitable for use with a square root esti...
virtual bool useLoadStackGuardNode(const Module &M) const
If this function returns true, SelectionDAGBuilder emits a LOAD_STACK_GUARD node when it is lowering ...
virtual unsigned combineRepeatedFPDivisors() const
Indicate whether this target prefers to combine FDIVs with the same divisor.
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
virtual SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG, const DenormalMode &Mode, SDNodeFlags Flags={}) const
Return a target-dependent comparison result if the input operand is suitable for use with a square ro...
virtual bool isGAPlusOffset(SDNode *N, const GlobalValue *&GA, int64_t &Offset) const
Returns true (and the GlobalValue and the offset) if the node is a GlobalAddress + offset.
virtual unsigned getJumpTableEncoding() const
Return the entry encoding for a jump table in the current function.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::LibcallImpl LibcallImpl, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
Primary interface to the complete machine description for the target machine.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
const STC & getSubtarget(const Function &F) const
This method returns a pointer to the specified type of TargetSubtargetInfo.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
virtual TargetLoweringObjectFile * getObjFileLowering() const
Reloc::Model getRelocationModel() const
Returns the code generation relocation model.
bool shouldAssumeDSOLocal(const GlobalValue *GV) const
CodeModel::Model getCodeModel() const
Returns the code model.
bool getFunctionSections() const
Return true if functions should be emitted into their own section, corresponding to -ffunction-sectio...
unsigned PPCGenScalarMASSEntries
Enables scalar MASS conversions.
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
LLVM_ABI bool isEmptyTy() const
Return true if this type is empty, that is, it has no elements or all of its elements are empty.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
@ FloatTyID
32-bit floating point type
@ DoubleTyID
64-bit floating point type
@ FP128TyID
128-bit floating point type (112-bit significand)
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isFunctionTy() const
True if this is an instance of FunctionType.
bool isIntegerTy() const
True if this is an instance of IntegerType.
A Use represents the edge between a Value definition and its users.
User * getUser() const
Returns the User that contains this Use.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI bool isConstantSplatVectorAllOnes(const SDNode *N, bool BuildVectorOnly=false)
Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where all of the elements are ~0 ...
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
@ PARTIAL_REDUCE_SMLA
PARTIAL_REDUCE_[U|S]MLA(Accumulator, Input1, Input2) The partial reduction nodes sign or zero extend ...
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ BSWAP
Byte Swap and Counting operators.
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ INIT_TRAMPOLINE
INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ SET_ROUNDING
Set rounding mode.
@ SIGN_EXTEND
Conversion operators.
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ BR
Control flow instructions. These all have token chains.
@ PREFETCH
PREFETCH - This corresponds to a prefetch intrinsic.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ SSUBO
Same for subtraction.
@ BR_JT
BR_JT - Jumptable branch.
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ GET_ROUNDING
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimumNumber or maximumNumber on two values,...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ INLINEASM_BR
INLINEASM_BR - Branching version of inline asm. Used by asm-goto.
@ EH_DWARF_CFA
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA),...
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ INLINEASM
INLINEASM - Represents an inline asm block.
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ CALLSEQ_START
CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of a call sequence,...
@ GET_DYNAMIC_AREA_OFFSET
GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of the most recent dynamic alloca.
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ ADJUST_TRAMPOLINE
ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
bool isEXTLoad(const SDNode *N)
Returns true if the specified node is a EXTLOAD.
LLVM_ABI bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
bool isSEXTLoad(const SDNode *N)
Returns true if the specified node is a SEXTLOAD.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
bool isUnsignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs an unsigned comparison when used with intege...
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
This namespace contains an enum with a value for every intrinsic/builtin function known by LLVM.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
@ MO_TLSLDM_FLAG
MO_TLSLDM_FLAG - on AIX the ML relocation type is only valid for a reference to a TOC symbol from the...
@ MO_PIC_LO_FLAG
MO_PIC_LO_FLAG = MO_PIC_FLAG | MO_LO.
@ MO_TPREL_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TPREL_FLAG.
@ MO_GOT_TPREL_PCREL_FLAG
MO_GOT_TPREL_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_GOT_PCREL_FLAG
MO_GOT_PCREL_FLAG = MO_PCREL_FLAG | MO_GOT_FLAG.
@ MO_TLSGDM_FLAG
MO_TLSGDM_FLAG - If this bit is set the symbol reference is relative to the region handle of TLS Gene...
@ MO_PCREL_FLAG
MO_PCREL_FLAG - If this bit is set, the symbol reference is relative to the current instruction addre...
@ MO_TLSLD_FLAG
MO_TLSLD_FLAG - If this bit is set the symbol reference is relative to TLS Local Dynamic model.
@ MO_TLS_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TLS.
@ MO_PLT
On PPC, the 12 bits are not enough for all target operand flags.
@ MO_TLS
Symbol for VK_TLS fixup attached to an ADD instruction.
@ MO_TPREL_FLAG
MO_TPREL_FLAG - If this bit is set, the symbol reference is relative to the thread pointer and the sy...
@ MO_LO
MO_LO, MO_HA - lo16(symbol) and ha16(symbol)
@ MO_GOT_TLSLD_PCREL_FLAG
MO_GOT_TLSLD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_HA_FLAG
MO_PIC_HA_FLAG = MO_PIC_FLAG | MO_HA.
@ MO_TLSGD_FLAG
MO_TLSGD_FLAG - If this bit is set the symbol reference is relative to TLS General Dynamic model for ...
@ MO_GOT_TLSGD_PCREL_FLAG
MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_FLAG
MO_PIC_FLAG - If this bit is set, the symbol reference is relative to the function's picbase,...
@ MFOCRF
R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
@ VADD_SPLAT
VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded during instruction selection to optimi...
@ PPC32_PICGOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
@ SRA_ADDZE
The combination of sra[wd]i and addze used to implemented signed integer division by a power of 2.
Define some predicates that are used for node matching.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
SDValue get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG)
get_VSPLTI_elt - If this is a build_vector of constants which can be formed by using a vspltis[bhw] i...
bool isXXBRDShuffleMask(ShuffleVectorSDNode *N)
isXXBRDShuffleMask - Return true if this is a shuffle mask suitable for a XXBRD instruction.
bool isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for a VRGH* instruction with the ...
bool isVPKUDUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUDUMShuffleMask - Return true if this is the shuffle mask for a VPKUDUM instruction.
bool isVMRGEOShuffleMask(ShuffleVectorSDNode *N, bool CheckEven, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGEOShuffleMask - Return true if this is a shuffle mask suitable for a VMRGEW or VMRGOW instructi...
bool isXXBRQShuffleMask(ShuffleVectorSDNode *N)
isXXBRQShuffleMask - Return true if this is a shuffle mask suitable for a XXBRQ instruction.
bool isXXBRWShuffleMask(ShuffleVectorSDNode *N)
isXXBRWShuffleMask - Return true if this is a shuffle mask suitable for a XXBRW instruction.
bool isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXPERMDIShuffleMask - Return true if this is a shuffle mask suitable for a XXPERMDI instruction.
bool isXXBRHShuffleMask(ShuffleVectorSDNode *N)
isXXBRHShuffleMask - Return true if this is a shuffle mask suitable for a XXBRH instruction.
unsigned getSplatIdxForPPCMnemonics(SDNode *N, unsigned EltSize, SelectionDAG &DAG)
getSplatIdxForPPCMnemonics - Return the splat index as a value that is appropriate for PPC mnemonics ...
bool isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXSLDWIShuffleMask - Return true if this is a shuffle mask suitable for a XXSLDWI instruction.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo, const LibcallLoweringInfo *LibcallLowering)
int isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift amount, otherwise return -1.
bool isVMRGLShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for a VRGL* instruction with the ...
bool isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, unsigned &InsertAtByte, bool &Swap, bool IsLE)
isXXINSERTWMask - Return true if this VECTOR_SHUFFLE can be handled by the XXINSERTW instruction intr...
bool isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize)
isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand specifies a splat of a singl...
bool isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a VPKUWUM instruction.
bool isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a VPKUHUM instruction.
Invariant opcodes: All instruction sets have these as their low opcodes.
@ XTY_ER
External reference.
initializer< Ty > init(const Ty &Val)
constexpr uint64_t PointerSize
aarch64 pointer size.
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
NodeAddr< NodeBase * > Node
NodeAddr< FuncNode * > Func
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
static bool isIndirectCall(const MachineInstr &MI)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool checkConvertToNonDenormSingle(APFloat &ArgAPFloat)
LLVM_ABI void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
LLVM_ABI SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
bool isIntS16Immediate(SDNode *N, int16_t &Imm)
isIntS16Immediate - This method tests to see if the node is either a 32-bit or 64-bit immediate,...
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
static bool isRunOfOnes64(uint64_t Val, unsigned &MB, unsigned &ME)
bool isa_and_nonnull(const Y &Val)
bool RetCC_PPC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
bool CC_PPC64_ELF(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
unsigned M1(unsigned Val)
bool isReleaseOrStronger(AtomicOrdering AO)
auto dyn_cast_or_null(const Y &Val)
constexpr bool has_single_bit(T Value) noexcept
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
bool convertToNonDenormSingle(APInt &ArgAPInt)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
bool CC_PPC32_SVR4_ByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
bool CC_PPC32_SVR4(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
constexpr 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.
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...
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
LLVM_ABI bool isPhysRegUsedAfter(Register Reg, MachineBasicBlock::iterator MBI)
Check if physical register Reg is used after MBI.
unsigned M0(unsigned Val)
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
bool isAcquireOrStronger(AtomicOrdering AO)
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
constexpr unsigned BitWidth
bool CC_PPC32_SVR4_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME)
Returns true iff Val consists of one contiguous run of 1s with any number of 0s on either side.
@ Increment
Incrementally increasing token ID.
@ Enabled
Convert any .debug_str_offsets tables to DWARF64 if needed.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
static const unsigned PerfectShuffleTable[6561+1]
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This is used by foldLoadsRecursive() to capture a Root Load node which is of type or(load,...
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Represent subnormal handling kind for floating point instruction inputs and outputs.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
LLVM_ABI std::string getEVTString() const
This function returns value type as a string, e.g. "i32".
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
unsigned getByValSize() const
void setByValSize(unsigned S)
Align getNonZeroByValAlign() const
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
bool isConstant() const
Returns true if we know the value of all bits.
void resetAll()
Resets the known state of all bits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Structure that collects some common arguments that get passed around between the functions for call l...
const CallingConv::ID CallConv
These are IR-level optimization flags that may be propagated to SDNodes.
void setNoFPExcept(bool b)
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
CallLoweringInfo & setIsPostTypeLegalization(bool Value=true)
CallLoweringInfo & setLibCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setZExtResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setTailCall(bool Value=true)
CallLoweringInfo & setSExtResult(bool Value=true)
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
CallLoweringInfo & setChain(SDValue InChain)
bool isBeforeLegalizeOps() const
bool isAfterLegalizeDAG() const
LLVM_ABI void AddToWorklist(SDNode *N)
bool isBeforeLegalize() const
LLVM_ABI SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)
This structure is used to pass arguments to makeLibCall function.