49#include "llvm/IR/IntrinsicsPowerPC.h"
72#define DEBUG_TYPE "ppc-isel"
73#define PASS_NAME "PowerPC DAG->DAG Pattern Instruction Selection"
76 "Number of (sext(setcc)) nodes expanded into GPR sequence.");
78 "Number of (zext(setcc)) nodes expanded into GPR sequence.");
80 "Number of sign extensions for compare inputs added.");
82 "Number of zero extensions for compare inputs added.");
84 "Number of logical ops on i1 values calculated in GPR.");
86 "Number of compares not eliminated as they have non-extending uses.");
88 "Number of compares lowered to setb.");
96 cl::desc(
"use aggressive ppc isel for bit permutations"),
99 "ppc-bit-perm-rewriter-stress-rotates",
100 cl::desc(
"stress rotate selection in aggressive ppc isel for "
105 "ppc-use-branch-hint",
cl::init(
true),
106 cl::desc(
"Enable static hinting of branches on ppc"),
111 cl::desc(
"Enable tls optimization peephole"),
120 cl::desc(
"Specify the types of comparisons to emit GPR-only code for."),
126 "Only comparisons where inputs don't need [sz]ext."),
129 "Only i32 comparisons with zext result."),
131 "Only i64 comparisons with zext result."),
134 "Only i32 comparisons with sext result."),
136 "Only i64 comparisons with sext result.")));
147 unsigned GlobalBaseReg = 0;
150 PPCDAGToDAGISel() =
delete;
160 if (Subtarget->hasROPProtect()) {
165 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
174 void PreprocessISelDAG()
override;
175 void PostprocessISelDAG()
override;
179 inline SDValue getI16Imm(
unsigned Imm,
const SDLoc &dl) {
180 return CurDAG->getTargetConstant(
Imm, dl, MVT::i16);
185 inline SDValue getI32Imm(
unsigned Imm,
const SDLoc &dl) {
186 return CurDAG->getTargetConstant(
Imm, dl, MVT::i32);
192 return CurDAG->getTargetConstant(
Imm, dl, MVT::i64);
196 inline SDValue getSmallIPtrImm(int64_t
Imm,
const SDLoc &dl) {
197 return CurDAG->getSignedTargetConstant(
198 Imm, dl, PPCLowering->getPointerTy(CurDAG->getDataLayout()));
203 static bool isRotateAndMask(SDNode *
N,
unsigned Mask,
bool isShiftMask,
204 unsigned &SH,
unsigned &MB,
unsigned &ME);
208 SDNode *getGlobalBaseReg();
210 void selectFrameIndex(SDNode *SN, SDNode *
N, int64_t
Offset = 0);
214 void Select(SDNode *
N)
override;
216 bool tryBitfieldInsert(SDNode *
N);
217 bool tryBitPermutation(SDNode *
N);
218 bool tryIntCompareInGPR(SDNode *
N);
223 bool tryTLSXFormLoad(LoadSDNode *
N);
227 bool tryTLSXFormStore(StoreSDNode *
N);
250 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
258 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
266 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
274 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
281 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
289 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
297 return PPCLowering->SelectForceXFormMode(
N, Disp,
Base, *CurDAG) ==
308 return PPCLowering->SelectAddressRegReg(
N,
Base, Index, *CurDAG,
319 return PPCLowering->SelectAddressRegReg(
N,
Base, Index, *CurDAG,
330 return PPCLowering->SelectAddressRegReg(
N,
Base, Index, *CurDAG,
337 return PPCLowering->SelectAddressRegRegOnly(
N,
Base, Index, *CurDAG);
346 return PPCLowering->SelectAddressRegImm(
N, Disp,
Base, *CurDAG,
354 return PPCLowering->SelectAddressRegImm(
N, Disp,
Base, *CurDAG,
Align(4));
361 return PPCLowering->SelectAddressRegImm(
N, Disp,
Base, *CurDAG,
369 return PPCLowering->SelectAddressRegImm34(
N, Disp,
Base, *CurDAG);
379 return PPCLowering->SelectAddressPCRel(
N,
Base);
387 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
389 std::vector<SDValue> &OutOps)
override {
390 switch(ConstraintID) {
392 errs() <<
"ConstraintID: "
395 case InlineAsm::ConstraintCode::es:
396 case InlineAsm::ConstraintCode::m:
397 case InlineAsm::ConstraintCode::o:
398 case InlineAsm::ConstraintCode::Q:
399 case InlineAsm::ConstraintCode::Z:
400 case InlineAsm::ConstraintCode::Zy:
403 const TargetRegisterInfo *
TRI = Subtarget->getRegisterInfo();
406 SDValue RC = CurDAG->getTargetConstant(TRC->
getID(), dl, MVT::i32);
408 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
409 dl,
Op.getValueType(),
412 OutOps.push_back(NewOp);
419#include "PPCGenDAGISel.inc"
422 bool trySETCC(SDNode *
N);
423 bool tryFoldSWTestBRCC(SDNode *
N);
424 bool trySelectLoopCountIntrinsic(SDNode *
N);
425 bool tryAsSingleRLDICL(SDNode *
N);
426 bool tryAsSingleRLDCL(SDNode *
N);
427 bool tryAsSingleRLDICR(SDNode *
N);
428 bool tryAsSingleRLWINM(SDNode *
N);
429 bool tryAsSingleRLWINM8(SDNode *
N);
430 bool tryAsSingleRLWIMI(SDNode *
N);
431 bool tryAsPairOfRLDICL(SDNode *
N);
432 bool tryAsSingleRLDIMI(SDNode *
N);
434 void PeepholePPC64();
435 void PeepholePPC64ZExt();
436 void PeepholeCROps();
439 void foldBoolExts(
SDValue &Res, SDNode *&
N);
441 bool AllUsersSelectZero(SDNode *
N);
442 void SwapAllSelectUsers(SDNode *
N);
444 bool isOffsetMultipleOf(SDNode *
N,
unsigned Val)
const;
445 void transferMemOperands(SDNode *
N, SDNode *Result);
451 explicit PPCDAGToDAGISelLegacy(PPCTargetMachine &tm,
453 : SelectionDAGISelLegacy(
454 ID, std::make_unique<PPCDAGToDAGISel>(tm, OptLevel)) {}
458char PPCDAGToDAGISelLegacy::ID = 0;
465SDNode *PPCDAGToDAGISel::getGlobalBaseReg() {
466 if (!GlobalBaseReg) {
474 if (PPCLowering->getPointerTy(CurDAG->getDataLayout()) == MVT::i32) {
477 if (!Subtarget->isSecurePlt() &&
487 TII.get(PPC::UpdateGBR), GlobalBaseReg)
493 RegInfo->createVirtualRegister(&PPC::GPRC_and_GPRC_NOR0RegClass);
513 return CurDAG->getRegister(GlobalBaseReg,
514 PPCLowering->getPointerTy(CurDAG->getDataLayout()))
554 if (
N->getOpcode() ==
ISD::Constant &&
N->getValueType(0) == MVT::i32) {
555 Imm =
N->getAsZExtVal();
564 if (
N->getOpcode() ==
ISD::Constant &&
N->getValueType(0) == MVT::i64) {
565 Imm =
N->getAsZExtVal();
616 if (std::max(TProb, FProb) / Threshold < std::min(TProb, FProb))
620 <<
"::" << BB->
getName() <<
"'\n"
621 <<
" -> " <<
TBB->getName() <<
": " << TProb <<
"\n"
622 <<
" -> " << FBB->
getName() <<
": " << FProb <<
"\n");
638 return N->getOpcode() ==
Opc
645 SDValue TFI = CurDAG->getTargetFrameIndex(FI,
N->getValueType(0));
646 unsigned Opc =
N->getValueType(0) == MVT::i32 ? PPC::ADDI : PPC::ADDI8;
648 CurDAG->SelectNodeTo(SN,
Opc,
N->getValueType(0), TFI,
649 getSmallIPtrImm(
Offset, dl));
651 ReplaceNode(SN, CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0), TFI,
652 getSmallIPtrImm(
Offset, dl)));
655bool PPCDAGToDAGISel::isRotateAndMask(SDNode *
N,
unsigned Mask,
656 bool isShiftMask,
unsigned &SH,
657 unsigned &MB,
unsigned &ME) {
660 if (
N->getValueType(0) != MVT::i32)
664 unsigned Indeterminant = ~0;
665 unsigned Opcode =
N->getOpcode();
666 if (
N->getNumOperands() != 2 ||
672 if (isShiftMask)
Mask =
Mask << Shift;
674 Indeterminant = ~(0xFFFFFFFFu << Shift);
677 if (isShiftMask)
Mask =
Mask >> Shift;
679 Indeterminant = ~(0xFFFFFFFFu >> Shift);
689 if (Mask && !(Mask & Indeterminant)) {
701 Base.getOpcode() == PPCISD::ADD_TLS &&
702 "Only expecting the ADD_TLS instruction to acquire the thread pointer!");
706 unsigned ADDTLSOp1Opcode = ADDTLSOp1.getOpcode();
715 if (ADDTLSOp1Opcode == PPCISD::LD_GOT_TPREL_L)
720 if (LD && LD->getBasePtr().getOpcode() == PPCISD::MAT_PCREL_ADDR)
726 if (ADDTLSOp1Opcode == PPCISD::GET_TPOINTER)
751 if (
Base.getOpcode() != PPCISD::ADD_TLS)
753 for (
auto *ADDTLSUse :
Base.getNode()->users()) {
758 if (LD->getSrcValueOffset() != 0 || !LD->getOffset().isUndef())
761 if (ST->getSrcValueOffset() != 0 || !ST->getOffset().isUndef())
767 if (
Base.getOperand(1).getOpcode() == PPCISD::TLS_LOCAL_EXEC_MAT_ADDR)
776bool PPCDAGToDAGISel::tryTLSXFormStore(StoreSDNode *ST) {
782 EVT MemVT =
ST->getMemoryVT();
783 EVT RegVT =
ST->getValue().getValueType();
790 Opcode = (RegVT == MVT::i32) ? PPC::STBXTLS_32 : PPC::STBXTLS;
794 Opcode = (RegVT == MVT::i32) ? PPC::STHXTLS_32 : PPC::STHXTLS;
798 Opcode = (RegVT == MVT::i32) ? PPC::STWXTLS_32 : PPC::STWXTLS;
802 Opcode = PPC::STDXTLS;
806 Opcode = PPC::STFSXTLS;
810 Opcode = PPC::STFDXTLS;
815 SDVTList VTs =
ST->getVTList();
818 SDNode *MN = CurDAG->getMachineNode(Opcode, dl, VTs,
Ops);
819 transferMemOperands(ST, MN);
824bool PPCDAGToDAGISel::tryTLSXFormLoad(LoadSDNode *LD) {
830 EVT MemVT =
LD->getMemoryVT();
831 EVT RegVT =
LD->getValueType(0);
838 Opcode = (RegVT == MVT::i32) ? PPC::LBZXTLS_32 : PPC::LBZXTLS;
842 if (RegVT == MVT::i32)
843 Opcode = isSExt ? PPC::LHAXTLS_32 : PPC::LHZXTLS_32;
845 Opcode = isSExt ? PPC::LHAXTLS : PPC::LHZXTLS;
849 if (RegVT == MVT::i32)
850 Opcode = isSExt ? PPC::LWAXTLS_32 : PPC::LWZXTLS_32;
852 Opcode = isSExt ? PPC::LWAXTLS : PPC::LWZXTLS;
856 Opcode = PPC::LDXTLS;
860 Opcode = PPC::LFSXTLS;
864 Opcode = PPC::LFDXTLS;
869 SDVTList VTs =
LD->getVTList();
871 SDNode *MN = CurDAG->getMachineNode(Opcode, dl, VTs,
Ops);
872 transferMemOperands(LD, MN);
879bool PPCDAGToDAGISel::tryBitfieldInsert(SDNode *
N) {
890 KnownBits LKnown = CurDAG->computeKnownBits(Op0);
891 KnownBits RKnown = CurDAG->computeKnownBits(Op1);
896 if ((TargetMask | InsertMask) == 0xFFFFFFFF) {
899 unsigned Value, SH = 0;
900 TargetMask = ~TargetMask;
901 InsertMask = ~InsertMask;
935 KnownBits MKnown = CurDAG->computeKnownBits(Op1.
getOperand(1));
949 SDValue Ops[] = { Op0, Op1, getI32Imm(SH, dl), getI32Imm(MB, dl),
951 ReplaceNode(
N, CurDAG->getMachineNode(PPC::RLWIMI, dl, MVT::i32,
Ops));
959 unsigned MaxTruncation = 0;
966 User->isMachineOpcode() ?
User->getMachineOpcode() :
User->getOpcode();
970 if (
User->isMachineOpcode())
972 MaxTruncation = std::max(MaxTruncation,
973 (
unsigned)
User->getValueType(0).getSizeInBits());
976 if (
User->isMachineOpcode())
982 MaxTruncation = std::max(MaxTruncation, MemVTSize);
991 MaxTruncation = std::max(MaxTruncation, 32u);
999 MaxTruncation = std::max(MaxTruncation, 16u);
1007 MaxTruncation = std::max(MaxTruncation, 8u);
1011 return MaxTruncation;
1019 if ((HiTZ + LoLZ) >= Num)
1033 SDNode *Result =
nullptr;
1036 auto getI32Imm = [CurDAG, dl](
unsigned Imm) {
1050 if (TZ > 15 && (LZ > 32 || LO > 32))
1052 getI32Imm((
Imm >> 16) & 0xffff));
1056 assert(LZ < 64 &&
"Unexpected leading zeros here.");
1063 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
1064 Result = CurDAG->
getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
1066 getI32Imm(
Imm & 0xffff));
1074 if ((LZ + FO + TZ) > 48) {
1076 getI32Imm((
Imm >> TZ) & 0xffff));
1078 getI32Imm(TZ), getI32Imm(LZ));
1095 if ((LZ + TO) > 48) {
1099 assert(LZ <= 32 &&
"Unexpected shift value.");
1101 getI32Imm((
Imm >> (48 - LZ) & 0xffff)));
1103 getI32Imm(48 - LZ), getI32Imm(LZ));
1121 if ((LZ + FO + TO) > 48) {
1123 getI32Imm((
Imm >> TO) & 0xffff));
1125 getI32Imm(TO), getI32Imm(LZ));
1131 if (LZ == 32 && ((Lo32 & 0x8000) == 0)) {
1133 getI32Imm(Lo32 & 0xffff));
1135 getI32Imm(Lo32 >> 16));
1159 getI32Imm(RotImm & 0xffff));
1161 getI32Imm(Shift), getI32Imm(0));
1168 uint64_t ImmHi16 = (Lo32 >> 16) & 0xffff;
1172 CurDAG->
getMachineNode(PPC::LI8, dl, MVT::i64, getI32Imm(ImmLo16));
1175 CurDAG->
getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(ImmHi16));
1179 CurDAG->
getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(ImmHi16));
1181 SDValue(Result, 0), getI32Imm(ImmLo16));
1198 if ((LZ + FO + TZ) > 32) {
1200 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
1201 Result = CurDAG->
getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
1203 getI32Imm((
Imm >> TZ) & 0xffff));
1205 getI32Imm(TZ), getI32Imm(LZ));
1212 if ((LZ + TO) > 32) {
1216 assert(LZ <= 32 &&
"Unexpected shift value.");
1218 getI32Imm((
Imm >> (48 - LZ)) & 0xffff));
1220 getI32Imm((
Imm >> (32 - LZ)) & 0xffff));
1222 getI32Imm(32 - LZ), getI32Imm(LZ));
1230 if ((LZ + FO + TO) > 32) {
1232 getI32Imm((
Imm >> (TO + 16)) & 0xffff));
1234 getI32Imm((
Imm >> TO) & 0xffff));
1236 getI32Imm(TO), getI32Imm(LZ));
1248 uint64_t ImmHi16 = (RotImm >> 16) & 0xffff;
1249 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
1250 Result = CurDAG->
getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
1252 getI32Imm(RotImm & 0xffff));
1254 getI32Imm(Shift), getI32Imm(0));
1275 auto getI32Imm = [CurDAG, dl](
unsigned Imm) {
1294 SDNode *Result =
nullptr;
1301 if ((LZ + FO + TZ) > 30) {
1305 getI64Imm(Extended.getZExtValue()));
1307 getI32Imm(TZ), getI32Imm(LZ));
1323 if ((LZ + TO) > 30) {
1324 APInt SignedInt34 =
APInt(34, (
Imm >> (30 - LZ)) & 0x3ffffffff);
1327 getI64Imm(Extended.getZExtValue()));
1329 getI32Imm(30 - LZ), getI32Imm(LZ));
1336 if ((LZ + FO + TO) > 30) {
1340 getI64Imm(Extended.getZExtValue()));
1342 getI32Imm(TO), getI32Imm(LZ));
1354 for (
unsigned Shift = 0; Shift < 63; ++Shift) {
1358 CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(RotImm));
1360 SDValue(Result, 0), getI32Imm(Shift),
1368 Result = CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(Hi32));
1378 CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(Hi32));
1380 CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(Lo32));
1387 unsigned *InstCnt =
nullptr) {
1388 unsigned InstCntDirect = 0;
1399 if (Subtarget.hasPrefixInstrs() && InstCntDirect != 1) {
1400 unsigned InstCntDirectP = 0;
1407 if (ResultP && (!Result || InstCntDirectP < InstCntDirect)) {
1409 *InstCnt = InstCntDirectP;
1416 *InstCnt = InstCntDirect;
1419 auto getI32Imm = [CurDAG, dl](
unsigned Imm) {
1428 if (Hi16OfLo32 && Lo16OfLo32) {
1431 bool IsSelected =
false;
1435 CurDAG->
getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(Hi16));
1437 SDValue(Result, 0), getI32Imm(Lo16));
1443 if (Hi16OfHi32 == Lo16OfHi32 && Lo16OfHi32 == Lo16OfLo32) {
1445 Result = getSplat(Hi16OfLo32, Lo16OfLo32);
1450 }
else if (Hi16OfHi32 == Hi16OfLo32 && Hi16OfLo32 == Lo16OfLo32) {
1452 Result = getSplat(Hi16OfHi32, Lo16OfHi32);
1455 getI32Imm(16), getI32Imm(31)};
1457 }
else if (Lo16OfHi32 == Lo16OfLo32 && Hi16OfLo32 == Lo16OfLo32) {
1459 Result = getSplat(Hi16OfHi32, Lo16OfHi32);
1462 getI32Imm(0), getI32Imm(15)};
1465 if (IsSelected ==
true) {
1478 SDValue(Result, 0), getI32Imm(Hi16OfLo32));
1483 getI32Imm(Lo16OfLo32));
1487 *InstCnt = InstCntDirect;
1496 int64_t
Imm =
N->getAsZExtVal();
1508class BitPermutationSelector {
1523 VariableKnownToBeZero
1526 ValueBit(
SDValue V,
unsigned I, Kind K = Variable)
1527 :
V(
V), Idx(
I), K(K) {}
1528 ValueBit(Kind K = Variable) : Idx(UINT32_MAX), K(K) {}
1531 return K == ConstZero || K == VariableKnownToBeZero;
1534 bool hasValue()
const {
1535 return K == Variable || K == VariableKnownToBeZero;
1539 assert(hasValue() &&
"Cannot get the value of a constant bit");
1543 unsigned getValueBitIndex()
const {
1544 assert(hasValue() &&
"Cannot get the value bit index of a constant bit");
1553 unsigned StartIdx, EndIdx;
1563 bool Repl32Coalesced;
1565 BitGroup(
SDValue V,
unsigned R,
unsigned S,
unsigned E)
1566 :
V(
V), RLAmt(
R), StartIdx(S), EndIdx(
E), Repl32(
false), Repl32CR(
false),
1567 Repl32Coalesced(
false) {
1568 LLVM_DEBUG(
dbgs() <<
"\tbit group for " <<
V.getNode() <<
" RLAmt = " << R
1569 <<
" [" << S <<
", " <<
E <<
"]\n");
1575 struct ValueRotInfo {
1577 unsigned RLAmt = std::numeric_limits<unsigned>::max();
1578 unsigned NumGroups = 0;
1579 unsigned FirstGroupStartIdx = std::numeric_limits<unsigned>::max();
1580 bool Repl32 =
false;
1582 ValueRotInfo() =
default;
1590 if (Repl32 <
Other.Repl32)
1592 else if (Repl32 >
Other.Repl32)
1594 else if (NumGroups >
Other.NumGroups)
1596 else if (NumGroups <
Other.NumGroups)
1598 else if (RLAmt == 0 &&
Other.RLAmt != 0)
1600 else if (RLAmt != 0 &&
Other.RLAmt == 0)
1602 else if (FirstGroupStartIdx <
Other.FirstGroupStartIdx)
1608 using ValueBitsMemoizedValue = std::pair<bool, SmallVector<ValueBit, 64>>;
1609 using ValueBitsMemoizer =
1610 DenseMap<SDValue, std::unique_ptr<ValueBitsMemoizedValue>>;
1611 ValueBitsMemoizer Memoizer;
1617 std::pair<bool, SmallVector<ValueBit, 64> *> getValueBits(
SDValue V,
1619 auto &ValueEntry = Memoizer[
V];
1621 return std::make_pair(ValueEntry->first, &ValueEntry->second);
1622 ValueEntry.reset(
new ValueBitsMemoizedValue());
1623 bool &Interesting = ValueEntry->first;
1625 Bits.resize(NumBits);
1627 switch (
V.getOpcode()) {
1632 unsigned RotAmt =
V.getConstantOperandVal(1) & (NumBits - 1);
1634 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1636 for (
unsigned i = 0; i < NumBits; ++i)
1637 Bits[i] = LHSBits[i < RotAmt ? i + (NumBits - RotAmt) : i - RotAmt];
1639 return std::make_pair(Interesting =
true, &Bits);
1646 unsigned ShiftAmt =
V.getConstantOperandVal(1) & ((NumBits << 1) - 1);
1648 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1650 if (ShiftAmt >= NumBits) {
1651 for (
unsigned i = 0; i < NumBits; ++i)
1652 Bits[i] = ValueBit(ValueBit::ConstZero);
1654 for (
unsigned i = ShiftAmt; i < NumBits; ++i)
1655 Bits[i] = LHSBits[i - ShiftAmt];
1656 for (
unsigned i = 0; i < ShiftAmt; ++i)
1657 Bits[i] = ValueBit(ValueBit::ConstZero);
1660 return std::make_pair(Interesting =
true, &Bits);
1667 unsigned ShiftAmt =
V.getConstantOperandVal(1) & ((NumBits << 1) - 1);
1669 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1671 if (ShiftAmt >= NumBits) {
1672 for (
unsigned i = 0; i < NumBits; ++i)
1673 Bits[i] = ValueBit(ValueBit::ConstZero);
1675 for (
unsigned i = 0; i < NumBits - ShiftAmt; ++i)
1676 Bits[i] = LHSBits[i + ShiftAmt];
1677 for (
unsigned i = NumBits - ShiftAmt; i < NumBits; ++i)
1678 Bits[i] = ValueBit(ValueBit::ConstZero);
1681 return std::make_pair(Interesting =
true, &Bits);
1693 std::tie(Interesting, LHSBits) = getValueBits(
V.getOperand(0), NumBits);
1695 for (
unsigned i = 0; i < NumBits; ++i)
1696 if (((Mask >> i) & 1) == 1)
1697 Bits[i] = (*LHSBits)[i];
1701 if ((*LHSBits)[i].
isZero())
1702 Bits[i] = (*LHSBits)[i];
1704 Bits[i] = ValueBit(ValueBit::ConstZero);
1707 return std::make_pair(Interesting, &Bits);
1711 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1712 const auto &RHSBits = *getValueBits(
V.getOperand(1), NumBits).second;
1714 bool AllDisjoint =
true;
1716 unsigned LastIdx = 0;
1717 for (
unsigned i = 0; i < NumBits; ++i) {
1725 if (LHSBits[i].hasValue() && LHSBits[i].
getValue() == LastVal &&
1726 LHSBits[i].getValueBitIndex() == LastIdx + 1)
1727 Bits[i] = LHSBits[i];
1728 else if (RHSBits[i].hasValue() && RHSBits[i].
getValue() == LastVal &&
1729 RHSBits[i].getValueBitIndex() == LastIdx + 1)
1730 Bits[i] = RHSBits[i];
1732 Bits[i] = ValueBit(ValueBit::ConstZero);
1734 else if (LHSBits[i].
isZero())
1735 Bits[i] = RHSBits[i];
1736 else if (RHSBits[i].
isZero())
1737 Bits[i] = LHSBits[i];
1739 AllDisjoint =
false;
1743 if (Bits[i].hasValue()) {
1744 LastVal =
Bits[i].getValue();
1745 LastIdx =
Bits[i].getValueBitIndex();
1748 if (LastVal) LastVal =
SDValue();
1756 return std::make_pair(Interesting =
true, &Bits);
1760 if (
V.getValueType() != MVT::i64 ||
1761 V.getOperand(0).getValueType() != MVT::i32)
1765 const unsigned NumOperandBits = 32;
1766 std::tie(Interesting, LHSBits) = getValueBits(
V.getOperand(0),
1769 for (
unsigned i = 0; i < NumOperandBits; ++i)
1770 Bits[i] = (*LHSBits)[i];
1772 for (
unsigned i = NumOperandBits; i < NumBits; ++i)
1773 Bits[i] = ValueBit(ValueBit::ConstZero);
1775 return std::make_pair(Interesting, &Bits);
1778 EVT
FromType =
V.getOperand(0).getValueType();
1779 EVT ToType =
V.getValueType();
1781 if (FromType != MVT::i64 || ToType != MVT::i32)
1783 const unsigned NumAllBits =
FromType.getSizeInBits();
1785 std::tie(Interesting, InBits) = getValueBits(
V.getOperand(0),
1791 bool UseUpper32bit =
false;
1792 for (
unsigned i = 0; i < NumValidBits; ++i)
1793 if ((*InBits)[i].hasValue() && (*InBits)[i].getValueBitIndex() >= 32) {
1794 UseUpper32bit =
true;
1800 for (
unsigned i = 0; i < NumValidBits; ++i)
1801 Bits[i] = (*InBits)[i];
1803 return std::make_pair(Interesting, &Bits);
1809 std::tie(Interesting, LHSBits) = getValueBits(
V.getOperand(0),
1813 const unsigned NumValidBits =
FromType.getSizeInBits();
1814 for (
unsigned i = 0; i < NumValidBits; ++i)
1815 Bits[i] = (*LHSBits)[i];
1819 for (
unsigned i = NumValidBits; i < NumBits; ++i)
1820 Bits[i] = (*LHSBits)[i].hasValue()
1821 ? ValueBit((*LHSBits)[i].
getValue(),
1822 (*LHSBits)[i].getValueBitIndex(),
1823 ValueBit::VariableKnownToBeZero)
1824 : ValueBit(ValueBit::ConstZero);
1826 return std::make_pair(Interesting, &Bits);
1831 EVT VT =
LD->getMemoryVT();
1834 for (
unsigned i = 0; i < NumValidBits; ++i)
1835 Bits[i] = ValueBit(V, i);
1838 for (
unsigned i = NumValidBits; i < NumBits; ++i)
1839 Bits[i] = ValueBit(V, i, ValueBit::VariableKnownToBeZero);
1843 return std::make_pair(Interesting =
false, &Bits);
1848 for (
unsigned i = 0; i < NumBits; ++i)
1849 Bits[i] = ValueBit(V, i);
1851 return std::make_pair(Interesting =
false, &Bits);
1856 void computeRotationAmounts() {
1858 RLAmt.resize(
Bits.size());
1859 for (
unsigned i = 0; i <
Bits.size(); ++i)
1860 if (Bits[i].hasValue()) {
1861 unsigned VBI =
Bits[i].getValueBitIndex();
1865 RLAmt[i] =
Bits.size() - (VBI - i);
1866 }
else if (Bits[i].
isZero()) {
1868 RLAmt[i] = UINT32_MAX;
1877 void collectBitGroups(
bool LateMask) {
1880 unsigned LastRLAmt = RLAmt[0];
1882 unsigned LastGroupStartIdx = 0;
1883 bool IsGroupOfZeros = !
Bits[LastGroupStartIdx].hasValue();
1884 for (
unsigned i = 1; i <
Bits.size(); ++i) {
1885 unsigned ThisRLAmt = RLAmt[i];
1887 if (LateMask && !ThisValue) {
1888 ThisValue = LastValue;
1889 ThisRLAmt = LastRLAmt;
1892 if (BitGroups.empty())
1893 LastGroupStartIdx = 0;
1900 if (IsGroupOfZeros && Bits[i].
isZero())
1905 if (ThisRLAmt == LastRLAmt && ThisValue == LastValue)
1908 if (!(IsGroupOfZeros && ThisValue && !Bits[i].
isZero()))
1912 BitGroups.push_back(BitGroup(LastValue, LastRLAmt, LastGroupStartIdx,
1914 LastRLAmt = ThisRLAmt;
1915 LastValue = ThisValue;
1916 LastGroupStartIdx = i;
1917 IsGroupOfZeros = !
Bits[LastGroupStartIdx].hasValue();
1920 BitGroups.push_back(BitGroup(LastValue, LastRLAmt, LastGroupStartIdx,
1923 if (BitGroups.empty())
1927 if (BitGroups.size() > 1) {
1931 if (BitGroups[0].StartIdx == 0 &&
1932 BitGroups[BitGroups.size()-1].EndIdx ==
Bits.size()-1 &&
1933 BitGroups[0].V == BitGroups[BitGroups.size()-1].V &&
1934 BitGroups[0].RLAmt == BitGroups[BitGroups.size()-1].RLAmt) {
1935 LLVM_DEBUG(
dbgs() <<
"\tcombining final bit group with initial one\n");
1936 BitGroups[BitGroups.size()-1].EndIdx = BitGroups[0].EndIdx;
1937 BitGroups.erase(BitGroups.begin());
1947 void collectValueRotInfo() {
1950 for (
auto &BG : BitGroups) {
1951 unsigned RLAmtKey = BG.RLAmt + (BG.Repl32 ? 64 : 0);
1952 ValueRotInfo &VRI = ValueRots[std::make_pair(BG.V, RLAmtKey)];
1954 VRI.RLAmt = BG.RLAmt;
1955 VRI.Repl32 = BG.Repl32;
1957 VRI.FirstGroupStartIdx = std::min(VRI.FirstGroupStartIdx, BG.StartIdx);
1962 ValueRotsVec.clear();
1963 for (
auto &
I : ValueRots) {
1964 ValueRotsVec.push_back(
I.second);
1977 void assignRepl32BitGroups() {
1988 auto IsAllLow32 = [
this](BitGroup & BG) {
1989 if (BG.StartIdx <= BG.EndIdx) {
1990 for (
unsigned i = BG.StartIdx; i <= BG.EndIdx; ++i) {
1991 if (!Bits[i].hasValue())
1993 if (Bits[i].getValueBitIndex() >= 32)
1997 for (
unsigned i = BG.StartIdx; i <
Bits.size(); ++i) {
1998 if (!Bits[i].hasValue())
2000 if (Bits[i].getValueBitIndex() >= 32)
2003 for (
unsigned i = 0; i <= BG.EndIdx; ++i) {
2004 if (!Bits[i].hasValue())
2006 if (Bits[i].getValueBitIndex() >= 32)
2014 for (
auto &BG : BitGroups) {
2018 if (BG.RLAmt == 0) {
2019 auto PotentiallyMerged = [
this](BitGroup & BG) {
2020 for (
auto &BG2 : BitGroups)
2021 if (&BG != &BG2 && BG.V == BG2.V &&
2022 (BG2.RLAmt == 0 || BG2.RLAmt == 32))
2026 if (!PotentiallyMerged(BG))
2029 if (BG.StartIdx < 32 && BG.EndIdx < 32) {
2030 if (IsAllLow32(BG)) {
2031 if (BG.RLAmt >= 32) {
2039 << BG.V.getNode() <<
" RLAmt = " << BG.RLAmt <<
" ["
2040 << BG.StartIdx <<
", " << BG.EndIdx <<
"]\n");
2046 for (
auto I = BitGroups.begin();
I != BitGroups.end();) {
2049 auto IP = (
I == BitGroups.begin()) ?
2050 std::prev(BitGroups.end()) : std::prev(
I);
2051 if (
I->Repl32 && IP->Repl32 &&
I->V == IP->V &&
I->RLAmt == IP->RLAmt &&
2052 I->StartIdx == (IP->EndIdx + 1) % 64 &&
I != IP) {
2054 LLVM_DEBUG(dbgs() <<
"\tcombining 32-bit replicated bit group for "
2055 << I->V.getNode() <<
" RLAmt = " << I->RLAmt <<
" ["
2056 << I->StartIdx <<
", " << I->EndIdx
2057 <<
"] with group with range [" << IP->StartIdx <<
", "
2058 << IP->EndIdx <<
"]\n");
2060 IP->EndIdx = I->EndIdx;
2061 IP->Repl32CR = IP->Repl32CR || I->Repl32CR;
2062 IP->Repl32Coalesced = true;
2063 I = BitGroups.erase(I);
2072 if (I->StartIdx == 32 && I->EndIdx == 63) {
2073 assert(std::next(I) == BitGroups.end() &&
2074 "bit group ends at index 63 but there is another?");
2075 auto IN = BitGroups.begin();
2077 if (IP->Repl32 && IN->Repl32 && I->V == IP->V && I->V == IN->V &&
2078 (I->RLAmt % 32) == IP->RLAmt && (I->RLAmt % 32) == IN->RLAmt &&
2079 IP->EndIdx == 31 && IN->StartIdx == 0 && I != IP &&
2082 LLVM_DEBUG(dbgs() <<
"\tcombining bit group for " << I->V.getNode()
2083 <<
" RLAmt = " << I->RLAmt <<
" [" << I->StartIdx
2084 <<
", " << I->EndIdx
2085 <<
"] with 32-bit replicated groups with ranges ["
2086 << IP->StartIdx <<
", " << IP->EndIdx <<
"] and ["
2087 << IN->StartIdx <<
", " << IN->EndIdx <<
"]\n");
2095 IP->Repl32CR = IP->Repl32CR || I->RLAmt >= 32;
2096 IP->Repl32Coalesced = true;
2097 I = BitGroups.erase(I);
2102 IP->EndIdx = IN->EndIdx;
2103 IP->Repl32CR = IP->Repl32CR || IN->Repl32CR || I->RLAmt >= 32;
2104 IP->Repl32Coalesced = true;
2105 I = BitGroups.erase(I);
2106 BitGroups.erase(BitGroups.begin());
2120 SDValue getI32Imm(
unsigned Imm,
const SDLoc &dl) {
2121 return CurDAG->getTargetConstant(
Imm, dl, MVT::i32);
2126 for (
unsigned i = 0; i <
Bits.size(); ++i) {
2127 if (Bits[i].hasValue())
2129 Mask |= (UINT64_C(1) << i);
2140 if (
V.getValueSizeInBits() == 64)
2143 assert(
V.getValueSizeInBits() == 32);
2144 SDValue SubRegIdx = CurDAG->getTargetConstant(PPC::sub_32, dl, MVT::i32);
2145 SDValue ImDef =
SDValue(CurDAG->getMachineNode(PPC::IMPLICIT_DEF, dl,
2147 SDValue ExtVal =
SDValue(CurDAG->getMachineNode(PPC::INSERT_SUBREG, dl,
2154 if (
V.getValueSizeInBits() == 32)
2157 assert(
V.getValueSizeInBits() == 64);
2158 SDValue SubRegIdx = CurDAG->getTargetConstant(PPC::sub_32, dl, MVT::i32);
2159 SDValue SubVal =
SDValue(CurDAG->getMachineNode(PPC::EXTRACT_SUBREG, dl,
2160 MVT::i32, V, SubRegIdx), 0);
2167 void SelectAndParts32(
const SDLoc &dl,
SDValue &Res,
unsigned *InstCnt) {
2171 for (ValueRotInfo &VRI : ValueRotsVec) {
2173 for (
unsigned i = 0; i <
Bits.size(); ++i) {
2174 if (!Bits[i].hasValue() || Bits[i].
getValue() != VRI.V)
2176 if (RLAmt[i] != VRI.RLAmt)
2182 unsigned ANDIMask = (
Mask & UINT16_MAX), ANDISMask = Mask >> 16;
2183 assert((ANDIMask != 0 || ANDISMask != 0) &&
2184 "No set bits in mask for value bit groups");
2185 bool NeedsRotate = VRI.RLAmt != 0;
2201 unsigned NumAndInsts = (unsigned) NeedsRotate +
2202 (
unsigned) (ANDIMask != 0) +
2203 (
unsigned) (ANDISMask != 0) +
2204 (
unsigned) (ANDIMask != 0 && ANDISMask != 0) +
2205 (
unsigned) (bool) Res;
2207 LLVM_DEBUG(
dbgs() <<
"\t\trotation groups for " << VRI.V.getNode()
2208 <<
" RL: " << VRI.RLAmt <<
":"
2209 <<
"\n\t\t\tisel using masking: " << NumAndInsts
2210 <<
" using rotates: " << VRI.NumGroups <<
"\n");
2212 if (NumAndInsts >= VRI.NumGroups)
2217 if (InstCnt) *InstCnt += NumAndInsts;
2222 { TruncateToInt32(VRI.V, dl), getI32Imm(VRI.RLAmt, dl),
2223 getI32Imm(0, dl), getI32Imm(31, dl) };
2224 VRot =
SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32,
2227 VRot = TruncateToInt32(VRI.V, dl);
2232 ANDIVal =
SDValue(CurDAG->getMachineNode(PPC::ANDI_rec, dl, MVT::i32,
2233 VRot, getI32Imm(ANDIMask, dl)),
2237 SDValue(CurDAG->getMachineNode(PPC::ANDIS_rec, dl, MVT::i32, VRot,
2238 getI32Imm(ANDISMask, dl)),
2243 TotalVal = ANDISVal;
2247 TotalVal =
SDValue(CurDAG->getMachineNode(PPC::OR, dl, MVT::i32,
2248 ANDIVal, ANDISVal), 0);
2253 Res =
SDValue(CurDAG->getMachineNode(PPC::OR, dl, MVT::i32,
2258 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
2259 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt;
2265 SDNode *Select32(SDNode *
N,
bool LateMask,
unsigned *InstCnt) {
2269 if (InstCnt) *InstCnt = 0;
2272 SelectAndParts32(dl, Res, InstCnt);
2277 if ((!NeedMask || LateMask) && !Res) {
2278 ValueRotInfo &VRI = ValueRotsVec[0];
2280 if (InstCnt) *InstCnt += 1;
2282 { TruncateToInt32(VRI.V, dl), getI32Imm(VRI.RLAmt, dl),
2283 getI32Imm(0, dl), getI32Imm(31, dl) };
2284 Res =
SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32,
Ops),
2287 Res = TruncateToInt32(VRI.V, dl);
2291 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
2292 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt;
2296 if (InstCnt) *InstCnt += BitGroups.size();
2299 for (
auto &BG : BitGroups) {
2302 { TruncateToInt32(BG.V, dl), getI32Imm(BG.RLAmt, dl),
2303 getI32Imm(
Bits.size() - BG.EndIdx - 1, dl),
2304 getI32Imm(
Bits.size() - BG.StartIdx - 1, dl) };
2305 Res =
SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32,
Ops), 0);
2308 { Res, TruncateToInt32(BG.V, dl), getI32Imm(BG.RLAmt, dl),
2309 getI32Imm(
Bits.size() - BG.EndIdx - 1, dl),
2310 getI32Imm(
Bits.size() - BG.StartIdx - 1, dl) };
2311 Res =
SDValue(CurDAG->getMachineNode(PPC::RLWIMI, dl, MVT::i32,
Ops), 0);
2316 unsigned Mask = (unsigned) getZerosMask();
2318 unsigned ANDIMask = (
Mask & UINT16_MAX), ANDISMask = Mask >> 16;
2319 assert((ANDIMask != 0 || ANDISMask != 0) &&
2320 "No set bits in zeros mask?");
2322 if (InstCnt) *InstCnt += (unsigned) (ANDIMask != 0) +
2323 (unsigned) (ANDISMask != 0) +
2324 (unsigned) (ANDIMask != 0 && ANDISMask != 0);
2328 ANDIVal =
SDValue(CurDAG->getMachineNode(PPC::ANDI_rec, dl, MVT::i32,
2329 Res, getI32Imm(ANDIMask, dl)),
2333 SDValue(CurDAG->getMachineNode(PPC::ANDIS_rec, dl, MVT::i32, Res,
2334 getI32Imm(ANDISMask, dl)),
2342 Res =
SDValue(CurDAG->getMachineNode(PPC::OR, dl, MVT::i32,
2343 ANDIVal, ANDISVal), 0);
2349 unsigned SelectRotMask64Count(
unsigned RLAmt,
bool Repl32,
2350 unsigned MaskStart,
unsigned MaskEnd,
2354 unsigned InstMaskStart = 64 - MaskEnd - 1,
2355 InstMaskEnd = 64 - MaskStart - 1;
2360 if ((!IsIns && (InstMaskEnd == 63 || InstMaskStart == 0)) ||
2361 InstMaskEnd == 63 - RLAmt)
2369 SDValue SelectRotMask64(
SDValue V,
const SDLoc &dl,
unsigned RLAmt,
2370 bool Repl32,
unsigned MaskStart,
unsigned MaskEnd,
2371 unsigned *InstCnt =
nullptr) {
2374 unsigned InstMaskStart = 64 - MaskEnd - 1,
2375 InstMaskEnd = 64 - MaskStart - 1;
2377 if (InstCnt) *InstCnt += 1;
2383 assert(InstMaskStart >= 32 &&
"Mask cannot start out of range");
2384 assert(InstMaskEnd >= 32 &&
"Mask cannot end out of range");
2386 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2387 getI32Imm(InstMaskStart - 32, dl), getI32Imm(InstMaskEnd - 32, dl) };
2388 return SDValue(CurDAG->getMachineNode(PPC::RLWINM8, dl, MVT::i64,
2392 if (InstMaskEnd == 63) {
2394 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2395 getI32Imm(InstMaskStart, dl) };
2396 return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64,
Ops), 0);
2399 if (InstMaskStart == 0) {
2401 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2402 getI32Imm(InstMaskEnd, dl) };
2403 return SDValue(CurDAG->getMachineNode(PPC::RLDICR, dl, MVT::i64,
Ops), 0);
2406 if (InstMaskEnd == 63 - RLAmt) {
2408 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2409 getI32Imm(InstMaskStart, dl) };
2410 return SDValue(CurDAG->getMachineNode(PPC::RLDIC, dl, MVT::i64,
Ops), 0);
2419 if (InstCnt) *InstCnt += 1;
2422 unsigned RLAmt2 = MaskStart;
2425 unsigned RLAmt1 = (64 + RLAmt - RLAmt2) % 64;
2427 V = SelectRotMask64(V, dl, RLAmt1,
false, 0, 63);
2428 return SelectRotMask64(V, dl, RLAmt2,
false, MaskStart, MaskEnd);
2434 unsigned RLAmt,
bool Repl32,
unsigned MaskStart,
2435 unsigned MaskEnd,
unsigned *InstCnt =
nullptr) {
2438 unsigned InstMaskStart = 64 - MaskEnd - 1,
2439 InstMaskEnd = 64 - MaskStart - 1;
2441 if (InstCnt) *InstCnt += 1;
2447 assert(InstMaskStart >= 32 &&
"Mask cannot start out of range");
2448 assert(InstMaskEnd >= 32 &&
"Mask cannot end out of range");
2450 { ExtendToInt64(
Base, dl), ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2451 getI32Imm(InstMaskStart - 32, dl), getI32Imm(InstMaskEnd - 32, dl) };
2452 return SDValue(CurDAG->getMachineNode(PPC::RLWIMI8, dl, MVT::i64,
2456 if (InstMaskEnd == 63 - RLAmt) {
2458 { ExtendToInt64(
Base, dl), ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2459 getI32Imm(InstMaskStart, dl) };
2460 return SDValue(CurDAG->getMachineNode(PPC::RLDIMI, dl, MVT::i64,
Ops), 0);
2469 if (InstCnt) *InstCnt += 1;
2472 unsigned RLAmt2 = MaskStart;
2475 unsigned RLAmt1 = (64 + RLAmt - RLAmt2) % 64;
2477 V = SelectRotMask64(V, dl, RLAmt1,
false, 0, 63);
2478 return SelectRotMaskIns64(
Base, V, dl, RLAmt2,
false, MaskStart, MaskEnd);
2481 void SelectAndParts64(
const SDLoc &dl,
SDValue &Res,
unsigned *InstCnt) {
2494 for (ValueRotInfo &VRI : ValueRotsVec) {
2502 auto MatchingBG = [VRI](
const BitGroup &BG) {
2506 unsigned EffRLAmt = BG.RLAmt;
2507 if (!VRI.Repl32 && BG.Repl32) {
2508 if (BG.StartIdx < 32 && BG.EndIdx < 32 && BG.StartIdx <= BG.EndIdx &&
2509 !BG.Repl32Coalesced) {
2515 }
else if (VRI.Repl32 != BG.Repl32) {
2519 return VRI.RLAmt == EffRLAmt;
2522 for (
auto &BG : BitGroups) {
2523 if (!MatchingBG(BG))
2526 if (BG.StartIdx <= BG.EndIdx) {
2527 for (
unsigned i = BG.StartIdx; i <= BG.EndIdx; ++i)
2528 Mask |= (UINT64_C(1) << i);
2530 for (
unsigned i = BG.StartIdx; i <
Bits.size(); ++i)
2531 Mask |= (UINT64_C(1) << i);
2532 for (
unsigned i = 0; i <= BG.EndIdx; ++i)
2533 Mask |= (UINT64_C(1) << i);
2542 unsigned ANDIMask = (
Mask & UINT16_MAX),
2543 ANDISMask = (Mask >> 16) & UINT16_MAX;
2545 bool NeedsRotate = VRI.RLAmt || (VRI.Repl32 && !
isUInt<32>(Mask));
2547 unsigned NumAndInsts = (unsigned) NeedsRotate +
2548 (
unsigned) (bool) Res;
2549 unsigned NumOfSelectInsts = 0;
2551 assert(NumOfSelectInsts > 0 &&
"Failed to select an i64 constant.");
2553 NumAndInsts += (unsigned) (ANDIMask != 0) + (unsigned) (ANDISMask != 0) +
2554 (unsigned) (ANDIMask != 0 && ANDISMask != 0);
2556 NumAndInsts += NumOfSelectInsts + 1;
2558 unsigned NumRLInsts = 0;
2559 bool FirstBG =
true;
2560 bool MoreBG =
false;
2561 for (
auto &BG : BitGroups) {
2562 if (!MatchingBG(BG)) {
2567 SelectRotMask64Count(BG.RLAmt, BG.Repl32, BG.StartIdx, BG.EndIdx,
2572 LLVM_DEBUG(
dbgs() <<
"\t\trotation groups for " << VRI.V.getNode()
2573 <<
" RL: " << VRI.RLAmt << (VRI.Repl32 ?
" (32):" :
":")
2574 <<
"\n\t\t\tisel using masking: " << NumAndInsts
2575 <<
" using rotates: " << NumRLInsts <<
"\n");
2581 if (NumAndInsts > NumRLInsts)
2586 if ((Use32BitInsts || MoreBG) && NumAndInsts == NumRLInsts)
2591 if (InstCnt) *InstCnt += NumAndInsts;
2598 if (VRI.RLAmt || (VRI.Repl32 && !
isUInt<32>(Mask)))
2599 VRot = SelectRotMask64(VRI.V, dl, VRI.RLAmt, VRI.Repl32,
2600 VRI.Repl32 ? 31 : 0, VRI.Repl32 ? 30 : 63);
2605 if (Use32BitInsts) {
2606 assert((ANDIMask != 0 || ANDISMask != 0) &&
2607 "No set bits in mask when using 32-bit ands for 64-bit value");
2611 ANDIVal =
SDValue(CurDAG->getMachineNode(PPC::ANDI8_rec, dl, MVT::i64,
2612 ExtendToInt64(VRot, dl),
2613 getI32Imm(ANDIMask, dl)),
2617 SDValue(CurDAG->getMachineNode(PPC::ANDIS8_rec, dl, MVT::i64,
2618 ExtendToInt64(VRot, dl),
2619 getI32Imm(ANDISMask, dl)),
2623 TotalVal = ANDISVal;
2627 TotalVal =
SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64,
2628 ExtendToInt64(ANDIVal, dl), ANDISVal), 0);
2632 SDValue(CurDAG->getMachineNode(PPC::AND8, dl, MVT::i64,
2633 ExtendToInt64(VRot, dl), TotalVal),
2640 Res =
SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64,
2641 ExtendToInt64(Res, dl), TotalVal),
2646 eraseMatchingBitGroups(MatchingBG);
2651 SDNode *Select64(SDNode *
N,
bool LateMask,
unsigned *InstCnt) {
2655 if (InstCnt) *InstCnt = 0;
2658 SelectAndParts64(dl, Res, InstCnt);
2663 if ((!NeedMask || LateMask) && !Res) {
2667 unsigned MaxGroupsIdx = 0;
2668 if (!ValueRotsVec[0].Repl32) {
2669 for (
unsigned i = 0, ie = ValueRotsVec.size(); i < ie; ++i)
2670 if (ValueRotsVec[i].Repl32) {
2671 if (ValueRotsVec[i].NumGroups > ValueRotsVec[0].NumGroups)
2677 ValueRotInfo &VRI = ValueRotsVec[MaxGroupsIdx];
2678 bool NeedsRotate =
false;
2681 }
else if (VRI.Repl32) {
2682 for (
auto &BG : BitGroups) {
2683 if (BG.V != VRI.V || BG.RLAmt != VRI.RLAmt ||
2684 BG.Repl32 != VRI.Repl32)
2689 if (BG.StartIdx < 32 && BG.EndIdx < 32 && BG.StartIdx < BG.EndIdx)
2698 Res = SelectRotMask64(VRI.V, dl, VRI.RLAmt, VRI.Repl32,
2699 VRI.Repl32 ? 31 : 0, VRI.Repl32 ? 30 : 63,
2706 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
2707 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt &&
2708 BG.Repl32 == VRI.Repl32;
2715 for (
auto I = BitGroups.begin(), IE = BitGroups.end();
I != IE; ++
I) {
2716 if (SelectRotMask64Count(
I->RLAmt,
I->Repl32,
I->StartIdx,
I->EndIdx,
2718 SelectRotMask64Count(
I->RLAmt,
I->Repl32,
I->StartIdx,
I->EndIdx,
2720 if (
I != BitGroups.begin()) {
2723 BitGroups.insert(BitGroups.begin(), BG);
2731 for (
auto &BG : BitGroups) {
2733 Res = SelectRotMask64(BG.V, dl, BG.RLAmt, BG.Repl32, BG.StartIdx,
2734 BG.EndIdx, InstCnt);
2736 Res = SelectRotMaskIns64(Res, BG.V, dl, BG.RLAmt, BG.Repl32,
2737 BG.StartIdx, BG.EndIdx, InstCnt);
2748 unsigned ANDIMask = (
Mask & UINT16_MAX),
2749 ANDISMask = (Mask >> 16) & UINT16_MAX;
2751 if (Use32BitInsts) {
2752 assert((ANDIMask != 0 || ANDISMask != 0) &&
2753 "No set bits in mask when using 32-bit ands for 64-bit value");
2755 if (InstCnt) *InstCnt += (unsigned) (ANDIMask != 0) +
2756 (unsigned) (ANDISMask != 0) +
2757 (unsigned) (ANDIMask != 0 && ANDISMask != 0);
2761 ANDIVal =
SDValue(CurDAG->getMachineNode(PPC::ANDI8_rec, dl, MVT::i64,
2762 ExtendToInt64(Res, dl),
2763 getI32Imm(ANDIMask, dl)),
2767 SDValue(CurDAG->getMachineNode(PPC::ANDIS8_rec, dl, MVT::i64,
2768 ExtendToInt64(Res, dl),
2769 getI32Imm(ANDISMask, dl)),
2777 Res =
SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64,
2778 ExtendToInt64(ANDIVal, dl), ANDISVal), 0);
2780 unsigned NumOfSelectInsts = 0;
2783 Res =
SDValue(CurDAG->getMachineNode(PPC::AND8, dl, MVT::i64,
2784 ExtendToInt64(Res, dl), MaskVal),
2787 *InstCnt += NumOfSelectInsts + 1;
2794 SDNode *
Select(SDNode *
N,
bool LateMask,
unsigned *InstCnt =
nullptr) {
2796 collectBitGroups(LateMask);
2797 if (BitGroups.empty())
2801 if (
Bits.size() == 64)
2802 assignRepl32BitGroups();
2805 collectValueRotInfo();
2807 if (
Bits.size() == 32) {
2808 return Select32(
N, LateMask, InstCnt);
2810 assert(
Bits.size() == 64 &&
"Not 64 bits here?");
2811 return Select64(
N, LateMask, InstCnt);
2817 void eraseMatchingBitGroups(function_ref<
bool(
const BitGroup &)>
F) {
2823 bool NeedMask =
false;
2828 DenseMap<std::pair<SDValue, unsigned>, ValueRotInfo> ValueRots;
2831 SelectionDAG *CurDAG =
nullptr;
2834 BitPermutationSelector(SelectionDAG *DAG)
2843 getValueBits(
SDValue(
N, 0),
N->getValueType(0).getSizeInBits());
2848 LLVM_DEBUG(
dbgs() <<
"Considering bit-permutation-based instruction"
2849 " selection for: ");
2853 computeRotationAmounts();
2866 unsigned InstCnt = 0, InstCntLateMask = 0;
2868 SDNode *
RN =
Select(
N,
false, &InstCnt);
2869 LLVM_DEBUG(
dbgs() <<
"\t\tisel would use " << InstCnt <<
" instructions\n");
2872 SDNode *RNLM =
Select(
N,
true, &InstCntLateMask);
2874 <<
" instructions\n");
2876 if (InstCnt <= InstCntLateMask) {
2886class IntegerCompareEliminator {
2887 SelectionDAG *CurDAG;
2891 enum ExtOrTruncConversion { Ext, Trunc };
2899 enum SetccInGPROpts { ZExtOrig, ZExtInvert, SExtOrig, SExtInvert };
2909 enum ZeroCompare { GEZExt, GESExt, LEZExt, LESExt };
2911 SDNode *tryEXTEND(SDNode *
N);
2912 SDNode *tryLogicOpOfCompares(SDNode *
N);
2916 SDValue addExtOrTrunc(
SDValue NatWidthRes, ExtOrTruncConversion Conv);
2920 int64_t RHSValue, SDLoc dl);
2922 int64_t RHSValue, SDLoc dl);
2924 int64_t RHSValue, SDLoc dl);
2926 int64_t RHSValue, SDLoc dl);
2930 IntegerCompareEliminator(SelectionDAG *DAG,
2931 PPCDAGToDAGISel *Sel) : CurDAG(DAG), S(Sel) {
2934 "Only expecting to use this on 64 bit targets.");
2939 switch (
N->getOpcode()) {
2950 return tryEXTEND(
N);
2954 return tryLogicOpOfCompares(
N);
2962SDNode *IntegerCompareEliminator::tryEXTEND(SDNode *
N) {
2965 "Expecting a zero/sign extend node!");
2970 N->getOperand(0).getValueType() == MVT::i1 &&
2972 WideRes = computeLogicOpInGPR(
N->getOperand(0));
2973 else if (
N->getOperand(0).getOpcode() !=
ISD::SETCC)
2977 getSETCCInGPR(
N->getOperand(0),
2979 SetccInGPROpts::SExtOrig : SetccInGPROpts::ZExtOrig);
2985 bool Output32Bit =
N->getValueType(0) == MVT::i32;
2991 if (Input32Bit != Output32Bit)
2992 ConvOp = addExtOrTrunc(WideRes, Input32Bit ? ExtOrTruncConversion::Ext :
2993 ExtOrTruncConversion::Trunc);
3001SDNode *IntegerCompareEliminator::tryLogicOpOfCompares(SDNode *
N) {
3002 if (
N->getValueType(0) != MVT::i1)
3005 "Expected a logic operation on setcc results.");
3007 if (!LoweredLogical)
3012 unsigned SubRegToExtract = IsBitwiseNegate ? PPC::sub_eq : PPC::sub_gt;
3021 if (IsBitwiseNegate &&
3024 else if (IsBitwiseNegate)
3026 OpToConvToRecForm = LoweredLogical.
getOperand(0);
3030 OpToConvToRecForm = LoweredLogical;
3040 if (NewOpc != -1 && IsBitwiseNegate) {
3043 "Expected a PPC::XORI8 only for bitwise negation.");
3045 std::vector<SDValue>
Ops;
3046 for (
int i = 0, e = OpToConvToRecForm.
getNumOperands(); i < e; i++)
3052 MVT::Glue,
Ops), 0);
3054 assert((NewOpc != -1 || !IsBitwiseNegate) &&
3055 "No record form available for AND8/OR8/XOR8?");
3058 dl, MVT::i64, MVT::Glue,
LHS,
RHS),
3070 MVT::i1, CR0Reg, SRIdxVal,
3083SDValue IntegerCompareEliminator::computeLogicOpInGPR(
SDValue LogicOp) {
3085 "Can only handle logic operations here.");
3087 "Can only handle logic operations on i1 values here.");
3099 unsigned OperandOpcode = Operand.getOpcode();
3101 return getSETCCInGPR(Operand, SetccInGPROpts::ZExtOrig);
3103 SDValue InputOp = Operand.getOperand(0);
3106 PPC::RLDICL, dl, InVT, InputOp,
3107 S->getI64Imm(0, dl),
3108 S->getI64Imm(63, dl)), 0);
3110 return computeLogicOpInGPR(Operand);
3119 if (!
LHS || (!
RHS && !IsBitwiseNegation))
3122 NumLogicOpsOnComparison++;
3125 if (
LHS.getValueType() == MVT::i32)
3126 LHS = addExtOrTrunc(
LHS, ExtOrTruncConversion::Ext);
3127 if (!IsBitwiseNegation &&
RHS.getValueType() == MVT::i32)
3128 RHS = addExtOrTrunc(
RHS, ExtOrTruncConversion::Ext);
3133 case ISD::AND: NewOpc = PPC::AND8;
break;
3134 case ISD::OR: NewOpc = PPC::OR8;
break;
3135 case ISD::XOR: NewOpc = PPC::XOR8;
break;
3138 if (IsBitwiseNegation) {
3139 RHS = S->getI64Imm(1, dl);
3140 NewOpc = PPC::XORI8;
3151SDValue IntegerCompareEliminator::signExtendInputIfNeeded(
SDValue Input) {
3153 "Can only sign-extend 32-bit values here.");
3161 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3167 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3172 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3175 SignExtensionsAdded++;
3177 MVT::i64, Input), 0);
3184SDValue IntegerCompareEliminator::zeroExtendInputIfNeeded(
SDValue Input) {
3186 "Can only zero-extend 32-bit values here.");
3196 if (IsTruncateOfZExt)
3197 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3201 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3206 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3210 ZeroExtensionsAdded++;
3212 S->getI64Imm(0, dl),
3213 S->getI64Imm(32, dl)), 0);
3220SDValue IntegerCompareEliminator::addExtOrTrunc(
SDValue NatWidthRes,
3221 ExtOrTruncConversion Conv) {
3222 SDLoc dl(NatWidthRes);
3226 if (Conv == ExtOrTruncConversion::Ext) {
3231 ImDef, NatWidthRes, SubRegIdx), 0);
3234 assert(Conv == ExtOrTruncConversion::Trunc &&
3235 "Unknown convertion between 32 and 64 bit values.");
3241 NatWidthRes, SubRegIdx), 0);
3247IntegerCompareEliminator::getCompoundZeroComparisonInGPR(
SDValue LHS, SDLoc dl,
3248 ZeroCompare CmpTy) {
3249 EVT InVT =
LHS.getValueType();
3250 bool Is32Bit = InVT == MVT::i32;
3255 case ZeroCompare::GEZExt:
3256 case ZeroCompare::GESExt:
3260 case ZeroCompare::LEZExt:
3261 case ZeroCompare::LESExt: {
3264 LHS = signExtendInputIfNeeded(
LHS);
3269 Neg, S->getI64Imm(1, dl),
3270 S->getI64Imm(63, dl)), 0);
3274 S->getI64Imm(~0ULL, dl)), 0);
3284 (CmpTy == ZeroCompare::GEZExt || CmpTy == ZeroCompare::LEZExt))
3286 ToExtend, S->getI64Imm(1, dl),
3287 S->getI64Imm(63, dl)), 0);
3289 (CmpTy == ZeroCompare::GESExt || CmpTy == ZeroCompare::LESExt))
3291 S->getI64Imm(63, dl)), 0);
3293 assert(Is32Bit &&
"Should have handled the 32-bit sequences above.");
3296 case ZeroCompare::GEZExt: {
3297 SDValue ShiftOps[] = { ToExtend, S->getI32Imm(1, dl), S->getI32Imm(31, dl),
3298 S->getI32Imm(31, dl) };
3302 case ZeroCompare::GESExt:
3304 S->getI32Imm(31, dl)), 0);
3305 case ZeroCompare::LEZExt:
3307 S->getI32Imm(1, dl)), 0);
3308 case ZeroCompare::LESExt:
3310 S->getI32Imm(-1, dl)), 0);
3323 int64_t RHSValue, SDLoc dl) {
3327 bool IsRHSZero = RHSValue == 0;
3328 bool IsRHSOne = RHSValue == 1;
3329 bool IsRHSNegOne = RHSValue == -1LL;
3339 SDValue ShiftOps[] = { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl),
3340 S->getI32Imm(31, dl) };
3351 SDValue ShiftOps[] = { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl),
3352 S->getI32Imm(31, dl) };
3356 S->getI32Imm(1, dl)), 0);
3362 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GEZExt);
3368 IsRHSZero = RHSConst && RHSConst->
isZero();
3379 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LEZExt);
3383 LHS = signExtendInputIfNeeded(
LHS);
3384 RHS = signExtendInputIfNeeded(
RHS);
3389 S->getI64Imm(1, dl), S->getI64Imm(63, dl)),
3393 MVT::i64, Shift, S->getI32Imm(1, dl)), 0);
3401 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GEZExt);
3407 LHS = signExtendInputIfNeeded(
LHS);
3408 RHS = signExtendInputIfNeeded(
RHS);
3412 Neg, S->getI32Imm(1, dl), S->getI32Imm(63, dl)), 0);
3418 IsRHSZero = RHSConst && RHSConst->
isZero();
3430 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LEZExt);
3434 SDValue ShiftOps[] = {
LHS, S->getI32Imm(1, dl), S->getI32Imm(31, dl),
3435 S->getI32Imm(31, dl) };
3443 LHS = signExtendInputIfNeeded(
LHS);
3444 RHS = signExtendInputIfNeeded(
RHS);
3448 SUBFNode, S->getI64Imm(1, dl),
3449 S->getI64Imm(63, dl)), 0);
3460 LHS = zeroExtendInputIfNeeded(
LHS);
3461 RHS = zeroExtendInputIfNeeded(
RHS);
3466 Subtract, S->getI64Imm(1, dl),
3467 S->getI64Imm(63, dl)), 0);
3469 S->getI32Imm(1, dl)), 0);
3480 LHS = zeroExtendInputIfNeeded(
LHS);
3481 RHS = zeroExtendInputIfNeeded(
RHS);
3485 Subtract, S->getI64Imm(1, dl),
3486 S->getI64Imm(63, dl)), 0);
3496 int64_t RHSValue, SDLoc dl) {
3500 bool IsRHSZero = RHSValue == 0;
3501 bool IsRHSOne = RHSValue == 1;
3502 bool IsRHSNegOne = RHSValue == -1LL;
3515 SDValue SHLOps[] = { Cntlzw, S->getI32Imm(27, dl),
3516 S->getI32Imm(5, dl), S->getI32Imm(31, dl) };
3534 { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl), S->getI32Imm(31, dl) };
3539 S->getI32Imm(1, dl)), 0);
3546 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GESExt);
3552 IsRHSZero = RHSConst && RHSConst->
isZero();
3561 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LESExt);
3564 LHS = signExtendInputIfNeeded(
LHS);
3565 RHS = signExtendInputIfNeeded(
RHS);
3571 SUBFNode, S->getI64Imm(1, dl),
3572 S->getI64Imm(63, dl)), 0);
3574 S->getI32Imm(-1, dl)), 0);
3581 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GESExt);
3586 LHS = signExtendInputIfNeeded(
LHS);
3587 RHS = signExtendInputIfNeeded(
RHS);
3591 S->getI64Imm(63, dl)), 0);
3597 IsRHSZero = RHSConst && RHSConst->
isZero();
3608 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LESExt);
3612 S->getI32Imm(31, dl)), 0);
3617 LHS = signExtendInputIfNeeded(
LHS);
3618 RHS = signExtendInputIfNeeded(
RHS);
3622 SUBFNode, S->getI64Imm(63, dl)), 0);
3633 LHS = zeroExtendInputIfNeeded(
LHS);
3634 RHS = zeroExtendInputIfNeeded(
RHS);
3639 S->getI32Imm(1, dl), S->getI32Imm(63,dl)),
3642 S->getI32Imm(-1, dl)), 0);
3653 LHS = zeroExtendInputIfNeeded(
LHS);
3654 RHS = zeroExtendInputIfNeeded(
RHS);
3658 Subtract, S->getI64Imm(63, dl)), 0);
3668 int64_t RHSValue, SDLoc dl) {
3672 bool IsRHSZero = RHSValue == 0;
3673 bool IsRHSOne = RHSValue == 1;
3674 bool IsRHSNegOne = RHSValue == -1LL;
3685 S->getI64Imm(58, dl),
3686 S->getI64Imm(63, dl)), 0);
3697 Xor, S->getI32Imm(~0U, dl)), 0);
3707 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GEZExt);
3710 IsRHSZero = RHSConst && RHSConst->
isZero();
3719 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LEZExt);
3722 S->getI64Imm(1, dl),
3723 S->getI64Imm(63, dl)), 0);
3726 S->getI64Imm(63, dl)), 0);
3731 ShiftR, ShiftL, SubtractCarry), 0);
3739 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GEZExt);
3743 S->getI64Imm(~0ULL, dl)), 0);
3747 S->getI64Imm(1, dl),
3748 S->getI64Imm(63, dl)), 0);
3752 IsRHSZero = RHSConst && RHSConst->
isZero();
3762 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LEZExt);
3765 S->getI64Imm(1, dl),
3766 S->getI64Imm(63, dl)), 0);
3769 LHS, S->getI64Imm(63, dl)), 0);
3772 RHS, S->getI64Imm(1, dl),
3773 S->getI64Imm(63, dl)), 0);
3779 SRDINode, SRADINode, SUBFC8Carry), 0);
3781 ADDE8Node, S->getI64Imm(1, dl)), 0);
3796 LHS,
LHS, SUBFC8Carry), 0);
3798 SUBFE8Node, S->getI64Imm(1, dl)), 0);
3813 LHS,
LHS, SubtractCarry), 0);
3825 int64_t RHSValue, SDLoc dl) {
3829 bool IsRHSZero = RHSValue == 0;
3830 bool IsRHSOne = RHSValue == 1;
3831 bool IsRHSNegOne = RHSValue == -1LL;
3843 AddInput, S->getI32Imm(~0U, dl)), 0);
3856 Xor, S->getI32Imm(0, dl)), 0);
3866 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GESExt);
3869 IsRHSZero = RHSConst && RHSConst->
isZero();
3878 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LESExt);
3881 S->getI64Imm(63, dl)), 0);
3884 S->getI64Imm(1, dl),
3885 S->getI64Imm(63, dl)), 0);
3891 ShiftR, ShiftL, SubtractCarry), 0);
3900 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GESExt);
3904 S->getI64Imm(-1, dl)), 0);
3908 S->getI64Imm(63, dl)), 0);
3912 IsRHSZero = RHSConst && RHSConst->
isZero();
3922 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LESExt);
3925 S->getI64Imm(63, dl)), 0);
3929 LHS, S->getI64Imm(63, dl)), 0);
3932 RHS, S->getI64Imm(1, dl),
3933 S->getI64Imm(63, dl)), 0);
3939 SRDINode, SRADINode, SUBFC8Carry), 0);
3942 ADDE8Node, S->getI64Imm(1, dl)), 0);
3959 LHS, SubtractCarry), 0);
3961 ExtSub, ExtSub), 0);
3984static bool allUsesExtend(
SDValue Compare, SelectionDAG *CurDAG) {
3986 "An ISD::SETCC node required here.");
3994 for (
auto *CompareUse :
Compare.getNode()->users())
3999 OmittedForNonExtendUses++;
4009 SetccInGPROpts ConvOpts) {
4012 "An ISD::SETCC node required here.");
4026 EVT InputVT =
LHS.getValueType();
4027 if (InputVT != MVT::i32 && InputVT != MVT::i64)
4030 if (ConvOpts == SetccInGPROpts::ZExtInvert ||
4031 ConvOpts == SetccInGPROpts::SExtInvert)
4034 bool Inputs32Bit = InputVT == MVT::i32;
4039 bool IsSext = ConvOpts == SetccInGPROpts::SExtOrig ||
4040 ConvOpts == SetccInGPROpts::SExtInvert;
4042 if (IsSext && Inputs32Bit)
4043 return get32BitSExtCompare(
LHS,
RHS, CC, RHSValue, dl);
4044 else if (Inputs32Bit)
4045 return get32BitZExtCompare(
LHS,
RHS, CC, RHSValue, dl);
4047 return get64BitSExtCompare(
LHS,
RHS, CC, RHSValue, dl);
4048 return get64BitZExtCompare(
LHS,
RHS, CC, RHSValue, dl);
4053bool PPCDAGToDAGISel::tryIntCompareInGPR(SDNode *
N) {
4054 if (
N->getValueType(0) != MVT::i32 &&
4055 N->getValueType(0) != MVT::i64)
4067 if (!(
CmpInGPR.getNumOccurrences() > 0) && Subtarget->isISA3_1())
4070 switch (
N->getOpcode()) {
4077 IntegerCompareEliminator ICmpElim(CurDAG,
this);
4078 if (SDNode *New = ICmpElim.Select(
N)) {
4079 ReplaceNode(
N, New);
4087bool PPCDAGToDAGISel::tryBitPermutation(SDNode *
N) {
4088 if (
N->getValueType(0) != MVT::i32 &&
4089 N->getValueType(0) != MVT::i64)
4095 switch (
N->getOpcode()) {
4100 if (Subtarget->isISA3_1() &&
N->getValueType(0) == MVT::i32 &&
4102 auto &OpRight =
N->getOperand(1);
4112 BitPermutationSelector BPS(CurDAG);
4113 if (SDNode *New = BPS.Select(
N)) {
4114 ReplaceNode(
N, New);
4127 const SDLoc &dl,
SDValue Chain) {
4131 if (
LHS.getValueType() == MVT::i32) {
4138 getI32Imm(
Imm & 0xFFFF, dl)),
4143 getI32Imm(
Imm & 0xFFFF, dl)),
4156 getI32Imm(
Imm >> 16, dl)), 0);
4158 getI32Imm(
Imm & 0xFFFF, dl)), 0);
4164 getI32Imm(
Imm & 0xFFFF, dl)), 0);
4170 getI32Imm((
int)SImm & 0xFFFF,
4175 }
else if (
LHS.getValueType() == MVT::i64) {
4182 getI32Imm(
Imm & 0xFFFF, dl)),
4187 getI32Imm(
Imm & 0xFFFF, dl)),
4201 getI64Imm(
Imm >> 16, dl)), 0);
4203 getI64Imm(
Imm & 0xFFFF, dl)),
4211 getI64Imm(
Imm & 0xFFFF, dl)), 0);
4217 getI64Imm(SImm & 0xFFFF, dl)),
4221 }
else if (
LHS.getValueType() == MVT::f32) {
4222 if (Subtarget->hasSPE()) {
4227 Opc = PPC::EFSCMPEQ;
4235 Opc = PPC::EFSCMPLT;
4243 Opc = PPC::EFSCMPGT;
4248 }
else if (
LHS.getValueType() == MVT::f64) {
4249 if (Subtarget->hasSPE()) {
4254 Opc = PPC::EFDCMPEQ;
4262 Opc = PPC::EFDCMPLT;
4270 Opc = PPC::EFDCMPGT;
4274 Opc = Subtarget->hasVSX() ? PPC::XSCMPUDP : PPC::FCMPUD;
4276 assert(
LHS.getValueType() == MVT::f128 &&
"Unknown vt!");
4277 assert(Subtarget->hasP9Vector() &&
"XSCMPUQP requires Power9 Vector");
4278 Opc = PPC::XSCMPUQP;
4346 case ISD::SETO: Invert =
true;
return 3;
4363 bool HasVSX,
bool &Swap,
bool &Negate) {
4390 if (VecVT == MVT::v4f32)
4391 return HasVSX ? PPC::XVCMPEQSP : PPC::VCMPEQFP;
4392 else if (VecVT == MVT::v2f64)
4393 return PPC::XVCMPEQDP;
4397 if (VecVT == MVT::v4f32)
4398 return HasVSX ? PPC::XVCMPGTSP : PPC::VCMPGTFP;
4399 else if (VecVT == MVT::v2f64)
4400 return PPC::XVCMPGTDP;
4404 if (VecVT == MVT::v4f32)
4405 return HasVSX ? PPC::XVCMPGESP : PPC::VCMPGEFP;
4406 else if (VecVT == MVT::v2f64)
4407 return PPC::XVCMPGEDP;
4434 if (VecVT == MVT::v16i8)
4435 return PPC::VCMPEQUB;
4436 else if (VecVT == MVT::v8i16)
4437 return PPC::VCMPEQUH;
4438 else if (VecVT == MVT::v4i32)
4439 return PPC::VCMPEQUW;
4440 else if (VecVT == MVT::v2i64)
4441 return PPC::VCMPEQUD;
4442 else if (VecVT == MVT::v1i128)
4443 return PPC::VCMPEQUQ;
4446 if (VecVT == MVT::v16i8)
4447 return PPC::VCMPGTSB;
4448 else if (VecVT == MVT::v8i16)
4449 return PPC::VCMPGTSH;
4450 else if (VecVT == MVT::v4i32)
4451 return PPC::VCMPGTSW;
4452 else if (VecVT == MVT::v2i64)
4453 return PPC::VCMPGTSD;
4454 else if (VecVT == MVT::v1i128)
4455 return PPC::VCMPGTSQ;
4458 if (VecVT == MVT::v16i8)
4459 return PPC::VCMPGTUB;
4460 else if (VecVT == MVT::v8i16)
4461 return PPC::VCMPGTUH;
4462 else if (VecVT == MVT::v4i32)
4463 return PPC::VCMPGTUW;
4464 else if (VecVT == MVT::v2i64)
4465 return PPC::VCMPGTUD;
4466 else if (VecVT == MVT::v1i128)
4467 return PPC::VCMPGTUQ;
4476bool PPCDAGToDAGISel::trySETCC(SDNode *
N) {
4479 bool IsStrict =
N->isStrictFPOpcode();
4484 bool isPPC64 = (PtrVT == MVT::i64);
4500 SDValue Ops[] = {
Op, getI32Imm(27, dl), getI32Imm(5, dl),
4501 getI32Imm(31, dl) };
4509 Op, getI32Imm(~0U, dl)), 0);
4514 SDValue Ops[] = {
Op, getI32Imm(1, dl), getI32Imm(31, dl),
4515 getI32Imm(31, dl) };
4523 SDValue Ops[] = {
T, getI32Imm(1, dl), getI32Imm(31, dl),
4524 getI32Imm(31, dl) };
4529 }
else if (
Imm == ~0U) {
4536 Op, getI32Imm(1, dl)), 0);
4541 0),
Op.getValue(1));
4546 SDNode *AD = CurDAG->
getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Glue,
4547 Op, getI32Imm(~0U, dl));
4554 getI32Imm(1, dl)), 0);
4557 SDValue Ops[] = { AN, getI32Imm(1, dl), getI32Imm(31, dl),
4558 getI32Imm(31, dl) };
4563 SDValue Ops[] = {
Op, getI32Imm(1, dl), getI32Imm(31, dl),
4564 getI32Imm(31, dl) };
4575 if (!IsStrict &&
LHS.getValueType().isVector()) {
4576 if (Subtarget->hasSPE())
4579 EVT VecVT =
LHS.getValueType();
4595 unsigned int VCmpInst =
4603 CurDAG->
SelectNodeTo(
N, Subtarget->hasVSX() ? PPC::XXLNOR : PPC::VNOR,
4612 if (Subtarget->useCRBits())
4624 if (Subtarget->hasSPE() &&
LHS.getValueType().isFloatingPoint()) {
4638 SDValue Ops[] = { IntCR, getI32Imm((32 - (3 - Idx)) & 31, dl),
4639 getI32Imm(31, dl), getI32Imm(31, dl) };
4648 CurDAG->
SelectNodeTo(
N, PPC::XORI, MVT::i32, Tmp, getI32Imm(1, dl));
4654bool PPCDAGToDAGISel::isOffsetMultipleOf(SDNode *
N,
unsigned Val)
const {
4659 if (LDN || (MIN &&
MIN->getOpcode() == PPCISD::LD_SPLAT))
4675 if ((SlotAlign % Val) != 0)
4690void PPCDAGToDAGISel::transferMemOperands(SDNode *
N, SDNode *Result) {
4697 bool &NeedSwapOps,
bool &IsUnCmp) {
4703 SDValue TrueRes =
N->getOperand(2);
4704 SDValue FalseRes =
N->getOperand(3);
4706 if (!TrueConst || (
N->getSimpleValueType(0) != MVT::i64 &&
4707 N->getSimpleValueType(0) != MVT::i32))
4716 if ((TrueResVal < -1 || TrueResVal > 1) ||
4753 if (!SelCCTrueConst || !SelCCFalseConst)
4758 if (SelCCTVal == -1 && SelCCFVal == 1) {
4760 }
else if (SelCCTVal != 1 || SelCCFVal != -1)
4770 bool InnerSwapped =
false;
4771 if (
LHS == InnerRHS &&
RHS == InnerLHS)
4772 InnerSwapped =
true;
4773 else if (
LHS != InnerLHS ||
RHS != InnerRHS)
4784 NeedSwapOps = (InnerCC ==
ISD::SETGT) ? InnerSwapped : !InnerSwapped;
4801 NeedSwapOps = (TrueResVal == 1);
4820 NeedSwapOps = (TrueResVal == -1);
4829 LLVM_DEBUG(
dbgs() <<
"Found a node that can be lowered to a SETB: ");
4837 if (
N.getOpcode() == PPCISD::FTSQRT)
4842 switch (
N.getConstantOperandVal(0)) {
4843 case Intrinsic::ppc_vsx_xvtdivdp:
4844 case Intrinsic::ppc_vsx_xvtdivsp:
4845 case Intrinsic::ppc_vsx_xvtsqrtdp:
4846 case Intrinsic::ppc_vsx_xvtsqrtsp:
4852bool PPCDAGToDAGISel::tryFoldSWTestBRCC(SDNode *
N) {
4910bool PPCDAGToDAGISel::trySelectLoopCountIntrinsic(SDNode *
N) {
4922 LHS.getOperand(0).getConstantOperandVal(1) != Intrinsic::loop_decrement)
4929 "Counter decrement comparison is not EQ or NE");
4932 assert(OldDecrement.
hasOneUse() &&
"loop decrement has more than one use!");
4934 SDLoc DecrementLoc(OldDecrement);
4936 SDValue DecrementOps[] = {Subtarget->isPPC64() ? getI64Imm(1, DecrementLoc)
4937 : getI32Imm(1, DecrementLoc)};
4938 unsigned DecrementOpcode =
4939 Subtarget->isPPC64() ? PPC::DecreaseCTR8loop : PPC::DecreaseCTRloop;
4940 SDNode *NewDecrement = CurDAG->
getMachineNode(DecrementOpcode, DecrementLoc,
4941 MVT::i1, DecrementOps);
4943 unsigned Val =
RHS->getAsZExtVal();
4945 unsigned Opcode = IsBranchOnTrue ? PPC::BC : PPC::BCn;
4947 ReplaceUses(
LHS.getValue(0),
LHS.getOperand(1));
4951 ReplaceUses(OldDecrement.
getValue(1), ChainInput);
4955 ChainInput,
N->getOperand(0));
4958 N->getOperand(4), Chain);
4962bool PPCDAGToDAGISel::tryAsSingleRLWINM(SDNode *
N) {
4970 unsigned SH, MB, ME;
4973 if (isRotateAndMask(Val.
getNode(),
Imm,
false, SH, MB, ME)) {
4975 SDValue Ops[] = {Val, getI32Imm(SH, dl), getI32Imm(MB, dl),
4986 unsigned AlreadyCleared = 0;
4989 if (IntrinsicID == Intrinsic::ppc_lbarx)
4990 AlreadyCleared = 24;
4991 else if (IntrinsicID == Intrinsic::ppc_lharx)
4992 AlreadyCleared = 16;
4993 if (AlreadyCleared != 0 && AlreadyCleared == MB && ME == 31) {
4994 ReplaceUses(
SDValue(
N, 0),
N->getOperand(0));
4999 SDValue Ops[] = {Val, getI32Imm(0, dl), getI32Imm(MB, dl),
5007 ReplaceUses(
SDValue(
N, 0),
N->getOperand(1));
5014bool PPCDAGToDAGISel::tryAsSingleRLWINM8(SDNode *
N) {
5031 SDValue Ops[] = {
N->getOperand(0), getI64Imm(0, dl), getI64Imm(MB - 32, dl),
5032 getI64Imm(ME - 32, dl)};
5040bool PPCDAGToDAGISel::tryAsPairOfRLDICL(SDNode *
N) {
5060 if (NumOfLeadingZeros != 0)
5073 unsigned OnesOnLeft = ME + 1;
5074 unsigned ZerosInBetween = (MB - ME + 63) & 63;
5078 getI64Imm(OnesOnLeft, Loc),
5079 getI64Imm(ZerosInBetween, Loc)),
5088 SDValue Ops[] = {Val, getI64Imm(64 - OnesOnLeft, Loc),
5089 getI64Imm(NumOfLeadingZeros, Loc)};
5094bool PPCDAGToDAGISel::tryAsSingleRLWIMI(SDNode *
N) {
5124 getI32Imm(MB, dl), getI32Imm(ME, dl)};
5132bool PPCDAGToDAGISel::tryAsSingleRLDCL(SDNode *
N) {
5161bool PPCDAGToDAGISel::tryAsSingleRLDICL(SDNode *
N) {
5180 auto ImDef = CurDAG->
getMachineNode(PPC::IMPLICIT_DEF, dl, ResultType);
5185 getI32Imm(PPC::sub_32, dl)),
5198 assert(
Imm < 64 &&
"Illegal shift amount");
5203 SDValue Ops[] = {Val, getI32Imm(SH, dl), getI32Imm(MB, dl)};
5208bool PPCDAGToDAGISel::tryAsSingleRLDICR(SDNode *
N) {
5221 SDValue Ops[] = {
N->getOperand(0), getI32Imm(SH, dl), getI32Imm(MB, dl)};
5226bool PPCDAGToDAGISel::tryAsSingleRLDIMI(SDNode *
N) {
5240 unsigned SH = 63 - ME;
5246 getI32Imm(SH, Dl), getI32Imm(MB, Dl)};
5253void PPCDAGToDAGISel::Select(SDNode *
N) {
5255 if (
N->isMachineOpcode()) {
5268 if (tryBitPermutation(
N))
5272 if (tryIntCompareInGPR(
N))
5275 switch (
N->getOpcode()) {
5279 if (
N->getValueType(0) == MVT::i64) {
5286 auto IntrinsicID =
N->getConstantOperandVal(1);
5287 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
5288 IntrinsicID != Intrinsic::ppc_trapd &&
5289 IntrinsicID != Intrinsic::ppc_trap)
5291 unsigned Opcode = (IntrinsicID == Intrinsic::ppc_tdw ||
5292 IntrinsicID == Intrinsic::ppc_trapd)
5297 if (IntrinsicID == Intrinsic::ppc_tdw ||
5298 IntrinsicID == Intrinsic::ppc_tw) {
5299 SDValue Ops[] = {
N->getOperand(4),
N->getOperand(2),
N->getOperand(3)};
5300 int16_t SImmOperand2;
5301 int16_t SImmOperand3;
5302 int16_t SImmOperand4;
5303 bool isOperand2IntS16Immediate =
5305 bool isOperand3IntS16Immediate =
5310 if (isOperand2IntS16Immediate == isOperand3IntS16Immediate)
5311 Opcode = IntrinsicID == Intrinsic::ppc_tdw ? PPC::TD : PPC::TW;
5312 else if (isOperand3IntS16Immediate)
5314 Ops[2] = getI32Imm(
int(SImmOperand3) & 0xFFFF, dl);
5317 bool isOperand4IntS16Immediate =
5319 (void)isOperand4IntS16Immediate;
5320 assert(isOperand4IntS16Immediate &&
5321 "The 4th operand is not an Immediate");
5323 int16_t TO = int(SImmOperand4) & 0x1F;
5325 if ((TO & 0x1) != ((TO & 0x2) >> 1))
5326 TO = (TO & 0x1) ? TO + 1 : TO - 1;
5328 if ((TO & 0x8) != ((TO & 0x10) >> 1))
5329 TO = (TO & 0x8) ? TO + 8 : TO - 8;
5330 Ops[0] = getI32Imm(TO, dl);
5331 Ops[1] =
N->getOperand(3);
5332 Ops[2] = getI32Imm(
int(SImmOperand2) & 0xFFFF, dl);
5337 OpsWithMD = {getI32Imm(24, dl),
N->getOperand(2), getI32Imm(0, dl)};
5341 if (
N->getNumOperands() > MDIndex) {
5342 SDValue MDV =
N->getOperand(MDIndex);
5347 "ppc-trap-reason") &&
5348 "Unsupported annotation data type!");
5351 "Invalid data type for annotation ppc-trap-reason!");
5354 MD->
getOperand(i))->getString().str()), dl));
5369 auto IntID =
N->getConstantOperandVal(0);
5370 if (IntID == Intrinsic::ppc_fsels) {
5371 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2),
N->getOperand(3)};
5376 if (IntID == Intrinsic::ppc_bcdadd_p || IntID == Intrinsic::ppc_bcdsub_p) {
5377 auto Pred =
N->getConstantOperandVal(1);
5379 IntID == Intrinsic::ppc_bcdadd_p ? PPC::BCDADD_rec : PPC::BCDSUB_rec;
5380 unsigned SubReg = 0;
5381 unsigned ShiftVal = 0;
5385 SubReg = PPC::sub_eq;
5389 SubReg = PPC::sub_eq;
5394 SubReg = PPC::sub_lt;
5398 SubReg = PPC::sub_lt;
5403 SubReg = PPC::sub_gt;
5407 SubReg = PPC::sub_gt;
5412 SubReg = PPC::sub_un;
5415 SubReg = PPC::sub_un;
5420 EVT VTs[] = {MVT::v16i8, MVT::Glue};
5427 if (Subtarget->isISA3_1()) {
5430 CurDAG->
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
5431 CR6Reg, SubRegIdx, BCDOp.
getValue(1)),
5440 SDValue Ops[] = {Move, getI32Imm((32 - (4 + ShiftVal)) & 31, dl),
5441 getI32Imm(31, dl), getI32Imm(31, dl)};
5447 CurDAG->
SelectNodeTo(
N, PPC::XORI, MVT::i32, Shift, getI32Imm(1, dl));
5453 if (!Subtarget->isISA3_1())
5455 unsigned Opcode = 0;
5459 case Intrinsic::ppc_altivec_vstribr_p:
5460 Opcode = PPC::VSTRIBR_rec;
5462 case Intrinsic::ppc_altivec_vstribl_p:
5463 Opcode = PPC::VSTRIBL_rec;
5465 case Intrinsic::ppc_altivec_vstrihr_p:
5466 Opcode = PPC::VSTRIHR_rec;
5468 case Intrinsic::ppc_altivec_vstrihl_p:
5469 Opcode = PPC::VSTRIHL_rec;
5476 EVT VTs[] = {MVT::v16i8, MVT::Glue};
5484 CurDAG->
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
5485 CR6Reg, SubRegIdx, VecStrOp.
getValue(1)),
5499 case PPCISD::ADDI_TLSLD_L_ADDR:
5500 case PPCISD::ADDI_TLSGD_L_ADDR: {
5502 if (PPCLowering->getPointerTy(CurDAG->
getDataLayout()) != MVT::i32 ||
5503 !Subtarget->isSecurePlt() || !Subtarget->
isTargetELF() ||
5511 case PPCISD::CALL_RM: {
5513 !Subtarget->isSecurePlt() || !Subtarget->
isTargetELF())
5529 ReplaceNode(
N, getGlobalBaseReg());
5533 selectFrameIndex(
N,
N);
5539 N->getOperand(0), InGlue));
5544 ReplaceNode(
N, CurDAG->
getMachineNode(PPC::ReadTB, dl, MVT::i32, MVT::i32,
5545 MVT::Other,
N->getOperand(0)));
5552 getConstantIntValue(), dl,
5553 N->getValueType(0));
5554 if (
N->getValueType(0) == MVT::i64) {
5562 assert(
N->getValueType(0) == MVT::i32 &&
5563 "Expecting i64 or i32 in PPCISD::SRA_ADDZE");
5579 if (tryTLSXFormStore(ST))
5586 EVT LoadedVT =
LD->getMemoryVT();
5593 if (tryTLSXFormLoad(LD))
5604 if (
LD->getValueType(0) != MVT::i64) {
5606 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5609 case MVT::f64: Opcode = PPC::LFDU;
break;
5610 case MVT::f32: Opcode = PPC::LFSU;
break;
5611 case MVT::i32: Opcode = PPC::LWZU;
break;
5612 case MVT::i16: Opcode = isSExt ? PPC::LHAU : PPC::LHZU;
break;
5614 case MVT::i8: Opcode = PPC::LBZU;
break;
5617 assert(
LD->getValueType(0) == MVT::i64 &&
"Unknown load result type!");
5618 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5621 case MVT::i64: Opcode = PPC::LDU;
break;
5622 case MVT::i32: Opcode = PPC::LWZU8;
break;
5623 case MVT::i16: Opcode = isSExt ? PPC::LHAU8 : PPC::LHZU8;
break;
5625 case MVT::i8: Opcode = PPC::LBZU8;
break;
5633 Opcode, dl,
LD->getValueType(0),
5635 transferMemOperands(
N, MN);
5641 if (
LD->getValueType(0) != MVT::i64) {
5643 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5646 case MVT::f64: Opcode = PPC::LFDUX;
break;
5647 case MVT::f32: Opcode = PPC::LFSUX;
break;
5648 case MVT::i32: Opcode = PPC::LWZUX;
break;
5649 case MVT::i16: Opcode = isSExt ? PPC::LHAUX : PPC::LHZUX;
break;
5651 case MVT::i8: Opcode = PPC::LBZUX;
break;
5654 assert(
LD->getValueType(0) == MVT::i64 &&
"Unknown load result type!");
5655 assert((!isSExt || LoadedVT == MVT::i16 || LoadedVT == MVT::i32) &&
5656 "Invalid sext update load");
5659 case MVT::i64: Opcode = PPC::LDUX;
break;
5660 case MVT::i32: Opcode = isSExt ? PPC::LWAUX : PPC::LWZUX8;
break;
5661 case MVT::i16: Opcode = isSExt ? PPC::LHAUX8 : PPC::LHZUX8;
break;
5663 case MVT::i8: Opcode = PPC::LBZUX8;
break;
5671 Opcode, dl,
LD->getValueType(0),
5673 transferMemOperands(
N, MN);
5681 if (tryAsSingleRLWINM(
N) || tryAsSingleRLWIMI(
N) || tryAsSingleRLDCL(
N) ||
5682 tryAsSingleRLDICL(
N) || tryAsSingleRLDICR(
N) || tryAsSingleRLWINM8(
N) ||
5683 tryAsPairOfRLDICL(
N))
5689 if (
N->getValueType(0) == MVT::i32)
5690 if (tryBitfieldInsert(
N))
5701 selectFrameIndex(
N,
N->getOperand(0).getNode(), (int64_t)
Imm);
5708 if (tryAsSingleRLDIMI(
N))
5714 bool IsPPC64 = Subtarget->isPPC64();
5716 (Imm64 & ~0xFFFFFFFFuLL) == 0) {
5720 if (ImmHi != 0 && ImmLo != 0) {
5723 getI16Imm(ImmLo, dl));
5737 bool IsPPC64 = Subtarget->isPPC64();
5739 (Imm64 & ~0xFFFFFFFFuLL) == 0) {
5743 if (ImmHi != 0 && ImmLo != 0) {
5746 getI16Imm(ImmLo, dl));
5759 selectFrameIndex(
N,
N->getOperand(0).getNode(), (int64_t)
Imm);
5766 unsigned Imm, SH, MB, ME;
5768 isRotateAndMask(
N,
Imm,
true, SH, MB, ME)) {
5770 getI32Imm(SH, dl), getI32Imm(MB, dl),
5771 getI32Imm(ME, dl) };
5780 unsigned Imm, SH, MB, ME;
5782 isRotateAndMask(
N,
Imm,
true, SH, MB, ME)) {
5784 getI32Imm(SH, dl), getI32Imm(MB, dl),
5785 getI32Imm(ME, dl) };
5815 SDNode *MulNode = CurDAG->
getMachineNode(PPC::MULLI8, dl, MVT::i64,
5816 N->getOperand(0), SDImm);
5819 getI32Imm(63 - Shift, dl)};
5824 SDNode *MulNode = CurDAG->
getMachineNode(PPC::MULLI, dl, MVT::i32,
5825 N->getOperand(0), SDImm);
5828 getI32Imm(0, dl), getI32Imm(31 - Shift, dl)};
5840 EVT InVT =
N->getOperand(0).getValueType();
5841 assert((InVT == MVT::i64 || InVT == MVT::i32) &&
5842 "Invalid input type for ANDI_rec_1_EQ_BIT");
5844 unsigned Opcode = (InVT == MVT::i64) ? PPC::ANDI8_rec : PPC::ANDI_rec;
5854 CurDAG->
SelectNodeTo(
N, TargetOpcode::EXTRACT_SUBREG, MVT::i1, CR0Reg,
5855 SRIdxVal,
SDValue(AndI.getNode(), 1) );
5862 bool isPPC64 = (PtrVT == MVT::i64);
5865 if (Subtarget->useCRBits() &&
N->getOperand(0).getValueType() == MVT::i1)
5868 if (Subtarget->isISA3_0() && Subtarget->isPPC64()) {
5869 bool NeedSwapOps =
false;
5870 bool IsUnCmp =
false;
5886 N,
N->getSimpleValueType(0) == MVT::i64 ? PPC::SETB8 : PPC::SETB,
5887 N->getValueType(0), GenCC);
5898 N->getValueType(0) == MVT::i32) {
5901 N->getOperand(0), getI32Imm(~0U, dl));
5903 N->getOperand(0),
SDValue(Tmp, 1));
5907 SDValue CCReg = SelectCC(
N->getOperand(0),
N->getOperand(1), CC, dl);
5909 if (
N->getValueType(0) == MVT::i1) {
5917 case 0: SRI = PPC::sub_lt;
break;
5918 case 1: SRI = PPC::sub_gt;
break;
5919 case 2: SRI = PPC::sub_eq;
break;
5920 case 3: SRI = PPC::sub_un;
break;
5927 SDValue C = Inv ? NotCCBit : CCBit,
5928 NotC = Inv ? CCBit : NotCCBit;
5931 C,
N->getOperand(2)), 0);
5933 NotC,
N->getOperand(3)), 0);
5935 CurDAG->
SelectNodeTo(
N, PPC::CROR, MVT::i1, CAndT, NotCAndF);
5942 unsigned SelectCCOp;
5943 if (
N->getValueType(0) == MVT::i32)
5944 SelectCCOp = PPC::SELECT_CC_I4;
5945 else if (
N->getValueType(0) == MVT::i64)
5946 SelectCCOp = PPC::SELECT_CC_I8;
5947 else if (
N->getValueType(0) == MVT::f32) {
5948 if (Subtarget->hasP8Vector())
5949 SelectCCOp = PPC::SELECT_CC_VSSRC;
5950 else if (Subtarget->hasSPE())
5951 SelectCCOp = PPC::SELECT_CC_SPE4;
5953 SelectCCOp = PPC::SELECT_CC_F4;
5954 }
else if (
N->getValueType(0) == MVT::f64) {
5955 if (Subtarget->hasVSX())
5956 SelectCCOp = PPC::SELECT_CC_VSFRC;
5957 else if (Subtarget->hasSPE())
5958 SelectCCOp = PPC::SELECT_CC_SPE;
5960 SelectCCOp = PPC::SELECT_CC_F8;
5961 }
else if (
N->getValueType(0) == MVT::f128)
5962 SelectCCOp = PPC::SELECT_CC_F16;
5963 else if (Subtarget->hasSPE())
5964 SelectCCOp = PPC::SELECT_CC_SPE;
5965 else if (
N->getValueType(0) == MVT::v2f64 ||
5966 N->getValueType(0) == MVT::v2i64)
5967 SelectCCOp = PPC::SELECT_CC_VSRC;
5969 SelectCCOp = PPC::SELECT_CC_VRRC;
5972 getI32Imm(BROpc, dl) };
5977 if (Subtarget->hasVSX() && (
N->getValueType(0) == MVT::v2f64 ||
5978 N->getValueType(0) == MVT::v2i64)) {
5985 for (
int i = 0; i < 2; ++i)
5991 if (Op1 == Op2 &&
DM[0] == 0 &&
DM[1] == 0 &&
5997 if (
LD->isUnindexed() &&
LD->hasOneUse() && Op1.
hasOneUse() &&
5998 (
LD->getMemoryVT() == MVT::f64 ||
5999 LD->getMemoryVT() == MVT::i64) &&
6003 MachineMemOperand *MemOp =
LD->getMemOperand();
6005 N->getValueType(0),
Ops);
6015 unsigned tmp =
DM[0];
6030 bool IsPPC64 = Subtarget->isPPC64();
6031 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(0) };
6033 ? (IsPPC64 ? PPC::BDNZ8 : PPC::BDNZ)
6034 : (IsPPC64 ? PPC::BDZ8 : PPC::BDZ),
6038 case PPCISD::COND_BRANCH: {
6045 unsigned PCC =
N->getConstantOperandVal(1);
6049 SDValue Pred = getI32Imm(PCC, dl);
6056 if (tryFoldSWTestBRCC(
N))
6058 if (trySelectLoopCountIntrinsic(
N))
6064 if (
N->getOperand(2).getValueType() == MVT::i1) {
6087 N->getOperand(Swap ? 3 : 2),
6088 N->getOperand(Swap ? 2 : 3)), 0);
6089 CurDAG->
SelectNodeTo(
N, PPC::BC, MVT::Other, BitComp,
N->getOperand(4),
6099 N->getOperand(4),
N->getOperand(0) };
6107 unsigned Opc =
Target.getValueType() == MVT::i32 ? PPC::MTCTR : PPC::MTCTR8;
6108 unsigned Reg =
Target.getValueType() == MVT::i32 ? PPC::BCTR : PPC::BCTR8;
6114 case PPCISD::TOC_ENTRY: {
6115 const bool isPPC64 = Subtarget->isPPC64();
6116 const bool isELFABI = Subtarget->
isSVR4ABI();
6117 const bool isAIXABI = Subtarget->
isAIXABI();
6123 "PowerPC doesn't support tiny or kernel code models.");
6134 auto replaceWith = [
this, &dl](
unsigned OpCode, SDNode *TocEntry,
6136 SDValue GA = TocEntry->getOperand(0);
6137 SDValue TocBase = TocEntry->getOperand(1);
6138 SDNode *MN =
nullptr;
6139 if (OpCode == PPC::ADDItoc || OpCode == PPC::ADDItoc8)
6145 transferMemOperands(TocEntry, MN);
6147 ReplaceNode(TocEntry, MN);
6156 "32-bit ELF can only have TOC entries in position independent"
6159 replaceWith(PPC::LWZtoc,
N, MVT::i32);
6163 assert(isAIXABI &&
"ELF ABI already handled");
6166 replaceWith(PPC::ADDItoc,
N, MVT::i32);
6170 replaceWith(PPC::LWZtoc,
N, MVT::i32);
6175 assert(isAIXABI &&
"ELF ABI handled in common SelectCode");
6178 replaceWith(PPC::ADDItoc8,
N, MVT::i64);
6188 assert((isPPC64 || (isAIXABI && !isPPC64)) &&
"We are dealing with 64-bit"
6189 " ELF/AIX or 32-bit AIX in the following.");
6214 isPPC64 ? PPC::ADDIStocHA8 : PPC::ADDIStocHA, dl, VT, TOCbase, GA);
6221 dl, VT,
SDValue(Tmp, 0), GA));
6225 if (PPCLowering->isAccessedAsGotIndirect(GA)) {
6229 isPPC64 ? PPC::LDtocL : PPC::LWZtocL, dl, VT, GA,
SDValue(Tmp, 0));
6231 transferMemOperands(
N, MN);
6236 assert(isPPC64 &&
"TOC_ENTRY already handled for 32-bit.");
6245 "PPCISD::PPC32_PICGOT is only supported for 32-bit SVR4");
6256 "Invalid operand on VADD_SPLAT!");
6258 int Elt =
N->getConstantOperandVal(0);
6259 int EltSize =
N->getConstantOperandVal(1);
6260 unsigned Opc1, Opc2, Opc3;
6264 Opc1 = PPC::VSPLTISB;
6265 Opc2 = PPC::VADDUBM;
6266 Opc3 = PPC::VSUBUBM;
6268 }
else if (EltSize == 2) {
6269 Opc1 = PPC::VSPLTISH;
6270 Opc2 = PPC::VADDUHM;
6271 Opc3 = PPC::VSUBUHM;
6274 assert(EltSize == 4 &&
"Invalid element size on VADD_SPLAT!");
6275 Opc1 = PPC::VSPLTISW;
6276 Opc2 = PPC::VADDUWM;
6277 Opc3 = PPC::VSUBUWM;
6281 if ((Elt & 1) == 0) {
6288 SDValue EltVal = getI32Imm(Elt >> 1, dl);
6293 }
else if (Elt > 0) {
6300 SDValue EltVal = getI32Imm(Elt - 16, dl);
6302 EltVal = getI32Imm(-16, dl);
6314 SDValue EltVal = getI32Imm(Elt + 16, dl);
6316 EltVal = getI32Imm(-16, dl);
6323 case PPCISD::LD_SPLAT: {
6327 if (!Subtarget->hasAltivec() || Subtarget->hasDirectMove())
6330 EVT
Type =
N->getValueType(0);
6331 if (
Type != MVT::v16i8 &&
Type != MVT::v8i16)
6340 isOffsetMultipleOf(
N, 16))
6344 CurDAG->
getRegister(Subtarget->isPPC64() ? PPC::ZERO8 : PPC::ZERO,
6346 unsigned LIOpcode = Subtarget->isPPC64() ? PPC::LI8 : PPC::LI;
6361 unsigned SplatOp = (
Type == MVT::v16i8) ? PPC::VSPLTB : PPC::VSPLTH;
6362 unsigned SplatElemIndex =
6373 SDNode *LoadHigh = LoadLow;
6374 if (
Type == MVT::v8i16) {
6376 PPC::LVX, dl, MVT::v16i8, MVT::Other,
6378 LIOpcode, dl, MVT::i32,
6381 N->getOperand(1),
SDValue(LoadLow, 1)});
6385 transferMemOperands(
N, LoadHigh);
6406SDValue PPCDAGToDAGISel::combineToCMPB(SDNode *
N) {
6410 "Only OR nodes are supported for CMPB");
6413 if (!Subtarget->hasCMPB())
6416 if (
N->getValueType(0) != MVT::i32 &&
6417 N->getValueType(0) != MVT::i64)
6420 EVT VT =
N->getValueType(0);
6423 bool BytesFound[8] = {
false,
false,
false,
false,
false,
false,
false,
false};
6426 auto IsByteSelectCC = [
this](
SDValue O,
unsigned &
b,
6437 uint64_t PM =
O.getConstantOperandVal(2);
6438 uint64_t PAlt =
O.getConstantOperandVal(3);
6439 for (b = 0;
b < 8; ++
b) {
6441 if (PM && (PM & Mask) == PM && (PAlt & Mask) == PAlt)
6451 O.getConstantOperandVal(1) != 0) {
6452 SDValue Op0 =
O.getOperand(0), Op1 =
O.getOperand(1);
6484 uint64_t ULim =
O.getConstantOperandVal(1);
6485 if (ULim != (UINT64_C(1) << b*8))
6510 if (
Op.getConstantOperandVal(1) != (UINT64_C(0xFF) << (8*b)))
6525 unsigned Bits =
Op.getValueSizeInBits();
6528 if (
Op.getConstantOperandVal(1) != Bits-8)
6546 while (!
Queue.empty()) {
6549 for (
const SDValue &O :
V.getNode()->ops()) {
6555 }
else if (IsByteSelectCC(O, b, M,
A, OLHS, ORHS)) {
6559 BytesFound[
b] =
true;
6562 }
else if ((
LHS == ORHS &&
RHS == OLHS) ||
6563 (
RHS == ORHS &&
LHS == OLHS)) {
6564 BytesFound[
b] =
true;
6576 unsigned LastB = 0, BCnt = 0;
6577 for (
unsigned i = 0; i < 8; ++i)
6578 if (BytesFound[LastB]) {
6583 if (!LastB || BCnt < 2)
6588 if (
LHS.getValueType() != VT) {
6595 bool NonTrivialMask = ((int64_t)
Mask) != INT64_C(-1);
6596 if (NonTrivialMask && !Alt) {
6623void PPCDAGToDAGISel::foldBoolExts(
SDValue &Res, SDNode *&
N) {
6624 if (!Subtarget->useCRBits())
6632 if (
N->getOperand(0).getValueType() != MVT::i1)
6635 if (!
N->hasOneUse())
6639 EVT VT =
N->getValueType(0);
6646 SDNode *
User = *
N->user_begin();
6647 if (
User->getNumOperands() != 2)
6656 User->getValueType(0), {O0, O1});
6661 SDValue TrueRes = TryFold(ConstTrue);
6662 if (!TrueRes || TrueRes.
isUndef())
6664 SDValue FalseRes = TryFold(ConstFalse);
6665 if (!FalseRes || FalseRes.
isUndef())
6678 ConstTrue = TrueRes;
6679 ConstFalse = FalseRes;
6680 }
while (
N->hasOneUse());
6683void PPCDAGToDAGISel::PreprocessISelDAG() {
6686 bool MadeChange =
false;
6688 SDNode *
N = &*--Position;
6693 switch (
N->getOpcode()) {
6696 Res = combineToCMPB(
N);
6701 foldBoolExts(Res,
N);
6721void PPCDAGToDAGISel::PostprocessISelDAG() {
6728 PeepholePPC64ZExt();
6736bool PPCDAGToDAGISel::AllUsersSelectZero(SDNode *
N) {
6737 for (
const SDNode *User :
N->users()) {
6738 if (!
User->isMachineOpcode())
6740 if (
User->getMachineOpcode() != PPC::SELECT_I4 &&
6741 User->getMachineOpcode() != PPC::SELECT_I8)
6744 SDNode *Op1 =
User->getOperand(1).getNode();
6745 SDNode *Op2 =
User->getOperand(2).getNode();
6765void PPCDAGToDAGISel::SwapAllSelectUsers(SDNode *
N) {
6767 for (SDNode *User :
N->users()) {
6768 assert((
User->getMachineOpcode() == PPC::SELECT_I4 ||
6769 User->getMachineOpcode() == PPC::SELECT_I8) &&
6770 "Must have all select users");
6774 for (SDNode *User : ToReplace) {
6777 User->getValueType(0),
User->getOperand(0),
6778 User->getOperand(2),
6779 User->getOperand(1));
6787 ReplaceUses(User, ResNode);
6791void PPCDAGToDAGISel::PeepholeCROps() {
6795 for (SDNode &Node : CurDAG->
allnodes()) {
6797 if (!MachineNode || MachineNode->
use_empty())
6799 SDNode *ResNode = MachineNode;
6801 bool Op1Set =
false, Op1Unset =
false,
6803 Op2Set =
false, Op2Unset =
false,
6818 if (
Op.isMachineOpcode()) {
6819 if (
Op.getMachineOpcode() == PPC::CRSET)
6821 else if (
Op.getMachineOpcode() == PPC::CRUNSET)
6823 else if ((
Op.getMachineOpcode() == PPC::CRNOR &&
6824 Op.getOperand(0) ==
Op.getOperand(1)) ||
6825 Op.getMachineOpcode() == PPC::CRNOT)
6832 case PPC::SELECT_I4:
6833 case PPC::SELECT_I8:
6834 case PPC::SELECT_F4:
6835 case PPC::SELECT_F8:
6836 case PPC::SELECT_SPE:
6837 case PPC::SELECT_SPE4:
6838 case PPC::SELECT_VRRC:
6839 case PPC::SELECT_VSFRC:
6840 case PPC::SELECT_VSSRC:
6841 case PPC::SELECT_VSRC: {
6843 if (
Op.isMachineOpcode()) {
6844 if (
Op.getMachineOpcode() == PPC::CRSET)
6846 else if (
Op.getMachineOpcode() == PPC::CRUNSET)
6848 else if ((
Op.getMachineOpcode() == PPC::CRNOR &&
6849 Op.getOperand(0) ==
Op.getOperand(1)) ||
6850 Op.getMachineOpcode() == PPC::CRNOT)
6857 bool SelectSwap =
false;
6870 else if (Op1Unset || Op2Unset)
6872 ResNode = CurDAG->
getMachineNode(PPC::CRUNSET, SDLoc(MachineNode),
6876 ResNode = CurDAG->
getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
6882 ResNode = CurDAG->
getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
6886 else if (AllUsersSelectZero(MachineNode)) {
6887 ResNode = CurDAG->
getMachineNode(PPC::CRNAND, SDLoc(MachineNode),
6909 else if (Op1Unset || Op2Unset)
6925 else if (AllUsersSelectZero(MachineNode)) {
6936 else if (Op1Set || Op2Set)
6958 else if (AllUsersSelectZero(MachineNode)) {
6968 ResNode = CurDAG->
getMachineNode(PPC::CRUNSET, SDLoc(MachineNode),
6998 else if (AllUsersSelectZero(MachineNode)) {
7006 if (Op1Set || Op2Set)
7008 ResNode = CurDAG->
getMachineNode(PPC::CRUNSET, SDLoc(MachineNode),
7022 ResNode = CurDAG->
getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
7028 ResNode = CurDAG->
getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
7032 else if (AllUsersSelectZero(MachineNode)) {
7072 else if (AllUsersSelectZero(MachineNode)) {
7082 ResNode = CurDAG->
getMachineNode(PPC::CRUNSET, SDLoc(MachineNode),
7089 else if (Op1Unset || Op2Set)
7091 ResNode = CurDAG->
getMachineNode(PPC::CRUNSET, SDLoc(MachineNode),
7108 else if (AllUsersSelectZero(MachineNode)) {
7120 else if (Op1Set || Op2Unset)
7134 ResNode = CurDAG->
getMachineNode(PPC::CRNAND, SDLoc(MachineNode),
7144 else if (AllUsersSelectZero(MachineNode)) {
7145 ResNode = CurDAG->
getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
7151 case PPC::SELECT_I4:
7152 case PPC::SELECT_I8:
7153 case PPC::SELECT_F4:
7154 case PPC::SELECT_F8:
7155 case PPC::SELECT_SPE:
7156 case PPC::SELECT_SPE4:
7157 case PPC::SELECT_VRRC:
7158 case PPC::SELECT_VSFRC:
7159 case PPC::SELECT_VSSRC:
7160 case PPC::SELECT_VSRC:
7192 SwapAllSelectUsers(MachineNode);
7194 if (ResNode != MachineNode) {
7201 ReplaceUses(MachineNode, ResNode);
7207 }
while (IsModified);
7318 if (!Op0OK && !Op1OK)
7341 if (!Op0OK && !Op1OK)
7355void PPCDAGToDAGISel::PeepholePPC64ZExt() {
7356 if (!Subtarget->isPPC64())
7370 bool MadeChange =
false;
7372 SDNode *
N = &*--Position;
7374 if (
N->use_empty() || !
N->isMachineOpcode())
7377 if (
N->getMachineOpcode() != PPC::RLDICL)
7380 if (
N->getConstantOperandVal(1) != 0 ||
7381 N->getConstantOperandVal(2) != 32)
7410 SmallPtrSet<SDNode *, 16> ToPromote;
7416 bool OutsideUse =
false;
7417 for (SDNode *PN : ToPromote) {
7418 for (SDNode *UN : PN->users()) {
7419 if (!ToPromote.count(UN) && UN != ISR.
getNode()) {
7437 for (SDNode *PN : ToPromote) {
7439 switch (PN->getMachineOpcode()) {
7442 case PPC::RLWINM: NewOpcode = PPC::RLWINM8;
break;
7443 case PPC::RLWNM: NewOpcode = PPC::RLWNM8;
break;
7444 case PPC::SLW: NewOpcode = PPC::SLW8;
break;
7445 case PPC::SRW: NewOpcode = PPC::SRW8;
break;
7446 case PPC::LI: NewOpcode = PPC::LI8;
break;
7447 case PPC::LIS: NewOpcode = PPC::LIS8;
break;
7448 case PPC::LHBRX: NewOpcode = PPC::LHBRX8;
break;
7449 case PPC::LWBRX: NewOpcode = PPC::LWBRX8;
break;
7450 case PPC::CNTLZW: NewOpcode = PPC::CNTLZW8;
break;
7451 case PPC::CNTTZW: NewOpcode = PPC::CNTTZW8;
break;
7452 case PPC::RLWIMI: NewOpcode = PPC::RLWIMI8;
break;
7453 case PPC::OR: NewOpcode = PPC::OR8;
break;
7454 case PPC::SELECT_I4: NewOpcode = PPC::SELECT_I8;
break;
7455 case PPC::ORI: NewOpcode = PPC::ORI8;
break;
7456 case PPC::ORIS: NewOpcode = PPC::ORIS8;
break;
7457 case PPC::AND: NewOpcode = PPC::AND8;
break;
7459 NewOpcode = PPC::ANDI8_rec;
7461 case PPC::ANDIS_rec:
7462 NewOpcode = PPC::ANDIS8_rec;
7472 for (
const SDValue &V : PN->ops()) {
7473 if (!ToPromote.count(
V.getNode()) &&
V.getValueType() == MVT::i32 &&
7490 SDVTList VTs = PN->getVTList();
7491 for (
unsigned i = 0, ie = VTs.
NumVTs; i != ie; ++i)
7492 if (VTs.
VTs[i] == MVT::i32)
7525 if (!
N->isMachineOpcode())
7527 unsigned Opc =
N->getMachineOpcode();
7531 if (
Opc == PPC::XXPERMDIs) {
7533 N->getConstantOperandVal(1) == 2;
7534 }
else if (
Opc == PPC::XXPERMDI ||
Opc == PPC::XXSLDWI) {
7535 return N->getOperand(0) ==
N->getOperand(1) &&
7537 N->getConstantOperandVal(2) == 2;
7545 if (!
N->isMachineOpcode())
7547 unsigned Opc =
N->getMachineOpcode();
7596 auto SkipRCCopy = [](
SDValue V) {
7597 while (V->isMachineOpcode() &&
7598 V->getMachineOpcode() == TargetOpcode::COPY_TO_REGCLASS) {
7600 if (V->use_empty() || !V->user_begin()->isOnlyUserOf(V.getNode()))
7602 V = V->getOperand(0);
7604 return V.hasOneUse() ? V :
SDValue();
7607 SDValue VecOp = SkipRCCopy(
N->getOperand(0));
7627 if (GV->hasAttribute(
"aix-small-tls"))
7648 if (!(Subtarget.hasAIXSmallLocalDynamicTLS() ||
7689 if (
N->getMachineOpcode() != PPC::ADDI8)
7694 SDValue InitialADDI =
N->getOperand(0);
7705 assert(GA &&
"Expecting a valid GlobalAddressSDNode when folding addi into "
7706 "local-[exec|dynamic] accesses!");
7714 int Offset =
N->getConstantOperandVal(1);
7723void PPCDAGToDAGISel::PeepholePPC64() {
7727 SDNode *
N = &*--Position;
7729 if (
N->use_empty() || !
N->isMachineOpcode())
7740 unsigned StorageOpcode =
N->getMachineOpcode();
7741 bool RequiresMod4Offset =
false;
7743 switch (StorageOpcode) {
7748 case PPC::DFLOADf64:
7749 case PPC::DFLOADf32:
7750 RequiresMod4Offset =
true;
7766 case PPC::DFSTOREf64:
7767 case PPC::DFSTOREf32:
7768 RequiresMod4Offset =
true;
7790 if (!
Base.isMachineOpcode())
7794 bool ReplaceFlags =
true;
7806 switch (
Base.getMachineOpcode()) {
7814 ReplaceFlags =
false;
7816 case PPC::ADDIdtprelL:
7819 case PPC::ADDItlsldL:
7822 case PPC::ADDItocL8:
7837 int MaxDisplacement = 7;
7839 const GlobalValue *GV = GA->getGlobal();
7841 MaxDisplacement = std::min((
int)
Alignment.value() - 1, MaxDisplacement);
7844 bool UpdateHBase =
false;
7847 int Offset =
N->getConstantOperandVal(FirstOp);
7853 if (
Base.getMachineOpcode() != PPC::ADDItocL8)
7864 if (HImmOpnd != ImmOpnd)
7872 if (RequiresMod4Offset) {
7873 if (GlobalAddressSDNode *GA =
7875 const GlobalValue *GV = GA->getGlobal();
7890 if (RequiresMod4Offset && (
Offset % 4) != 0)
7898 }
else if (
Offset != 0) {
7906 assert(GA &&
"Expecting a valid GlobalAddressSDNode when folding "
7907 "addi into local-[exec|dynamic] accesses!");
7920 LLVM_DEBUG(
dbgs() <<
"Folding add-immediate into mem-op:\nBase: ");
7931 const GlobalValue *GV = GA->getGlobal();
7935 if (Alignment < 4 && (RequiresMod4Offset || (
Offset % 4) != 0)) {
7936 LLVM_DEBUG(
dbgs() <<
"Rejected this candidate for alignment.\n\n");
7940 }
else if (ConstantPoolSDNode *CP =
7950 Base.getOperand(0),
N->getOperand(3));
7960 if (
Base.getNode()->use_empty())
7970 return new PPCDAGToDAGISelLegacy(TM, OptLevel);
static bool isOpcWithIntImmediate(const SDNode *N, unsigned Opc, uint64_t &Imm)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
AMDGPU Register Bank Select
This file implements a class to represent arbitrary precision integral constant values and operations...
static bool isInt32Immediate(SDNode *N, unsigned &Imm)
isInt32Immediate - This method tests to see if the node is a 32-bit constant operand.
MachineBasicBlock MachineBasicBlock::iterator MBBI
Function Alias Analysis false
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
const HexagonInstrInfo * TII
static MaybeAlign getAlign(Value *Ptr)
Module.h This file contains the declarations for the Module class.
static constexpr Value * getValue(Ty &ValueOrUse)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
Machine Check Debug Module
Register const TargetRegisterInfo * TRI
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 cl::opt< bool > UseBitPermRewriter("ppc-use-bit-perm-rewriter", cl::init(true), cl::desc("use aggressive ppc isel for bit permutations"), cl::Hidden)
static bool isEligibleToFoldADDIForFasterLocalAccesses(SelectionDAG *DAG, SDValue ADDIToFold)
static bool canOptimizeTLSDFormToXForm(SelectionDAG *CurDAG, SDValue Base)
static cl::opt< bool > EnableBranchHint("ppc-use-branch-hint", cl::init(true), cl::desc("Enable static hinting of branches on ppc"), cl::Hidden)
static bool hasTocDataAttr(SDValue Val)
static void foldADDIForFasterLocalAccesses(SDNode *N, SelectionDAG *DAG)
static bool isThreadPointerAcquisitionNode(SDValue Base, SelectionDAG *CurDAG)
static bool PeepholePPC64ZExtGather(SDValue Op32, SmallPtrSetImpl< SDNode * > &ToPromote)
static bool isLaneInsensitive(SDValue N)
static unsigned allUsesTruncate(SelectionDAG *CurDAG, SDNode *N)
static CodeModel::Model getCodeModel(const PPCSubtarget &Subtarget, const TargetMachine &TM, const SDNode *Node)
static void reduceVSXSwap(SDNode *N, SelectionDAG *DAG)
static bool isOpcWithIntImmediate(SDNode *N, unsigned Opc, unsigned &Imm)
static PPC::Predicate getPredicateForSetCC(ISD::CondCode CC, const EVT &VT, const PPCSubtarget *Subtarget)
static unsigned getCRIdxForSetCC(ISD::CondCode CC, bool &Invert)
getCRIdxForSetCC - Return the index of the condition register field associated with the SetCC conditi...
static bool isInt64Immediate(SDNode *N, uint64_t &Imm)
isInt64Immediate - This method tests to see if the node is a 64-bit constant operand.
static bool isInt32Immediate(SDNode *N, unsigned &Imm)
isInt32Immediate - This method tests to see if the node is a 32-bit constant operand.
static unsigned getBranchHint(unsigned PCC, const FunctionLoweringInfo &FuncInfo, const SDValue &DestMBB)
static bool mayUseP9Setb(SDNode *N, const ISD::CondCode &CC, SelectionDAG *DAG, bool &NeedSwapOps, bool &IsUnCmp)
static cl::opt< bool > EnableTLSOpt("ppc-tls-opt", cl::init(true), cl::desc("Enable tls optimization peephole"), cl::Hidden)
static unsigned int getVCmpInst(MVT VecVT, ISD::CondCode CC, bool HasVSX, bool &Swap, bool &Negate)
static cl::opt< ICmpInGPRType > CmpInGPR("ppc-gpr-icmps", cl::Hidden, cl::init(ICGPR_All), cl::desc("Specify the types of comparisons to emit GPR-only code for."), cl::values(clEnumValN(ICGPR_None, "none", "Do not modify integer comparisons."), clEnumValN(ICGPR_All, "all", "All possible int comparisons in GPRs."), clEnumValN(ICGPR_I32, "i32", "Only i32 comparisons in GPRs."), clEnumValN(ICGPR_I64, "i64", "Only i64 comparisons in GPRs."), clEnumValN(ICGPR_NonExtIn, "nonextin", "Only comparisons where inputs don't need [sz]ext."), clEnumValN(ICGPR_Zext, "zext", "Only comparisons with zext result."), clEnumValN(ICGPR_ZextI32, "zexti32", "Only i32 comparisons with zext result."), clEnumValN(ICGPR_ZextI64, "zexti64", "Only i64 comparisons with zext result."), clEnumValN(ICGPR_Sext, "sext", "Only comparisons with sext result."), clEnumValN(ICGPR_SextI32, "sexti32", "Only i32 comparisons with sext result."), clEnumValN(ICGPR_SextI64, "sexti64", "Only i64 comparisons with sext result.")))
static SDNode * selectI64ImmDirectPrefix(SelectionDAG *CurDAG, const SDLoc &dl, uint64_t Imm, unsigned &InstCnt)
static SDNode * selectI64ImmDirect(SelectionDAG *CurDAG, const SDLoc &dl, uint64_t Imm, unsigned &InstCnt)
static bool hasAIXSmallTLSAttr(SDValue Val)
static cl::opt< bool > BPermRewriterNoMasking("ppc-bit-perm-rewriter-stress-rotates", cl::desc("stress rotate selection in aggressive ppc isel for " "bit permutations"), cl::Hidden)
static bool isSWTestOp(SDValue N)
static SDNode * selectI64Imm(SelectionDAG *CurDAG, const SDLoc &dl, uint64_t Imm, unsigned *InstCnt=nullptr)
static bool isVSXSwap(SDValue N)
static uint32_t findContiguousZerosAtLeast(uint64_t Imm, unsigned Num)
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
LLVM_ABI APInt rotr(unsigned rotateAmt) const
Rotate right by rotateAmt.
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
MachineBasicBlock * getBasicBlock() const
LLVM Basic Block Representation.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
LLVM_ABI BranchProbability getEdgeProbability(const BasicBlock *Src, unsigned IndexInSuccessors) const
Get an edge's probability, relative to other out-edges of the Src.
int64_t getSExtValue() const
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
BranchProbabilityInfo * BPI
MachineBasicBlock * MBB
MBB - The current block.
FunctionPass class - This class is used to implement most global optimizations.
unsigned getTargetFlags() const
const GlobalValue * getGlobal() const
Module * getParent()
Get the module that this global value is contained inside of...
bool hasAttribute(Attribute::AttrKind Kind) const
Return true if the attribute exists.
static StringRef getMemConstraintName(ConstraintCode C)
LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
This class is used to represent ISD::LOAD nodes.
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
unsigned getID() const
getID() - Return the register class ID number.
const MDOperand & getOperand(unsigned I) const
unsigned getNumOperands() const
Return number of MDNode operands.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
MachineInstrBundleIterator< MachineInstr > iterator
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.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
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.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
void setROPProtectionHashSaveIndex(int Idx)
static int getRecordFormOpcode(unsigned Opcode)
bool is32BitELFABI() const
MVT getScalarIntVT() const
const PPCInstrInfo * getInstrInfo() const override
MCRegister getThreadPointerRegister() const
bool isLittleEndian() const
CodeModel::Model getCodeModel(const TargetMachine &TM, const GlobalValue *GV) const
Calculates the effective code model for argument GV.
Common code between 32-bit and 64-bit PowerPC targets.
Wrapper class representing virtual and physical registers.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.
LLVM_ABI void dump() const
Dump this node, for debugging.
bool hasOneUse() const
Return true if there is exactly one use of this node.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
bool use_empty() const
Return true if there are no uses of this node.
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
SDVTList getVTList() const
const SDValue & getOperand(unsigned Num) const
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node, in exactly one operand.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
bool isMachineOpcode() const
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
unsigned getMachineOpcode() const
unsigned getOpcode() const
unsigned getNumOperands() const
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
virtual bool runOnMachineFunction(MachineFunction &mf)
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
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 SDNode * SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT)
These are used for target selectors to mutate the specified node to have the specified return type,...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
const TargetLowering & getTargetLoweringInfo() const
allnodes_const_iterator allnodes_begin() const
allnodes_const_iterator allnodes_end() const
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...
LLVM_ABI void setNodeMemRefs(MachineSDNode *N, ArrayRef< MachineMemOperand * > NewMemRefs)
Mutate the specified machine node's memory references to the provided list.
const DataLayout & getDataLayout() const
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 getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
LLVM_ABI void RemoveDeadNodes()
This method deletes all unreachable nodes in the SelectionDAG.
LLVM_ABI void RemoveDeadNode(SDNode *N)
Remove the specified node from the system.
LLVM_ABI SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
LLVM_ABI SDValue FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDValue > Ops, SDNodeFlags Flags=SDNodeFlags())
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...
iterator_range< allnodes_iterator > allnodes()
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 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
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 bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
LLVM_ABI SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
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.
ilist< SDNode >::iterator allnodes_iterator
int getMaskElt(unsigned Idx) const
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
void insert_range(Range &&R)
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.
void push_back(const T &Elt)
This class is used to represent ISD::STORE nodes.
TargetInstrInfo - Interface to description of machine instruction set.
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...
Primary interface to the complete machine description for the target machine.
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
bool isPositionIndependent() const
CodeModel::Model getCodeModel() const
Returns the code model.
virtual const TargetLowering * getTargetLowering() const
A Use represents the edge between a Value definition and its users.
LLVM_ABI unsigned getOperandNo() const
Return the operand # of this use in its User.
User * getUser() const
Returns the User that contains this Use.
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
#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 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.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ BSWAP
Byte Swap and Counting operators.
@ 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.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ BR_CC
BR_CC - Conditional branch.
@ BRIND
BRIND - Indirect branch.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ 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) ...
@ TargetConstant
TargetConstant* - Like Constant*, but the DAG does not do any folding, simplification,...
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
LLVM_ABI CondCode getSetCCInverse(CondCode Operation, EVT Type)
Return the operation corresponding to !(X op Y), where 'op' is a valid SetCC operation.
bool isBitwiseLogicOp(unsigned Opcode)
Whether this is bitwise logic opcode.
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...
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
bool isUnsignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs an unsigned comparison when used with intege...
@ MO_TLSLD_FLAG
MO_TLSLD_FLAG - If this bit is set the symbol reference is relative to TLS Local Dynamic model.
@ MO_PLT
On PPC, the 12 bits are not enough for all target operand flags.
@ MO_DTPREL_LO
These values identify relocations on immediates folded into memory operations.
@ MO_TPREL_FLAG
MO_TPREL_FLAG - If this bit is set, the symbol reference is relative to the thread pointer and the sy...
@ BDNZ
CHAIN = BDNZ CHAIN, DESTBB - These are used to create counter-based loops.
@ ANDI_rec_1_EQ_BIT
i1 = ANDI_rec_1_[EQ|GT]_BIT(i32 or i64 x) - Represents the result of the eq or gt bit of CR0 after ex...
@ 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.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
@ User
could "use" a pointer
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
bool operator<(int64_t V1, const APSInt &V2)
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.
@ Define
Register definition.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
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 T maskLeadingOnes(unsigned N)
Create a bitmask with the N left-most bits set to 1, and all other bits set to 0.
@ O1
Optimize quickly without destroying debuggability.
@ O0
Disable as many optimizations as possible.
static bool isRunOfOnes64(uint64_t Val, unsigned &MB, unsigned &ME)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
auto dyn_cast_or_null(const Y &Val)
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
LLVM_ABI bool isBitwiseNot(SDValue V, bool AllowUndefs=false)
Returns true if V is a bitwise not operation.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
void sort(IteratorTy Start, IteratorTy End)
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)
constexpr bool isMask_64(uint64_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
int countl_one(T Value)
Count the number of ones from the most significant bit to the first zero bit.
CodeGenOptLevel
Code generation optimization level.
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...
FunctionPass * createPPCISelDag(PPCTargetMachine &TM, CodeGenOptLevel OL)
createPPCISelDag - This pass converts a legalized DAG into a PowerPC-specific DAG,...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Xor
Bitwise or logical XOR of integers.
@ Sub
Subtraction of integers.
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isOneConstant(SDValue V)
Returns true if V is a constant integer one.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
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.
MCRegisterClass TargetRegisterClass
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
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.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isInteger() const
Return true if this is an integer or a vector integer type.