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.");
92 cl::desc(
"expose the ANDI glue bug on PPC"),
97 cl::desc(
"use aggressive ppc isel for bit permutations"),
100 "ppc-bit-perm-rewriter-stress-rotates",
101 cl::desc(
"stress rotate selection in aggressive ppc isel for "
106 "ppc-use-branch-hint",
cl::init(
true),
107 cl::desc(
"Enable static hinting of branches on ppc"),
112 cl::desc(
"Enable tls optimization peephole"),
121 cl::desc(
"Specify the types of comparisons to emit GPR-only code for."),
127 "Only comparisons where inputs don't need [sz]ext."),
130 "Only i32 comparisons with zext result."),
132 "Only i64 comparisons with zext result."),
135 "Only i32 comparisons with sext result."),
137 "Only i64 comparisons with sext result.")));
148 unsigned GlobalBaseReg = 0;
151 PPCDAGToDAGISel() =
delete;
161 if (Subtarget->hasROPProtect()) {
166 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
175 void PreprocessISelDAG()
override;
176 void PostprocessISelDAG()
override;
180 inline SDValue getI16Imm(
unsigned Imm,
const SDLoc &dl) {
181 return CurDAG->getTargetConstant(
Imm, dl, MVT::i16);
186 inline SDValue getI32Imm(
unsigned Imm,
const SDLoc &dl) {
187 return CurDAG->getTargetConstant(
Imm, dl, MVT::i32);
193 return CurDAG->getTargetConstant(
Imm, dl, MVT::i64);
197 inline SDValue getSmallIPtrImm(int64_t
Imm,
const SDLoc &dl) {
198 return CurDAG->getSignedTargetConstant(
199 Imm, dl, PPCLowering->getPointerTy(CurDAG->getDataLayout()));
204 static bool isRotateAndMask(SDNode *
N,
unsigned Mask,
bool isShiftMask,
205 unsigned &SH,
unsigned &MB,
unsigned &ME);
209 SDNode *getGlobalBaseReg();
211 void selectFrameIndex(SDNode *SN, SDNode *
N, int64_t
Offset = 0);
215 void Select(SDNode *
N)
override;
217 bool tryBitfieldInsert(SDNode *
N);
218 bool tryBitPermutation(SDNode *
N);
219 bool tryIntCompareInGPR(SDNode *
N);
224 bool tryTLSXFormLoad(LoadSDNode *
N);
228 bool tryTLSXFormStore(StoreSDNode *
N);
251 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
259 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
267 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
275 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
282 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
290 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
298 return PPCLowering->SelectForceXFormMode(
N, Disp,
Base, *CurDAG) ==
309 return PPCLowering->SelectAddressRegReg(
N,
Base, Index, *CurDAG,
320 return PPCLowering->SelectAddressRegReg(
N,
Base, Index, *CurDAG,
331 return PPCLowering->SelectAddressRegReg(
N,
Base, Index, *CurDAG,
338 return PPCLowering->SelectAddressRegRegOnly(
N,
Base, Index, *CurDAG);
347 return PPCLowering->SelectAddressRegImm(
N, Disp,
Base, *CurDAG,
355 return PPCLowering->SelectAddressRegImm(
N, Disp,
Base, *CurDAG,
Align(4));
362 return PPCLowering->SelectAddressRegImm(
N, Disp,
Base, *CurDAG,
370 return PPCLowering->SelectAddressRegImm34(
N, Disp,
Base, *CurDAG);
380 return PPCLowering->SelectAddressPCRel(
N,
Base);
388 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
390 std::vector<SDValue> &OutOps)
override {
391 switch(ConstraintID) {
393 errs() <<
"ConstraintID: "
396 case InlineAsm::ConstraintCode::es:
397 case InlineAsm::ConstraintCode::m:
398 case InlineAsm::ConstraintCode::o:
399 case InlineAsm::ConstraintCode::Q:
400 case InlineAsm::ConstraintCode::Z:
401 case InlineAsm::ConstraintCode::Zy:
404 const TargetInstrInfo *
TII = Subtarget->getInstrInfo();
408 SDValue RC = CurDAG->getTargetConstant(TRC->
getID(), dl, MVT::i32);
410 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
411 dl,
Op.getValueType(),
414 OutOps.push_back(NewOp);
421#include "PPCGenDAGISel.inc"
424 bool trySETCC(SDNode *
N);
425 bool tryFoldSWTestBRCC(SDNode *
N);
426 bool trySelectLoopCountIntrinsic(SDNode *
N);
427 bool tryAsSingleRLDICL(SDNode *
N);
428 bool tryAsSingleRLDCL(SDNode *
N);
429 bool tryAsSingleRLDICR(SDNode *
N);
430 bool tryAsSingleRLWINM(SDNode *
N);
431 bool tryAsSingleRLWINM8(SDNode *
N);
432 bool tryAsSingleRLWIMI(SDNode *
N);
433 bool tryAsPairOfRLDICL(SDNode *
N);
434 bool tryAsSingleRLDIMI(SDNode *
N);
436 void PeepholePPC64();
437 void PeepholePPC64ZExt();
438 void PeepholeCROps();
441 void foldBoolExts(
SDValue &Res, SDNode *&
N);
443 bool AllUsersSelectZero(SDNode *
N);
444 void SwapAllSelectUsers(SDNode *
N);
446 bool isOffsetMultipleOf(SDNode *
N,
unsigned Val)
const;
447 void transferMemOperands(SDNode *
N, SDNode *Result);
453 explicit PPCDAGToDAGISelLegacy(PPCTargetMachine &tm,
455 : SelectionDAGISelLegacy(
456 ID, std::make_unique<PPCDAGToDAGISel>(tm, OptLevel)) {}
460char PPCDAGToDAGISelLegacy::ID = 0;
467SDNode *PPCDAGToDAGISel::getGlobalBaseReg() {
468 if (!GlobalBaseReg) {
476 if (PPCLowering->getPointerTy(CurDAG->getDataLayout()) == MVT::i32) {
489 TII.get(PPC::UpdateGBR), GlobalBaseReg)
495 RegInfo->createVirtualRegister(&PPC::GPRC_and_GPRC_NOR0RegClass);
515 return CurDAG->getRegister(GlobalBaseReg,
516 PPCLowering->getPointerTy(CurDAG->getDataLayout()))
556 if (
N->getOpcode() ==
ISD::Constant &&
N->getValueType(0) == MVT::i32) {
557 Imm =
N->getAsZExtVal();
566 if (
N->getOpcode() ==
ISD::Constant &&
N->getValueType(0) == MVT::i64) {
567 Imm =
N->getAsZExtVal();
618 if (std::max(TProb, FProb) / Threshold < std::min(TProb, FProb))
622 <<
"::" << BB->
getName() <<
"'\n"
623 <<
" -> " <<
TBB->getName() <<
": " << TProb <<
"\n"
624 <<
" -> " << FBB->
getName() <<
": " << FProb <<
"\n");
640 return N->getOpcode() ==
Opc
647 SDValue TFI = CurDAG->getTargetFrameIndex(FI,
N->getValueType(0));
648 unsigned Opc =
N->getValueType(0) == MVT::i32 ? PPC::ADDI : PPC::ADDI8;
650 CurDAG->SelectNodeTo(SN,
Opc,
N->getValueType(0), TFI,
651 getSmallIPtrImm(
Offset, dl));
653 ReplaceNode(SN, CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0), TFI,
654 getSmallIPtrImm(
Offset, dl)));
657bool PPCDAGToDAGISel::isRotateAndMask(SDNode *
N,
unsigned Mask,
658 bool isShiftMask,
unsigned &SH,
659 unsigned &MB,
unsigned &ME) {
662 if (
N->getValueType(0) != MVT::i32)
666 unsigned Indeterminant = ~0;
667 unsigned Opcode =
N->getOpcode();
668 if (
N->getNumOperands() != 2 ||
674 if (isShiftMask)
Mask =
Mask << Shift;
676 Indeterminant = ~(0xFFFFFFFFu << Shift);
679 if (isShiftMask)
Mask =
Mask >> Shift;
681 Indeterminant = ~(0xFFFFFFFFu >> Shift);
691 if (Mask && !(Mask & Indeterminant)) {
703 Base.getOpcode() == PPCISD::ADD_TLS &&
704 "Only expecting the ADD_TLS instruction to acquire the thread pointer!");
708 unsigned ADDTLSOp1Opcode = ADDTLSOp1.getOpcode();
717 if (ADDTLSOp1Opcode == PPCISD::LD_GOT_TPREL_L)
722 if (LD && LD->getBasePtr().getOpcode() == PPCISD::MAT_PCREL_ADDR)
728 if (ADDTLSOp1Opcode == PPCISD::GET_TPOINTER)
753 if (
Base.getOpcode() != PPCISD::ADD_TLS)
755 for (
auto *ADDTLSUse :
Base.getNode()->users()) {
760 if (LD->getSrcValueOffset() != 0 || !LD->getOffset().isUndef())
763 if (ST->getSrcValueOffset() != 0 || !ST->getOffset().isUndef())
769 if (
Base.getOperand(1).getOpcode() == PPCISD::TLS_LOCAL_EXEC_MAT_ADDR)
778bool PPCDAGToDAGISel::tryTLSXFormStore(StoreSDNode *ST) {
784 EVT MemVT =
ST->getMemoryVT();
785 EVT RegVT =
ST->getValue().getValueType();
792 Opcode = (RegVT == MVT::i32) ? PPC::STBXTLS_32 : PPC::STBXTLS;
796 Opcode = (RegVT == MVT::i32) ? PPC::STHXTLS_32 : PPC::STHXTLS;
800 Opcode = (RegVT == MVT::i32) ? PPC::STWXTLS_32 : PPC::STWXTLS;
804 Opcode = PPC::STDXTLS;
808 Opcode = PPC::STFSXTLS;
812 Opcode = PPC::STFDXTLS;
817 SDVTList VTs =
ST->getVTList();
820 SDNode *MN = CurDAG->getMachineNode(Opcode, dl, VTs,
Ops);
821 transferMemOperands(ST, MN);
826bool PPCDAGToDAGISel::tryTLSXFormLoad(LoadSDNode *LD) {
832 EVT MemVT =
LD->getMemoryVT();
833 EVT RegVT =
LD->getValueType(0);
840 Opcode = (RegVT == MVT::i32) ? PPC::LBZXTLS_32 : PPC::LBZXTLS;
844 if (RegVT == MVT::i32)
845 Opcode = isSExt ? PPC::LHAXTLS_32 : PPC::LHZXTLS_32;
847 Opcode = isSExt ? PPC::LHAXTLS : PPC::LHZXTLS;
851 if (RegVT == MVT::i32)
852 Opcode = isSExt ? PPC::LWAXTLS_32 : PPC::LWZXTLS_32;
854 Opcode = isSExt ? PPC::LWAXTLS : PPC::LWZXTLS;
858 Opcode = PPC::LDXTLS;
862 Opcode = PPC::LFSXTLS;
866 Opcode = PPC::LFDXTLS;
871 SDVTList VTs =
LD->getVTList();
873 SDNode *MN = CurDAG->getMachineNode(Opcode, dl, VTs,
Ops);
874 transferMemOperands(LD, MN);
881bool PPCDAGToDAGISel::tryBitfieldInsert(SDNode *
N) {
892 KnownBits LKnown = CurDAG->computeKnownBits(Op0);
893 KnownBits RKnown = CurDAG->computeKnownBits(Op1);
898 if ((TargetMask | InsertMask) == 0xFFFFFFFF) {
901 unsigned Value, SH = 0;
902 TargetMask = ~TargetMask;
903 InsertMask = ~InsertMask;
937 KnownBits MKnown = CurDAG->computeKnownBits(Op1.
getOperand(1));
951 SDValue Ops[] = { Op0, Op1, getI32Imm(SH, dl), getI32Imm(MB, dl),
953 ReplaceNode(
N, CurDAG->getMachineNode(PPC::RLWIMI, dl, MVT::i32,
Ops));
961 unsigned MaxTruncation = 0;
968 User->isMachineOpcode() ?
User->getMachineOpcode() :
User->getOpcode();
972 if (
User->isMachineOpcode())
974 MaxTruncation = std::max(MaxTruncation,
975 (
unsigned)
User->getValueType(0).getSizeInBits());
978 if (
User->isMachineOpcode())
984 MaxTruncation = std::max(MaxTruncation, MemVTSize);
993 MaxTruncation = std::max(MaxTruncation, 32u);
1001 MaxTruncation = std::max(MaxTruncation, 16u);
1009 MaxTruncation = std::max(MaxTruncation, 8u);
1013 return MaxTruncation;
1021 if ((HiTZ + LoLZ) >= Num)
1035 SDNode *Result =
nullptr;
1038 auto getI32Imm = [CurDAG, dl](
unsigned Imm) {
1052 if (TZ > 15 && (LZ > 32 || LO > 32))
1054 getI32Imm((
Imm >> 16) & 0xffff));
1058 assert(LZ < 64 &&
"Unexpected leading zeros here.");
1065 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
1066 Result = CurDAG->
getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
1068 getI32Imm(
Imm & 0xffff));
1076 if ((LZ + FO + TZ) > 48) {
1078 getI32Imm((
Imm >> TZ) & 0xffff));
1080 getI32Imm(TZ), getI32Imm(LZ));
1097 if ((LZ + TO) > 48) {
1101 assert(LZ <= 32 &&
"Unexpected shift value.");
1103 getI32Imm((
Imm >> (48 - LZ) & 0xffff)));
1105 getI32Imm(48 - LZ), getI32Imm(LZ));
1123 if ((LZ + FO + TO) > 48) {
1125 getI32Imm((
Imm >> TO) & 0xffff));
1127 getI32Imm(TO), getI32Imm(LZ));
1133 if (LZ == 32 && ((Lo32 & 0x8000) == 0)) {
1135 getI32Imm(Lo32 & 0xffff));
1137 getI32Imm(Lo32 >> 16));
1161 getI32Imm(RotImm & 0xffff));
1163 getI32Imm(Shift), getI32Imm(0));
1170 uint64_t ImmHi16 = (Lo32 >> 16) & 0xffff;
1174 CurDAG->
getMachineNode(PPC::LI8, dl, MVT::i64, getI32Imm(ImmLo16));
1177 CurDAG->
getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(ImmHi16));
1181 CurDAG->
getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(ImmHi16));
1183 SDValue(Result, 0), getI32Imm(ImmLo16));
1200 if ((LZ + FO + TZ) > 32) {
1202 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
1203 Result = CurDAG->
getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
1205 getI32Imm((
Imm >> TZ) & 0xffff));
1207 getI32Imm(TZ), getI32Imm(LZ));
1214 if ((LZ + TO) > 32) {
1218 assert(LZ <= 32 &&
"Unexpected shift value.");
1220 getI32Imm((
Imm >> (48 - LZ)) & 0xffff));
1222 getI32Imm((
Imm >> (32 - LZ)) & 0xffff));
1224 getI32Imm(32 - LZ), getI32Imm(LZ));
1232 if ((LZ + FO + TO) > 32) {
1234 getI32Imm((
Imm >> (TO + 16)) & 0xffff));
1236 getI32Imm((
Imm >> TO) & 0xffff));
1238 getI32Imm(TO), getI32Imm(LZ));
1250 uint64_t ImmHi16 = (RotImm >> 16) & 0xffff;
1251 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
1252 Result = CurDAG->
getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
1254 getI32Imm(RotImm & 0xffff));
1256 getI32Imm(Shift), getI32Imm(0));
1277 auto getI32Imm = [CurDAG, dl](
unsigned Imm) {
1296 SDNode *Result =
nullptr;
1303 if ((LZ + FO + TZ) > 30) {
1307 getI64Imm(Extended.getZExtValue()));
1309 getI32Imm(TZ), getI32Imm(LZ));
1325 if ((LZ + TO) > 30) {
1326 APInt SignedInt34 =
APInt(34, (
Imm >> (30 - LZ)) & 0x3ffffffff);
1329 getI64Imm(Extended.getZExtValue()));
1331 getI32Imm(30 - LZ), getI32Imm(LZ));
1338 if ((LZ + FO + TO) > 30) {
1342 getI64Imm(Extended.getZExtValue()));
1344 getI32Imm(TO), getI32Imm(LZ));
1356 for (
unsigned Shift = 0; Shift < 63; ++Shift) {
1360 CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(RotImm));
1362 SDValue(Result, 0), getI32Imm(Shift),
1370 Result = CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(Hi32));
1380 CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(Hi32));
1382 CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(Lo32));
1389 unsigned *InstCnt =
nullptr) {
1390 unsigned InstCntDirect = 0;
1401 if (
Subtarget.hasPrefixInstrs() && InstCntDirect != 1) {
1402 unsigned InstCntDirectP = 0;
1409 if (ResultP && (!Result || InstCntDirectP < InstCntDirect)) {
1411 *InstCnt = InstCntDirectP;
1418 *InstCnt = InstCntDirect;
1421 auto getI32Imm = [CurDAG, dl](
unsigned Imm) {
1430 if (Hi16OfLo32 && Lo16OfLo32) {
1433 bool IsSelected =
false;
1437 CurDAG->
getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(Hi16));
1439 SDValue(Result, 0), getI32Imm(Lo16));
1445 if (Hi16OfHi32 == Lo16OfHi32 && Lo16OfHi32 == Lo16OfLo32) {
1447 Result = getSplat(Hi16OfLo32, Lo16OfLo32);
1452 }
else if (Hi16OfHi32 == Hi16OfLo32 && Hi16OfLo32 == Lo16OfLo32) {
1454 Result = getSplat(Hi16OfHi32, Lo16OfHi32);
1457 getI32Imm(16), getI32Imm(31)};
1459 }
else if (Lo16OfHi32 == Lo16OfLo32 && Hi16OfLo32 == Lo16OfLo32) {
1461 Result = getSplat(Hi16OfHi32, Lo16OfHi32);
1464 getI32Imm(0), getI32Imm(15)};
1467 if (IsSelected ==
true) {
1480 SDValue(Result, 0), getI32Imm(Hi16OfLo32));
1485 getI32Imm(Lo16OfLo32));
1489 *InstCnt = InstCntDirect;
1498 int64_t
Imm =
N->getAsZExtVal();
1510class BitPermutationSelector {
1525 VariableKnownToBeZero
1528 ValueBit(
SDValue V,
unsigned I, Kind K = Variable)
1530 ValueBit(Kind K = Variable) :
Idx(UINT32_MAX), K(K) {}
1533 return K == ConstZero || K == VariableKnownToBeZero;
1536 bool hasValue()
const {
1537 return K == Variable || K == VariableKnownToBeZero;
1541 assert(hasValue() &&
"Cannot get the value of a constant bit");
1545 unsigned getValueBitIndex()
const {
1546 assert(hasValue() &&
"Cannot get the value bit index of a constant bit");
1555 unsigned StartIdx, EndIdx;
1565 bool Repl32Coalesced;
1567 BitGroup(
SDValue V,
unsigned R,
unsigned S,
unsigned E)
1568 :
V(
V), RLAmt(
R), StartIdx(S), EndIdx(
E), Repl32(
false), Repl32CR(
false),
1569 Repl32Coalesced(
false) {
1570 LLVM_DEBUG(
dbgs() <<
"\tbit group for " <<
V.getNode() <<
" RLAmt = " << R
1571 <<
" [" << S <<
", " <<
E <<
"]\n");
1577 struct ValueRotInfo {
1579 unsigned RLAmt = std::numeric_limits<unsigned>::max();
1580 unsigned NumGroups = 0;
1581 unsigned FirstGroupStartIdx = std::numeric_limits<unsigned>::max();
1582 bool Repl32 =
false;
1584 ValueRotInfo() =
default;
1592 if (Repl32 <
Other.Repl32)
1594 else if (Repl32 >
Other.Repl32)
1596 else if (NumGroups >
Other.NumGroups)
1598 else if (NumGroups <
Other.NumGroups)
1600 else if (RLAmt == 0 &&
Other.RLAmt != 0)
1602 else if (RLAmt != 0 &&
Other.RLAmt == 0)
1604 else if (FirstGroupStartIdx <
Other.FirstGroupStartIdx)
1610 using ValueBitsMemoizedValue = std::pair<bool, SmallVector<ValueBit, 64>>;
1611 using ValueBitsMemoizer =
1612 DenseMap<SDValue, std::unique_ptr<ValueBitsMemoizedValue>>;
1613 ValueBitsMemoizer Memoizer;
1619 std::pair<bool, SmallVector<ValueBit, 64> *> getValueBits(
SDValue V,
1621 auto &ValueEntry = Memoizer[
V];
1623 return std::make_pair(ValueEntry->first, &ValueEntry->second);
1624 ValueEntry.reset(
new ValueBitsMemoizedValue());
1625 bool &Interesting = ValueEntry->first;
1627 Bits.resize(NumBits);
1629 switch (
V.getOpcode()) {
1634 unsigned RotAmt =
V.getConstantOperandVal(1) & (NumBits - 1);
1636 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1638 for (
unsigned i = 0; i < NumBits; ++i)
1639 Bits[i] = LHSBits[i < RotAmt ? i + (NumBits - RotAmt) : i - RotAmt];
1641 return std::make_pair(Interesting =
true, &Bits);
1648 unsigned ShiftAmt =
V.getConstantOperandVal(1) & ((NumBits << 1) - 1);
1650 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1652 if (ShiftAmt >= NumBits) {
1653 for (
unsigned i = 0; i < NumBits; ++i)
1654 Bits[i] = ValueBit(ValueBit::ConstZero);
1656 for (
unsigned i = ShiftAmt; i < NumBits; ++i)
1657 Bits[i] = LHSBits[i - ShiftAmt];
1658 for (
unsigned i = 0; i < ShiftAmt; ++i)
1659 Bits[i] = ValueBit(ValueBit::ConstZero);
1662 return std::make_pair(Interesting =
true, &Bits);
1669 unsigned ShiftAmt =
V.getConstantOperandVal(1) & ((NumBits << 1) - 1);
1671 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1673 if (ShiftAmt >= NumBits) {
1674 for (
unsigned i = 0; i < NumBits; ++i)
1675 Bits[i] = ValueBit(ValueBit::ConstZero);
1677 for (
unsigned i = 0; i < NumBits - ShiftAmt; ++i)
1678 Bits[i] = LHSBits[i + ShiftAmt];
1679 for (
unsigned i = NumBits - ShiftAmt; i < NumBits; ++i)
1680 Bits[i] = ValueBit(ValueBit::ConstZero);
1683 return std::make_pair(Interesting =
true, &Bits);
1695 std::tie(Interesting, LHSBits) = getValueBits(
V.getOperand(0), NumBits);
1697 for (
unsigned i = 0; i < NumBits; ++i)
1698 if (((Mask >> i) & 1) == 1)
1699 Bits[i] = (*LHSBits)[i];
1703 if ((*LHSBits)[i].
isZero())
1704 Bits[i] = (*LHSBits)[i];
1706 Bits[i] = ValueBit(ValueBit::ConstZero);
1709 return std::make_pair(Interesting, &Bits);
1713 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1714 const auto &RHSBits = *getValueBits(
V.getOperand(1), NumBits).second;
1716 bool AllDisjoint =
true;
1718 unsigned LastIdx = 0;
1719 for (
unsigned i = 0; i < NumBits; ++i) {
1727 if (LHSBits[i].hasValue() && LHSBits[i].
getValue() == LastVal &&
1728 LHSBits[i].getValueBitIndex() == LastIdx + 1)
1729 Bits[i] = LHSBits[i];
1730 else if (RHSBits[i].hasValue() && RHSBits[i].
getValue() == LastVal &&
1731 RHSBits[i].getValueBitIndex() == LastIdx + 1)
1732 Bits[i] = RHSBits[i];
1734 Bits[i] = ValueBit(ValueBit::ConstZero);
1736 else if (LHSBits[i].
isZero())
1737 Bits[i] = RHSBits[i];
1738 else if (RHSBits[i].
isZero())
1739 Bits[i] = LHSBits[i];
1741 AllDisjoint =
false;
1745 if (Bits[i].hasValue()) {
1746 LastVal =
Bits[i].getValue();
1747 LastIdx =
Bits[i].getValueBitIndex();
1750 if (LastVal) LastVal =
SDValue();
1758 return std::make_pair(Interesting =
true, &Bits);
1762 if (
V.getValueType() != MVT::i64 ||
1763 V.getOperand(0).getValueType() != MVT::i32)
1767 const unsigned NumOperandBits = 32;
1768 std::tie(Interesting, LHSBits) = getValueBits(
V.getOperand(0),
1771 for (
unsigned i = 0; i < NumOperandBits; ++i)
1772 Bits[i] = (*LHSBits)[i];
1774 for (
unsigned i = NumOperandBits; i < NumBits; ++i)
1775 Bits[i] = ValueBit(ValueBit::ConstZero);
1777 return std::make_pair(Interesting, &Bits);
1780 EVT
FromType =
V.getOperand(0).getValueType();
1781 EVT ToType =
V.getValueType();
1783 if (FromType != MVT::i64 || ToType != MVT::i32)
1785 const unsigned NumAllBits =
FromType.getSizeInBits();
1787 std::tie(Interesting, InBits) = getValueBits(
V.getOperand(0),
1793 bool UseUpper32bit =
false;
1794 for (
unsigned i = 0; i < NumValidBits; ++i)
1795 if ((*InBits)[i].hasValue() && (*InBits)[i].getValueBitIndex() >= 32) {
1796 UseUpper32bit =
true;
1802 for (
unsigned i = 0; i < NumValidBits; ++i)
1803 Bits[i] = (*InBits)[i];
1805 return std::make_pair(Interesting, &Bits);
1811 std::tie(Interesting, LHSBits) = getValueBits(
V.getOperand(0),
1815 const unsigned NumValidBits =
FromType.getSizeInBits();
1816 for (
unsigned i = 0; i < NumValidBits; ++i)
1817 Bits[i] = (*LHSBits)[i];
1821 for (
unsigned i = NumValidBits; i < NumBits; ++i)
1822 Bits[i] = (*LHSBits)[i].hasValue()
1823 ? ValueBit((*LHSBits)[i].
getValue(),
1824 (*LHSBits)[i].getValueBitIndex(),
1825 ValueBit::VariableKnownToBeZero)
1826 : ValueBit(ValueBit::ConstZero);
1828 return std::make_pair(Interesting, &Bits);
1833 EVT VT =
LD->getMemoryVT();
1836 for (
unsigned i = 0; i < NumValidBits; ++i)
1837 Bits[i] = ValueBit(
V, i);
1840 for (
unsigned i = NumValidBits; i < NumBits; ++i)
1841 Bits[i] = ValueBit(
V, i, ValueBit::VariableKnownToBeZero);
1845 return std::make_pair(Interesting =
false, &Bits);
1850 for (
unsigned i = 0; i < NumBits; ++i)
1851 Bits[i] = ValueBit(
V, i);
1853 return std::make_pair(Interesting =
false, &Bits);
1858 void computeRotationAmounts() {
1860 RLAmt.resize(
Bits.size());
1861 for (
unsigned i = 0; i <
Bits.size(); ++i)
1862 if (Bits[i].hasValue()) {
1863 unsigned VBI =
Bits[i].getValueBitIndex();
1867 RLAmt[i] =
Bits.size() - (VBI - i);
1868 }
else if (Bits[i].
isZero()) {
1870 RLAmt[i] = UINT32_MAX;
1879 void collectBitGroups(
bool LateMask) {
1882 unsigned LastRLAmt = RLAmt[0];
1884 unsigned LastGroupStartIdx = 0;
1885 bool IsGroupOfZeros = !
Bits[LastGroupStartIdx].hasValue();
1886 for (
unsigned i = 1; i <
Bits.size(); ++i) {
1887 unsigned ThisRLAmt = RLAmt[i];
1889 if (LateMask && !ThisValue) {
1890 ThisValue = LastValue;
1891 ThisRLAmt = LastRLAmt;
1894 if (BitGroups.empty())
1895 LastGroupStartIdx = 0;
1902 if (IsGroupOfZeros && Bits[i].
isZero())
1907 if (ThisRLAmt == LastRLAmt && ThisValue == LastValue)
1910 if (!(IsGroupOfZeros && ThisValue && !Bits[i].
isZero()))
1914 BitGroups.push_back(BitGroup(LastValue, LastRLAmt, LastGroupStartIdx,
1916 LastRLAmt = ThisRLAmt;
1917 LastValue = ThisValue;
1918 LastGroupStartIdx = i;
1919 IsGroupOfZeros = !
Bits[LastGroupStartIdx].hasValue();
1922 BitGroups.push_back(BitGroup(LastValue, LastRLAmt, LastGroupStartIdx,
1925 if (BitGroups.empty())
1929 if (BitGroups.size() > 1) {
1933 if (BitGroups[0].StartIdx == 0 &&
1934 BitGroups[BitGroups.size()-1].EndIdx ==
Bits.size()-1 &&
1935 BitGroups[0].V == BitGroups[BitGroups.size()-1].V &&
1936 BitGroups[0].RLAmt == BitGroups[BitGroups.size()-1].RLAmt) {
1937 LLVM_DEBUG(
dbgs() <<
"\tcombining final bit group with initial one\n");
1938 BitGroups[BitGroups.size()-1].EndIdx = BitGroups[0].EndIdx;
1939 BitGroups.erase(BitGroups.begin());
1949 void collectValueRotInfo() {
1952 for (
auto &BG : BitGroups) {
1953 unsigned RLAmtKey = BG.RLAmt + (BG.Repl32 ? 64 : 0);
1954 ValueRotInfo &VRI = ValueRots[std::make_pair(BG.V, RLAmtKey)];
1956 VRI.RLAmt = BG.RLAmt;
1957 VRI.Repl32 = BG.Repl32;
1959 VRI.FirstGroupStartIdx = std::min(VRI.FirstGroupStartIdx, BG.StartIdx);
1964 ValueRotsVec.clear();
1965 for (
auto &
I : ValueRots) {
1966 ValueRotsVec.push_back(
I.second);
1979 void assignRepl32BitGroups() {
1990 auto IsAllLow32 = [
this](BitGroup & BG) {
1991 if (BG.StartIdx <= BG.EndIdx) {
1992 for (
unsigned i = BG.StartIdx; i <= BG.EndIdx; ++i) {
1993 if (!Bits[i].hasValue())
1995 if (Bits[i].getValueBitIndex() >= 32)
1999 for (
unsigned i = BG.StartIdx; i <
Bits.size(); ++i) {
2000 if (!Bits[i].hasValue())
2002 if (Bits[i].getValueBitIndex() >= 32)
2005 for (
unsigned i = 0; i <= BG.EndIdx; ++i) {
2006 if (!Bits[i].hasValue())
2008 if (Bits[i].getValueBitIndex() >= 32)
2016 for (
auto &BG : BitGroups) {
2020 if (BG.RLAmt == 0) {
2021 auto PotentiallyMerged = [
this](BitGroup & BG) {
2022 for (
auto &BG2 : BitGroups)
2023 if (&BG != &BG2 && BG.V == BG2.V &&
2024 (BG2.RLAmt == 0 || BG2.RLAmt == 32))
2028 if (!PotentiallyMerged(BG))
2031 if (BG.StartIdx < 32 && BG.EndIdx < 32) {
2032 if (IsAllLow32(BG)) {
2033 if (BG.RLAmt >= 32) {
2041 << BG.V.getNode() <<
" RLAmt = " << BG.RLAmt <<
" ["
2042 << BG.StartIdx <<
", " << BG.EndIdx <<
"]\n");
2048 for (
auto I = BitGroups.begin();
I != BitGroups.end();) {
2051 auto IP = (
I == BitGroups.begin()) ?
2052 std::prev(BitGroups.end()) : std::prev(
I);
2053 if (
I->Repl32 && IP->Repl32 &&
I->V == IP->V &&
I->RLAmt == IP->RLAmt &&
2054 I->StartIdx == (IP->EndIdx + 1) % 64 &&
I != IP) {
2056 LLVM_DEBUG(dbgs() <<
"\tcombining 32-bit replicated bit group for "
2057 << I->V.getNode() <<
" RLAmt = " << I->RLAmt <<
" ["
2058 << I->StartIdx <<
", " << I->EndIdx
2059 <<
"] with group with range [" << IP->StartIdx <<
", "
2060 << IP->EndIdx <<
"]\n");
2062 IP->EndIdx = I->EndIdx;
2063 IP->Repl32CR = IP->Repl32CR || I->Repl32CR;
2064 IP->Repl32Coalesced = true;
2065 I = BitGroups.erase(I);
2074 if (I->StartIdx == 32 && I->EndIdx == 63) {
2075 assert(std::next(I) == BitGroups.end() &&
2076 "bit group ends at index 63 but there is another?");
2077 auto IN = BitGroups.begin();
2079 if (IP->Repl32 && IN->Repl32 && I->V == IP->V && I->V == IN->V &&
2080 (I->RLAmt % 32) == IP->RLAmt && (I->RLAmt % 32) == IN->RLAmt &&
2081 IP->EndIdx == 31 && IN->StartIdx == 0 && I != IP &&
2084 LLVM_DEBUG(dbgs() <<
"\tcombining bit group for " << I->V.getNode()
2085 <<
" RLAmt = " << I->RLAmt <<
" [" << I->StartIdx
2086 <<
", " << I->EndIdx
2087 <<
"] with 32-bit replicated groups with ranges ["
2088 << IP->StartIdx <<
", " << IP->EndIdx <<
"] and ["
2089 << IN->StartIdx <<
", " << IN->EndIdx <<
"]\n");
2097 IP->Repl32CR = IP->Repl32CR || I->RLAmt >= 32;
2098 IP->Repl32Coalesced = true;
2099 I = BitGroups.erase(I);
2104 IP->EndIdx = IN->EndIdx;
2105 IP->Repl32CR = IP->Repl32CR || IN->Repl32CR || I->RLAmt >= 32;
2106 IP->Repl32Coalesced = true;
2107 I = BitGroups.erase(I);
2108 BitGroups.erase(BitGroups.begin());
2122 SDValue getI32Imm(
unsigned Imm,
const SDLoc &dl) {
2123 return CurDAG->getTargetConstant(
Imm, dl, MVT::i32);
2128 for (
unsigned i = 0; i <
Bits.size(); ++i) {
2129 if (Bits[i].hasValue())
2131 Mask |= (UINT64_C(1) << i);
2142 if (
V.getValueSizeInBits() == 64)
2145 assert(
V.getValueSizeInBits() == 32);
2146 SDValue SubRegIdx = CurDAG->getTargetConstant(PPC::sub_32, dl, MVT::i32);
2147 SDValue ImDef =
SDValue(CurDAG->getMachineNode(PPC::IMPLICIT_DEF, dl,
2149 SDValue ExtVal =
SDValue(CurDAG->getMachineNode(PPC::INSERT_SUBREG, dl,
2156 if (
V.getValueSizeInBits() == 32)
2159 assert(
V.getValueSizeInBits() == 64);
2160 SDValue SubRegIdx = CurDAG->getTargetConstant(PPC::sub_32, dl, MVT::i32);
2161 SDValue SubVal =
SDValue(CurDAG->getMachineNode(PPC::EXTRACT_SUBREG, dl,
2162 MVT::i32,
V, SubRegIdx), 0);
2169 void SelectAndParts32(
const SDLoc &dl,
SDValue &Res,
unsigned *InstCnt) {
2173 for (ValueRotInfo &VRI : ValueRotsVec) {
2175 for (
unsigned i = 0; i <
Bits.size(); ++i) {
2176 if (!Bits[i].hasValue() || Bits[i].
getValue() != VRI.V)
2178 if (RLAmt[i] != VRI.RLAmt)
2184 unsigned ANDIMask = (
Mask & UINT16_MAX), ANDISMask = Mask >> 16;
2185 assert((ANDIMask != 0 || ANDISMask != 0) &&
2186 "No set bits in mask for value bit groups");
2187 bool NeedsRotate = VRI.RLAmt != 0;
2203 unsigned NumAndInsts = (unsigned) NeedsRotate +
2204 (
unsigned) (ANDIMask != 0) +
2205 (
unsigned) (ANDISMask != 0) +
2206 (
unsigned) (ANDIMask != 0 && ANDISMask != 0) +
2207 (
unsigned) (bool) Res;
2209 LLVM_DEBUG(
dbgs() <<
"\t\trotation groups for " << VRI.V.getNode()
2210 <<
" RL: " << VRI.RLAmt <<
":"
2211 <<
"\n\t\t\tisel using masking: " << NumAndInsts
2212 <<
" using rotates: " << VRI.NumGroups <<
"\n");
2214 if (NumAndInsts >= VRI.NumGroups)
2219 if (InstCnt) *InstCnt += NumAndInsts;
2224 { TruncateToInt32(VRI.V, dl), getI32Imm(VRI.RLAmt, dl),
2225 getI32Imm(0, dl), getI32Imm(31, dl) };
2226 VRot =
SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32,
2229 VRot = TruncateToInt32(VRI.V, dl);
2234 ANDIVal =
SDValue(CurDAG->getMachineNode(PPC::ANDI_rec, dl, MVT::i32,
2235 VRot, getI32Imm(ANDIMask, dl)),
2239 SDValue(CurDAG->getMachineNode(PPC::ANDIS_rec, dl, MVT::i32, VRot,
2240 getI32Imm(ANDISMask, dl)),
2245 TotalVal = ANDISVal;
2249 TotalVal =
SDValue(CurDAG->getMachineNode(PPC::OR, dl, MVT::i32,
2250 ANDIVal, ANDISVal), 0);
2255 Res =
SDValue(CurDAG->getMachineNode(PPC::OR, dl, MVT::i32,
2260 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
2261 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt;
2267 SDNode *Select32(SDNode *
N,
bool LateMask,
unsigned *InstCnt) {
2271 if (InstCnt) *InstCnt = 0;
2274 SelectAndParts32(dl, Res, InstCnt);
2279 if ((!NeedMask || LateMask) && !Res) {
2280 ValueRotInfo &VRI = ValueRotsVec[0];
2282 if (InstCnt) *InstCnt += 1;
2284 { TruncateToInt32(VRI.V, dl), getI32Imm(VRI.RLAmt, dl),
2285 getI32Imm(0, dl), getI32Imm(31, dl) };
2286 Res =
SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32,
Ops),
2289 Res = TruncateToInt32(VRI.V, dl);
2293 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
2294 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt;
2298 if (InstCnt) *InstCnt += BitGroups.size();
2301 for (
auto &BG : BitGroups) {
2304 { TruncateToInt32(BG.V, dl), getI32Imm(BG.RLAmt, dl),
2305 getI32Imm(
Bits.size() - BG.EndIdx - 1, dl),
2306 getI32Imm(
Bits.size() - BG.StartIdx - 1, dl) };
2307 Res =
SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32,
Ops), 0);
2310 { Res, TruncateToInt32(BG.V, dl), getI32Imm(BG.RLAmt, dl),
2311 getI32Imm(
Bits.size() - BG.EndIdx - 1, dl),
2312 getI32Imm(
Bits.size() - BG.StartIdx - 1, dl) };
2313 Res =
SDValue(CurDAG->getMachineNode(PPC::RLWIMI, dl, MVT::i32,
Ops), 0);
2318 unsigned Mask = (unsigned) getZerosMask();
2320 unsigned ANDIMask = (
Mask & UINT16_MAX), ANDISMask = Mask >> 16;
2321 assert((ANDIMask != 0 || ANDISMask != 0) &&
2322 "No set bits in zeros mask?");
2324 if (InstCnt) *InstCnt += (unsigned) (ANDIMask != 0) +
2325 (unsigned) (ANDISMask != 0) +
2326 (unsigned) (ANDIMask != 0 && ANDISMask != 0);
2330 ANDIVal =
SDValue(CurDAG->getMachineNode(PPC::ANDI_rec, dl, MVT::i32,
2331 Res, getI32Imm(ANDIMask, dl)),
2335 SDValue(CurDAG->getMachineNode(PPC::ANDIS_rec, dl, MVT::i32, Res,
2336 getI32Imm(ANDISMask, dl)),
2344 Res =
SDValue(CurDAG->getMachineNode(PPC::OR, dl, MVT::i32,
2345 ANDIVal, ANDISVal), 0);
2351 unsigned SelectRotMask64Count(
unsigned RLAmt,
bool Repl32,
2352 unsigned MaskStart,
unsigned MaskEnd,
2356 unsigned InstMaskStart = 64 - MaskEnd - 1,
2357 InstMaskEnd = 64 - MaskStart - 1;
2362 if ((!IsIns && (InstMaskEnd == 63 || InstMaskStart == 0)) ||
2363 InstMaskEnd == 63 - RLAmt)
2372 bool Repl32,
unsigned MaskStart,
unsigned MaskEnd,
2373 unsigned *InstCnt =
nullptr) {
2376 unsigned InstMaskStart = 64 - MaskEnd - 1,
2377 InstMaskEnd = 64 - MaskStart - 1;
2379 if (InstCnt) *InstCnt += 1;
2385 assert(InstMaskStart >= 32 &&
"Mask cannot start out of range");
2386 assert(InstMaskEnd >= 32 &&
"Mask cannot end out of range");
2388 { ExtendToInt64(
V, dl), getI32Imm(RLAmt, dl),
2389 getI32Imm(InstMaskStart - 32, dl), getI32Imm(InstMaskEnd - 32, dl) };
2390 return SDValue(CurDAG->getMachineNode(PPC::RLWINM8, dl, MVT::i64,
2394 if (InstMaskEnd == 63) {
2396 { ExtendToInt64(
V, dl), getI32Imm(RLAmt, dl),
2397 getI32Imm(InstMaskStart, dl) };
2398 return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64,
Ops), 0);
2401 if (InstMaskStart == 0) {
2403 { ExtendToInt64(
V, dl), getI32Imm(RLAmt, dl),
2404 getI32Imm(InstMaskEnd, dl) };
2405 return SDValue(CurDAG->getMachineNode(PPC::RLDICR, dl, MVT::i64,
Ops), 0);
2408 if (InstMaskEnd == 63 - RLAmt) {
2410 { ExtendToInt64(
V, dl), getI32Imm(RLAmt, dl),
2411 getI32Imm(InstMaskStart, dl) };
2412 return SDValue(CurDAG->getMachineNode(PPC::RLDIC, dl, MVT::i64,
Ops), 0);
2421 if (InstCnt) *InstCnt += 1;
2424 unsigned RLAmt2 = MaskStart;
2427 unsigned RLAmt1 = (64 + RLAmt - RLAmt2) % 64;
2429 V = SelectRotMask64(
V, dl, RLAmt1,
false, 0, 63);
2430 return SelectRotMask64(
V, dl, RLAmt2,
false, MaskStart, MaskEnd);
2436 unsigned RLAmt,
bool Repl32,
unsigned MaskStart,
2437 unsigned MaskEnd,
unsigned *InstCnt =
nullptr) {
2440 unsigned InstMaskStart = 64 - MaskEnd - 1,
2441 InstMaskEnd = 64 - MaskStart - 1;
2443 if (InstCnt) *InstCnt += 1;
2449 assert(InstMaskStart >= 32 &&
"Mask cannot start out of range");
2450 assert(InstMaskEnd >= 32 &&
"Mask cannot end out of range");
2452 { ExtendToInt64(
Base, dl), ExtendToInt64(
V, dl), getI32Imm(RLAmt, dl),
2453 getI32Imm(InstMaskStart - 32, dl), getI32Imm(InstMaskEnd - 32, dl) };
2454 return SDValue(CurDAG->getMachineNode(PPC::RLWIMI8, dl, MVT::i64,
2458 if (InstMaskEnd == 63 - RLAmt) {
2460 { ExtendToInt64(
Base, dl), ExtendToInt64(
V, dl), getI32Imm(RLAmt, dl),
2461 getI32Imm(InstMaskStart, dl) };
2462 return SDValue(CurDAG->getMachineNode(PPC::RLDIMI, dl, MVT::i64,
Ops), 0);
2471 if (InstCnt) *InstCnt += 1;
2474 unsigned RLAmt2 = MaskStart;
2477 unsigned RLAmt1 = (64 + RLAmt - RLAmt2) % 64;
2479 V = SelectRotMask64(
V, dl, RLAmt1,
false, 0, 63);
2480 return SelectRotMaskIns64(
Base,
V, dl, RLAmt2,
false, MaskStart, MaskEnd);
2483 void SelectAndParts64(
const SDLoc &dl,
SDValue &Res,
unsigned *InstCnt) {
2496 for (ValueRotInfo &VRI : ValueRotsVec) {
2504 auto MatchingBG = [VRI](
const BitGroup &BG) {
2508 unsigned EffRLAmt = BG.RLAmt;
2509 if (!VRI.Repl32 && BG.Repl32) {
2510 if (BG.StartIdx < 32 && BG.EndIdx < 32 && BG.StartIdx <= BG.EndIdx &&
2511 !BG.Repl32Coalesced) {
2517 }
else if (VRI.Repl32 != BG.Repl32) {
2521 return VRI.RLAmt == EffRLAmt;
2524 for (
auto &BG : BitGroups) {
2525 if (!MatchingBG(BG))
2528 if (BG.StartIdx <= BG.EndIdx) {
2529 for (
unsigned i = BG.StartIdx; i <= BG.EndIdx; ++i)
2530 Mask |= (UINT64_C(1) << i);
2532 for (
unsigned i = BG.StartIdx; i <
Bits.size(); ++i)
2533 Mask |= (UINT64_C(1) << i);
2534 for (
unsigned i = 0; i <= BG.EndIdx; ++i)
2535 Mask |= (UINT64_C(1) << i);
2544 unsigned ANDIMask = (
Mask & UINT16_MAX),
2545 ANDISMask = (Mask >> 16) & UINT16_MAX;
2547 bool NeedsRotate = VRI.RLAmt || (VRI.Repl32 && !
isUInt<32>(Mask));
2549 unsigned NumAndInsts = (unsigned) NeedsRotate +
2550 (
unsigned) (bool) Res;
2551 unsigned NumOfSelectInsts = 0;
2553 assert(NumOfSelectInsts > 0 &&
"Failed to select an i64 constant.");
2555 NumAndInsts += (unsigned) (ANDIMask != 0) + (unsigned) (ANDISMask != 0) +
2556 (unsigned) (ANDIMask != 0 && ANDISMask != 0);
2558 NumAndInsts += NumOfSelectInsts + 1;
2560 unsigned NumRLInsts = 0;
2561 bool FirstBG =
true;
2562 bool MoreBG =
false;
2563 for (
auto &BG : BitGroups) {
2564 if (!MatchingBG(BG)) {
2569 SelectRotMask64Count(BG.RLAmt, BG.Repl32, BG.StartIdx, BG.EndIdx,
2574 LLVM_DEBUG(
dbgs() <<
"\t\trotation groups for " << VRI.V.getNode()
2575 <<
" RL: " << VRI.RLAmt << (VRI.Repl32 ?
" (32):" :
":")
2576 <<
"\n\t\t\tisel using masking: " << NumAndInsts
2577 <<
" using rotates: " << NumRLInsts <<
"\n");
2583 if (NumAndInsts > NumRLInsts)
2588 if ((Use32BitInsts || MoreBG) && NumAndInsts == NumRLInsts)
2593 if (InstCnt) *InstCnt += NumAndInsts;
2600 if (VRI.RLAmt || (VRI.Repl32 && !
isUInt<32>(Mask)))
2601 VRot = SelectRotMask64(VRI.V, dl, VRI.RLAmt, VRI.Repl32,
2602 VRI.Repl32 ? 31 : 0, VRI.Repl32 ? 30 : 63);
2607 if (Use32BitInsts) {
2608 assert((ANDIMask != 0 || ANDISMask != 0) &&
2609 "No set bits in mask when using 32-bit ands for 64-bit value");
2613 ANDIVal =
SDValue(CurDAG->getMachineNode(PPC::ANDI8_rec, dl, MVT::i64,
2614 ExtendToInt64(VRot, dl),
2615 getI32Imm(ANDIMask, dl)),
2619 SDValue(CurDAG->getMachineNode(PPC::ANDIS8_rec, dl, MVT::i64,
2620 ExtendToInt64(VRot, dl),
2621 getI32Imm(ANDISMask, dl)),
2625 TotalVal = ANDISVal;
2629 TotalVal =
SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64,
2630 ExtendToInt64(ANDIVal, dl), ANDISVal), 0);
2634 SDValue(CurDAG->getMachineNode(PPC::AND8, dl, MVT::i64,
2635 ExtendToInt64(VRot, dl), TotalVal),
2642 Res =
SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64,
2643 ExtendToInt64(Res, dl), TotalVal),
2648 eraseMatchingBitGroups(MatchingBG);
2653 SDNode *Select64(SDNode *
N,
bool LateMask,
unsigned *InstCnt) {
2657 if (InstCnt) *InstCnt = 0;
2660 SelectAndParts64(dl, Res, InstCnt);
2665 if ((!NeedMask || LateMask) && !Res) {
2669 unsigned MaxGroupsIdx = 0;
2670 if (!ValueRotsVec[0].Repl32) {
2671 for (
unsigned i = 0, ie = ValueRotsVec.size(); i < ie; ++i)
2672 if (ValueRotsVec[i].Repl32) {
2673 if (ValueRotsVec[i].NumGroups > ValueRotsVec[0].NumGroups)
2679 ValueRotInfo &VRI = ValueRotsVec[MaxGroupsIdx];
2680 bool NeedsRotate =
false;
2683 }
else if (VRI.Repl32) {
2684 for (
auto &BG : BitGroups) {
2685 if (BG.V != VRI.V || BG.RLAmt != VRI.RLAmt ||
2686 BG.Repl32 != VRI.Repl32)
2691 if (BG.StartIdx < 32 && BG.EndIdx < 32 && BG.StartIdx < BG.EndIdx)
2700 Res = SelectRotMask64(VRI.V, dl, VRI.RLAmt, VRI.Repl32,
2701 VRI.Repl32 ? 31 : 0, VRI.Repl32 ? 30 : 63,
2708 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
2709 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt &&
2710 BG.Repl32 == VRI.Repl32;
2717 for (
auto I = BitGroups.begin(), IE = BitGroups.end();
I != IE; ++
I) {
2718 if (SelectRotMask64Count(
I->RLAmt,
I->Repl32,
I->StartIdx,
I->EndIdx,
2720 SelectRotMask64Count(
I->RLAmt,
I->Repl32,
I->StartIdx,
I->EndIdx,
2722 if (
I != BitGroups.begin()) {
2725 BitGroups.insert(BitGroups.begin(), BG);
2733 for (
auto &BG : BitGroups) {
2735 Res = SelectRotMask64(BG.V, dl, BG.RLAmt, BG.Repl32, BG.StartIdx,
2736 BG.EndIdx, InstCnt);
2738 Res = SelectRotMaskIns64(Res, BG.V, dl, BG.RLAmt, BG.Repl32,
2739 BG.StartIdx, BG.EndIdx, InstCnt);
2750 unsigned ANDIMask = (
Mask & UINT16_MAX),
2751 ANDISMask = (Mask >> 16) & UINT16_MAX;
2753 if (Use32BitInsts) {
2754 assert((ANDIMask != 0 || ANDISMask != 0) &&
2755 "No set bits in mask when using 32-bit ands for 64-bit value");
2757 if (InstCnt) *InstCnt += (unsigned) (ANDIMask != 0) +
2758 (unsigned) (ANDISMask != 0) +
2759 (unsigned) (ANDIMask != 0 && ANDISMask != 0);
2763 ANDIVal =
SDValue(CurDAG->getMachineNode(PPC::ANDI8_rec, dl, MVT::i64,
2764 ExtendToInt64(Res, dl),
2765 getI32Imm(ANDIMask, dl)),
2769 SDValue(CurDAG->getMachineNode(PPC::ANDIS8_rec, dl, MVT::i64,
2770 ExtendToInt64(Res, dl),
2771 getI32Imm(ANDISMask, dl)),
2779 Res =
SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64,
2780 ExtendToInt64(ANDIVal, dl), ANDISVal), 0);
2782 unsigned NumOfSelectInsts = 0;
2785 Res =
SDValue(CurDAG->getMachineNode(PPC::AND8, dl, MVT::i64,
2786 ExtendToInt64(Res, dl), MaskVal),
2789 *InstCnt += NumOfSelectInsts + 1;
2796 SDNode *
Select(SDNode *
N,
bool LateMask,
unsigned *InstCnt =
nullptr) {
2798 collectBitGroups(LateMask);
2799 if (BitGroups.empty())
2803 if (
Bits.size() == 64)
2804 assignRepl32BitGroups();
2807 collectValueRotInfo();
2809 if (
Bits.size() == 32) {
2810 return Select32(
N, LateMask, InstCnt);
2812 assert(
Bits.size() == 64 &&
"Not 64 bits here?");
2813 return Select64(
N, LateMask, InstCnt);
2819 void eraseMatchingBitGroups(function_ref<
bool(
const BitGroup &)>
F) {
2830 DenseMap<std::pair<SDValue, unsigned>, ValueRotInfo> ValueRots;
2833 SelectionDAG *CurDAG =
nullptr;
2836 BitPermutationSelector(SelectionDAG *DAG)
2845 getValueBits(
SDValue(
N, 0),
N->getValueType(0).getSizeInBits());
2850 LLVM_DEBUG(
dbgs() <<
"Considering bit-permutation-based instruction"
2851 " selection for: ");
2855 computeRotationAmounts();
2868 unsigned InstCnt = 0, InstCntLateMask = 0;
2870 SDNode *
RN =
Select(
N,
false, &InstCnt);
2871 LLVM_DEBUG(
dbgs() <<
"\t\tisel would use " << InstCnt <<
" instructions\n");
2874 SDNode *RNLM =
Select(
N,
true, &InstCntLateMask);
2876 <<
" instructions\n");
2878 if (InstCnt <= InstCntLateMask) {
2888class IntegerCompareEliminator {
2889 SelectionDAG *CurDAG;
2893 enum ExtOrTruncConversion { Ext, Trunc };
2901 enum SetccInGPROpts { ZExtOrig, ZExtInvert, SExtOrig, SExtInvert };
2911 enum ZeroCompare { GEZExt, GESExt, LEZExt, LESExt };
2913 SDNode *tryEXTEND(SDNode *
N);
2914 SDNode *tryLogicOpOfCompares(SDNode *
N);
2918 SDValue addExtOrTrunc(
SDValue NatWidthRes, ExtOrTruncConversion Conv);
2922 int64_t RHSValue, SDLoc dl);
2924 int64_t RHSValue, SDLoc dl);
2926 int64_t RHSValue, SDLoc dl);
2928 int64_t RHSValue, SDLoc dl);
2932 IntegerCompareEliminator(SelectionDAG *DAG,
2933 PPCDAGToDAGISel *Sel) : CurDAG(DAG), S(Sel) {
2936 "Only expecting to use this on 64 bit targets.");
2941 switch (
N->getOpcode()) {
2952 return tryEXTEND(
N);
2956 return tryLogicOpOfCompares(
N);
2964SDNode *IntegerCompareEliminator::tryEXTEND(SDNode *
N) {
2967 "Expecting a zero/sign extend node!");
2972 N->getOperand(0).getValueType() == MVT::i1 &&
2974 WideRes = computeLogicOpInGPR(
N->getOperand(0));
2975 else if (
N->getOperand(0).getOpcode() !=
ISD::SETCC)
2979 getSETCCInGPR(
N->getOperand(0),
2981 SetccInGPROpts::SExtOrig : SetccInGPROpts::ZExtOrig);
2987 bool Output32Bit =
N->getValueType(0) == MVT::i32;
2993 if (Input32Bit != Output32Bit)
2994 ConvOp = addExtOrTrunc(WideRes, Input32Bit ? ExtOrTruncConversion::Ext :
2995 ExtOrTruncConversion::Trunc);
3003SDNode *IntegerCompareEliminator::tryLogicOpOfCompares(SDNode *
N) {
3004 if (
N->getValueType(0) != MVT::i1)
3007 "Expected a logic operation on setcc results.");
3009 if (!LoweredLogical)
3014 unsigned SubRegToExtract = IsBitwiseNegate ? PPC::sub_eq : PPC::sub_gt;
3023 if (IsBitwiseNegate &&
3026 else if (IsBitwiseNegate)
3028 OpToConvToRecForm = LoweredLogical.
getOperand(0);
3032 OpToConvToRecForm = LoweredLogical;
3042 if (NewOpc != -1 && IsBitwiseNegate) {
3045 "Expected a PPC::XORI8 only for bitwise negation.");
3047 std::vector<SDValue>
Ops;
3048 for (
int i = 0, e = OpToConvToRecForm.
getNumOperands(); i < e; i++)
3054 MVT::Glue,
Ops), 0);
3056 assert((NewOpc != -1 || !IsBitwiseNegate) &&
3057 "No record form available for AND8/OR8/XOR8?");
3060 dl, MVT::i64, MVT::Glue,
LHS,
RHS),
3072 MVT::i1, CR0Reg, SRIdxVal,
3085SDValue IntegerCompareEliminator::computeLogicOpInGPR(
SDValue LogicOp) {
3087 "Can only handle logic operations here.");
3089 "Can only handle logic operations on i1 values here.");
3101 unsigned OperandOpcode = Operand.getOpcode();
3103 return getSETCCInGPR(Operand, SetccInGPROpts::ZExtOrig);
3105 SDValue InputOp = Operand.getOperand(0);
3108 PPC::RLDICL, dl, InVT, InputOp,
3109 S->getI64Imm(0, dl),
3110 S->getI64Imm(63, dl)), 0);
3112 return computeLogicOpInGPR(Operand);
3121 if (!
LHS || (!
RHS && !IsBitwiseNegation))
3124 NumLogicOpsOnComparison++;
3127 if (
LHS.getValueType() == MVT::i32)
3128 LHS = addExtOrTrunc(
LHS, ExtOrTruncConversion::Ext);
3129 if (!IsBitwiseNegation &&
RHS.getValueType() == MVT::i32)
3130 RHS = addExtOrTrunc(
RHS, ExtOrTruncConversion::Ext);
3135 case ISD::AND: NewOpc = PPC::AND8;
break;
3136 case ISD::OR: NewOpc = PPC::OR8;
break;
3137 case ISD::XOR: NewOpc = PPC::XOR8;
break;
3140 if (IsBitwiseNegation) {
3141 RHS = S->getI64Imm(1, dl);
3142 NewOpc = PPC::XORI8;
3153SDValue IntegerCompareEliminator::signExtendInputIfNeeded(
SDValue Input) {
3155 "Can only sign-extend 32-bit values here.");
3163 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3169 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3174 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3177 SignExtensionsAdded++;
3179 MVT::i64, Input), 0);
3186SDValue IntegerCompareEliminator::zeroExtendInputIfNeeded(
SDValue Input) {
3188 "Can only zero-extend 32-bit values here.");
3198 if (IsTruncateOfZExt)
3199 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3203 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3208 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3212 ZeroExtensionsAdded++;
3214 S->getI64Imm(0, dl),
3215 S->getI64Imm(32, dl)), 0);
3222SDValue IntegerCompareEliminator::addExtOrTrunc(
SDValue NatWidthRes,
3223 ExtOrTruncConversion Conv) {
3224 SDLoc dl(NatWidthRes);
3228 if (Conv == ExtOrTruncConversion::Ext) {
3233 ImDef, NatWidthRes, SubRegIdx), 0);
3236 assert(Conv == ExtOrTruncConversion::Trunc &&
3237 "Unknown convertion between 32 and 64 bit values.");
3243 NatWidthRes, SubRegIdx), 0);
3249IntegerCompareEliminator::getCompoundZeroComparisonInGPR(
SDValue LHS, SDLoc dl,
3250 ZeroCompare CmpTy) {
3251 EVT InVT =
LHS.getValueType();
3252 bool Is32Bit = InVT == MVT::i32;
3257 case ZeroCompare::GEZExt:
3258 case ZeroCompare::GESExt:
3262 case ZeroCompare::LEZExt:
3263 case ZeroCompare::LESExt: {
3266 LHS = signExtendInputIfNeeded(
LHS);
3271 Neg, S->getI64Imm(1, dl),
3272 S->getI64Imm(63, dl)), 0);
3276 S->getI64Imm(~0ULL, dl)), 0);
3286 (CmpTy == ZeroCompare::GEZExt || CmpTy == ZeroCompare::LEZExt))
3288 ToExtend, S->getI64Imm(1, dl),
3289 S->getI64Imm(63, dl)), 0);
3291 (CmpTy == ZeroCompare::GESExt || CmpTy == ZeroCompare::LESExt))
3293 S->getI64Imm(63, dl)), 0);
3295 assert(Is32Bit &&
"Should have handled the 32-bit sequences above.");
3298 case ZeroCompare::GEZExt: {
3299 SDValue ShiftOps[] = { ToExtend, S->getI32Imm(1, dl), S->getI32Imm(31, dl),
3300 S->getI32Imm(31, dl) };
3304 case ZeroCompare::GESExt:
3306 S->getI32Imm(31, dl)), 0);
3307 case ZeroCompare::LEZExt:
3309 S->getI32Imm(1, dl)), 0);
3310 case ZeroCompare::LESExt:
3312 S->getI32Imm(-1, dl)), 0);
3325 int64_t RHSValue, SDLoc dl) {
3329 bool IsRHSZero = RHSValue == 0;
3330 bool IsRHSOne = RHSValue == 1;
3331 bool IsRHSNegOne = RHSValue == -1LL;
3341 SDValue ShiftOps[] = { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl),
3342 S->getI32Imm(31, dl) };
3353 SDValue ShiftOps[] = { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl),
3354 S->getI32Imm(31, dl) };
3358 S->getI32Imm(1, dl)), 0);
3364 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GEZExt);
3370 IsRHSZero = RHSConst && RHSConst->
isZero();
3381 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LEZExt);
3385 LHS = signExtendInputIfNeeded(
LHS);
3386 RHS = signExtendInputIfNeeded(
RHS);
3391 S->getI64Imm(1, dl), S->getI64Imm(63, dl)),
3395 MVT::i64, Shift, S->getI32Imm(1, dl)), 0);
3403 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GEZExt);
3409 LHS = signExtendInputIfNeeded(
LHS);
3410 RHS = signExtendInputIfNeeded(
RHS);
3414 Neg, S->getI32Imm(1, dl), S->getI32Imm(63, dl)), 0);
3420 IsRHSZero = RHSConst && RHSConst->
isZero();
3432 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LEZExt);
3436 SDValue ShiftOps[] = {
LHS, S->getI32Imm(1, dl), S->getI32Imm(31, dl),
3437 S->getI32Imm(31, dl) };
3445 LHS = signExtendInputIfNeeded(
LHS);
3446 RHS = signExtendInputIfNeeded(
RHS);
3450 SUBFNode, S->getI64Imm(1, dl),
3451 S->getI64Imm(63, dl)), 0);
3462 LHS = zeroExtendInputIfNeeded(
LHS);
3463 RHS = zeroExtendInputIfNeeded(
RHS);
3468 Subtract, S->getI64Imm(1, dl),
3469 S->getI64Imm(63, dl)), 0);
3471 S->getI32Imm(1, dl)), 0);
3482 LHS = zeroExtendInputIfNeeded(
LHS);
3483 RHS = zeroExtendInputIfNeeded(
RHS);
3487 Subtract, S->getI64Imm(1, dl),
3488 S->getI64Imm(63, dl)), 0);
3498 int64_t RHSValue, SDLoc dl) {
3502 bool IsRHSZero = RHSValue == 0;
3503 bool IsRHSOne = RHSValue == 1;
3504 bool IsRHSNegOne = RHSValue == -1LL;
3517 SDValue SHLOps[] = { Cntlzw, S->getI32Imm(27, dl),
3518 S->getI32Imm(5, dl), S->getI32Imm(31, dl) };
3536 { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl), S->getI32Imm(31, dl) };
3541 S->getI32Imm(1, dl)), 0);
3548 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GESExt);
3554 IsRHSZero = RHSConst && RHSConst->
isZero();
3563 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LESExt);
3566 LHS = signExtendInputIfNeeded(
LHS);
3567 RHS = signExtendInputIfNeeded(
RHS);
3573 SUBFNode, S->getI64Imm(1, dl),
3574 S->getI64Imm(63, dl)), 0);
3576 S->getI32Imm(-1, dl)), 0);
3583 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GESExt);
3588 LHS = signExtendInputIfNeeded(
LHS);
3589 RHS = signExtendInputIfNeeded(
RHS);
3593 S->getI64Imm(63, dl)), 0);
3599 IsRHSZero = RHSConst && RHSConst->
isZero();
3610 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LESExt);
3614 S->getI32Imm(31, dl)), 0);
3619 LHS = signExtendInputIfNeeded(
LHS);
3620 RHS = signExtendInputIfNeeded(
RHS);
3624 SUBFNode, S->getI64Imm(63, dl)), 0);
3635 LHS = zeroExtendInputIfNeeded(
LHS);
3636 RHS = zeroExtendInputIfNeeded(
RHS);
3641 S->getI32Imm(1, dl), S->getI32Imm(63,dl)),
3644 S->getI32Imm(-1, dl)), 0);
3655 LHS = zeroExtendInputIfNeeded(
LHS);
3656 RHS = zeroExtendInputIfNeeded(
RHS);
3660 Subtract, S->getI64Imm(63, dl)), 0);
3670 int64_t RHSValue, SDLoc dl) {
3674 bool IsRHSZero = RHSValue == 0;
3675 bool IsRHSOne = RHSValue == 1;
3676 bool IsRHSNegOne = RHSValue == -1LL;
3687 S->getI64Imm(58, dl),
3688 S->getI64Imm(63, dl)), 0);
3699 Xor, S->getI32Imm(~0U, dl)), 0);
3709 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GEZExt);
3712 IsRHSZero = RHSConst && RHSConst->
isZero();
3721 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LEZExt);
3724 S->getI64Imm(1, dl),
3725 S->getI64Imm(63, dl)), 0);
3728 S->getI64Imm(63, dl)), 0);
3733 ShiftR, ShiftL, SubtractCarry), 0);
3741 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GEZExt);
3745 S->getI64Imm(~0ULL, dl)), 0);
3749 S->getI64Imm(1, dl),
3750 S->getI64Imm(63, dl)), 0);
3754 IsRHSZero = RHSConst && RHSConst->
isZero();
3764 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LEZExt);
3767 S->getI64Imm(1, dl),
3768 S->getI64Imm(63, dl)), 0);
3771 LHS, S->getI64Imm(63, dl)), 0);
3774 RHS, S->getI64Imm(1, dl),
3775 S->getI64Imm(63, dl)), 0);
3781 SRDINode, SRADINode, SUBFC8Carry), 0);
3783 ADDE8Node, S->getI64Imm(1, dl)), 0);
3798 LHS,
LHS, SUBFC8Carry), 0);
3800 SUBFE8Node, S->getI64Imm(1, dl)), 0);
3815 LHS,
LHS, SubtractCarry), 0);
3827 int64_t RHSValue, SDLoc dl) {
3831 bool IsRHSZero = RHSValue == 0;
3832 bool IsRHSOne = RHSValue == 1;
3833 bool IsRHSNegOne = RHSValue == -1LL;
3845 AddInput, S->getI32Imm(~0U, dl)), 0);
3858 Xor, S->getI32Imm(0, dl)), 0);
3868 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GESExt);
3871 IsRHSZero = RHSConst && RHSConst->
isZero();
3880 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LESExt);
3883 S->getI64Imm(63, dl)), 0);
3886 S->getI64Imm(1, dl),
3887 S->getI64Imm(63, dl)), 0);
3893 ShiftR, ShiftL, SubtractCarry), 0);
3902 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GESExt);
3906 S->getI64Imm(-1, dl)), 0);
3910 S->getI64Imm(63, dl)), 0);
3914 IsRHSZero = RHSConst && RHSConst->
isZero();
3924 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LESExt);
3927 S->getI64Imm(63, dl)), 0);
3931 LHS, S->getI64Imm(63, dl)), 0);
3934 RHS, S->getI64Imm(1, dl),
3935 S->getI64Imm(63, dl)), 0);
3941 SRDINode, SRADINode, SUBFC8Carry), 0);
3944 ADDE8Node, S->getI64Imm(1, dl)), 0);
3961 LHS, SubtractCarry), 0);
3963 ExtSub, ExtSub), 0);
3986static bool allUsesExtend(
SDValue Compare, SelectionDAG *CurDAG) {
3988 "An ISD::SETCC node required here.");
3996 for (
auto *CompareUse :
Compare.getNode()->users())
4001 OmittedForNonExtendUses++;
4011 SetccInGPROpts ConvOpts) {
4014 "An ISD::SETCC node required here.");
4027 EVT InputVT =
LHS.getValueType();
4028 if (InputVT != MVT::i32 && InputVT != MVT::i64)
4031 if (ConvOpts == SetccInGPROpts::ZExtInvert ||
4032 ConvOpts == SetccInGPROpts::SExtInvert)
4035 bool Inputs32Bit = InputVT == MVT::i32;
4040 bool IsSext = ConvOpts == SetccInGPROpts::SExtOrig ||
4041 ConvOpts == SetccInGPROpts::SExtInvert;
4043 if (IsSext && Inputs32Bit)
4044 return get32BitSExtCompare(
LHS,
RHS,
CC, RHSValue, dl);
4045 else if (Inputs32Bit)
4046 return get32BitZExtCompare(
LHS,
RHS,
CC, RHSValue, dl);
4048 return get64BitSExtCompare(
LHS,
RHS,
CC, RHSValue, dl);
4049 return get64BitZExtCompare(
LHS,
RHS,
CC, RHSValue, dl);
4054bool PPCDAGToDAGISel::tryIntCompareInGPR(SDNode *
N) {
4055 if (
N->getValueType(0) != MVT::i32 &&
4056 N->getValueType(0) != MVT::i64)
4071 switch (
N->getOpcode()) {
4078 IntegerCompareEliminator ICmpElim(CurDAG,
this);
4079 if (SDNode *New = ICmpElim.Select(
N)) {
4080 ReplaceNode(
N, New);
4088bool PPCDAGToDAGISel::tryBitPermutation(SDNode *
N) {
4089 if (
N->getValueType(0) != MVT::i32 &&
4090 N->getValueType(0) != MVT::i64)
4096 switch (
N->getOpcode()) {
4101 if (
Subtarget->isISA3_1() &&
N->getValueType(0) == MVT::i32 &&
4103 auto &OpRight =
N->getOperand(1);
4113 BitPermutationSelector BPS(CurDAG);
4114 if (SDNode *New = BPS.Select(
N)) {
4115 ReplaceNode(
N, New);
4128 const SDLoc &dl,
SDValue Chain) {
4132 if (
LHS.getValueType() == MVT::i32) {
4139 getI32Imm(
Imm & 0xFFFF, dl)),
4144 getI32Imm(
Imm & 0xFFFF, dl)),
4157 getI32Imm(
Imm >> 16, dl)), 0);
4159 getI32Imm(
Imm & 0xFFFF, dl)), 0);
4165 getI32Imm(
Imm & 0xFFFF, dl)), 0);
4171 getI32Imm((
int)SImm & 0xFFFF,
4176 }
else if (
LHS.getValueType() == MVT::i64) {
4183 getI32Imm(
Imm & 0xFFFF, dl)),
4188 getI32Imm(
Imm & 0xFFFF, dl)),
4202 getI64Imm(
Imm >> 16, dl)), 0);
4204 getI64Imm(
Imm & 0xFFFF, dl)),
4212 getI64Imm(
Imm & 0xFFFF, dl)), 0);
4218 getI64Imm(SImm & 0xFFFF, dl)),
4222 }
else if (
LHS.getValueType() == MVT::f32) {
4228 Opc = PPC::EFSCMPEQ;
4236 Opc = PPC::EFSCMPLT;
4244 Opc = PPC::EFSCMPGT;
4249 }
else if (
LHS.getValueType() == MVT::f64) {
4255 Opc = PPC::EFDCMPEQ;
4263 Opc = PPC::EFDCMPLT;
4271 Opc = PPC::EFDCMPGT;
4275 Opc =
Subtarget->hasVSX() ? PPC::XSCMPUDP : PPC::FCMPUD;
4277 assert(
LHS.getValueType() == MVT::f128 &&
"Unknown vt!");
4278 assert(
Subtarget->hasP9Vector() &&
"XSCMPUQP requires Power9 Vector");
4279 Opc = PPC::XSCMPUQP;
4347 case ISD::SETO: Invert =
true;
return 3;
4364 bool HasVSX,
bool &
Swap,
bool &Negate) {
4391 if (VecVT == MVT::v4f32)
4392 return HasVSX ? PPC::XVCMPEQSP : PPC::VCMPEQFP;
4393 else if (VecVT == MVT::v2f64)
4394 return PPC::XVCMPEQDP;
4398 if (VecVT == MVT::v4f32)
4399 return HasVSX ? PPC::XVCMPGTSP : PPC::VCMPGTFP;
4400 else if (VecVT == MVT::v2f64)
4401 return PPC::XVCMPGTDP;
4405 if (VecVT == MVT::v4f32)
4406 return HasVSX ? PPC::XVCMPGESP : PPC::VCMPGEFP;
4407 else if (VecVT == MVT::v2f64)
4408 return PPC::XVCMPGEDP;
4435 if (VecVT == MVT::v16i8)
4436 return PPC::VCMPEQUB;
4437 else if (VecVT == MVT::v8i16)
4438 return PPC::VCMPEQUH;
4439 else if (VecVT == MVT::v4i32)
4440 return PPC::VCMPEQUW;
4441 else if (VecVT == MVT::v2i64)
4442 return PPC::VCMPEQUD;
4443 else if (VecVT == MVT::v1i128)
4444 return PPC::VCMPEQUQ;
4447 if (VecVT == MVT::v16i8)
4448 return PPC::VCMPGTSB;
4449 else if (VecVT == MVT::v8i16)
4450 return PPC::VCMPGTSH;
4451 else if (VecVT == MVT::v4i32)
4452 return PPC::VCMPGTSW;
4453 else if (VecVT == MVT::v2i64)
4454 return PPC::VCMPGTSD;
4455 else if (VecVT == MVT::v1i128)
4456 return PPC::VCMPGTSQ;
4459 if (VecVT == MVT::v16i8)
4460 return PPC::VCMPGTUB;
4461 else if (VecVT == MVT::v8i16)
4462 return PPC::VCMPGTUH;
4463 else if (VecVT == MVT::v4i32)
4464 return PPC::VCMPGTUW;
4465 else if (VecVT == MVT::v2i64)
4466 return PPC::VCMPGTUD;
4467 else if (VecVT == MVT::v1i128)
4468 return PPC::VCMPGTUQ;
4477bool PPCDAGToDAGISel::trySETCC(SDNode *
N) {
4480 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()) {
4579 EVT VecVT =
LHS.getValueType();
4595 unsigned int VCmpInst =
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) ||
4752 if (!SelCCTrueConst || !SelCCFalseConst)
4757 if (SelCCTVal == -1 && SelCCFVal == 1) {
4759 }
else if (SelCCTVal != 1 || SelCCFVal != -1)
4769 bool InnerSwapped =
false;
4770 if (
LHS == InnerRHS &&
RHS == InnerLHS)
4771 InnerSwapped =
true;
4772 else if (
LHS != InnerLHS ||
RHS != InnerRHS)
4783 NeedSwapOps = (InnerCC ==
ISD::SETGT) ? InnerSwapped : !InnerSwapped;
4800 NeedSwapOps = (TrueResVal == 1);
4819 NeedSwapOps = (TrueResVal == -1);
4828 LLVM_DEBUG(
dbgs() <<
"Found a node that can be lowered to a SETB: ");
4836 if (
N.getOpcode() == PPCISD::FTSQRT)
4841 switch (
N.getConstantOperandVal(0)) {
4842 case Intrinsic::ppc_vsx_xvtdivdp:
4843 case Intrinsic::ppc_vsx_xvtdivsp:
4844 case Intrinsic::ppc_vsx_xvtsqrtdp:
4845 case Intrinsic::ppc_vsx_xvtsqrtsp:
4851bool PPCDAGToDAGISel::tryFoldSWTestBRCC(SDNode *
N) {
4909bool PPCDAGToDAGISel::trySelectLoopCountIntrinsic(SDNode *
N) {
4921 LHS.getOperand(0).getConstantOperandVal(1) != Intrinsic::loop_decrement)
4928 "Counter decrement comparison is not EQ or NE");
4931 assert(OldDecrement.
hasOneUse() &&
"loop decrement has more than one use!");
4933 SDLoc DecrementLoc(OldDecrement);
4935 SDValue DecrementOps[] = {
Subtarget->isPPC64() ? getI64Imm(1, DecrementLoc)
4936 : getI32Imm(1, DecrementLoc)};
4937 unsigned DecrementOpcode =
4938 Subtarget->isPPC64() ? PPC::DecreaseCTR8loop : PPC::DecreaseCTRloop;
4939 SDNode *NewDecrement = CurDAG->
getMachineNode(DecrementOpcode, DecrementLoc,
4940 MVT::i1, DecrementOps);
4942 unsigned Val =
RHS->getAsZExtVal();
4944 unsigned Opcode = IsBranchOnTrue ? PPC::BC : PPC::BCn;
4946 ReplaceUses(
LHS.getValue(0),
LHS.getOperand(1));
4950 ReplaceUses(OldDecrement.
getValue(1), ChainInput);
4954 ChainInput,
N->getOperand(0));
4957 N->getOperand(4), Chain);
4961bool PPCDAGToDAGISel::tryAsSingleRLWINM(SDNode *
N) {
4969 unsigned SH, MB, ME;
4972 if (isRotateAndMask(Val.
getNode(),
Imm,
false, SH, MB, ME)) {
4974 SDValue Ops[] = {Val, getI32Imm(SH, dl), getI32Imm(MB, dl),
4985 unsigned AlreadyCleared = 0;
4988 if (IntrinsicID == Intrinsic::ppc_lbarx)
4989 AlreadyCleared = 24;
4990 else if (IntrinsicID == Intrinsic::ppc_lharx)
4991 AlreadyCleared = 16;
4992 if (AlreadyCleared != 0 && AlreadyCleared == MB && ME == 31) {
4993 ReplaceUses(
SDValue(
N, 0),
N->getOperand(0));
4998 SDValue Ops[] = {Val, getI32Imm(0, dl), getI32Imm(MB, dl),
5006 ReplaceUses(
SDValue(
N, 0),
N->getOperand(1));
5013bool PPCDAGToDAGISel::tryAsSingleRLWINM8(SDNode *
N) {
5030 SDValue Ops[] = {
N->getOperand(0), getI64Imm(0, dl), getI64Imm(MB - 32, dl),
5031 getI64Imm(ME - 32, dl)};
5039bool PPCDAGToDAGISel::tryAsPairOfRLDICL(SDNode *
N) {
5059 if (NumOfLeadingZeros != 0)
5072 unsigned OnesOnLeft = ME + 1;
5073 unsigned ZerosInBetween = (MB - ME + 63) & 63;
5077 getI64Imm(OnesOnLeft, Loc),
5078 getI64Imm(ZerosInBetween, Loc)),
5087 SDValue Ops[] = {Val, getI64Imm(64 - OnesOnLeft, Loc),
5088 getI64Imm(NumOfLeadingZeros, Loc)};
5093bool PPCDAGToDAGISel::tryAsSingleRLWIMI(SDNode *
N) {
5123 getI32Imm(MB, dl), getI32Imm(ME, dl)};
5131bool PPCDAGToDAGISel::tryAsSingleRLDCL(SDNode *
N) {
5160bool PPCDAGToDAGISel::tryAsSingleRLDICL(SDNode *
N) {
5179 auto ImDef = CurDAG->
getMachineNode(PPC::IMPLICIT_DEF, dl, ResultType);
5184 getI32Imm(PPC::sub_32, dl)),
5197 assert(
Imm < 64 &&
"Illegal shift amount");
5202 SDValue Ops[] = {Val, getI32Imm(SH, dl), getI32Imm(MB, dl)};
5207bool PPCDAGToDAGISel::tryAsSingleRLDICR(SDNode *
N) {
5220 SDValue Ops[] = {
N->getOperand(0), getI32Imm(SH, dl), getI32Imm(MB, dl)};
5225bool PPCDAGToDAGISel::tryAsSingleRLDIMI(SDNode *
N) {
5239 unsigned SH = 63 - ME;
5245 getI32Imm(SH, Dl), getI32Imm(MB, Dl)};
5252void PPCDAGToDAGISel::Select(SDNode *
N) {
5254 if (
N->isMachineOpcode()) {
5267 if (tryBitPermutation(
N))
5271 if (tryIntCompareInGPR(
N))
5274 switch (
N->getOpcode()) {
5278 if (
N->getValueType(0) == MVT::i64) {
5285 auto IntrinsicID =
N->getConstantOperandVal(1);
5286 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
5287 IntrinsicID != Intrinsic::ppc_trapd &&
5288 IntrinsicID != Intrinsic::ppc_trap)
5290 unsigned Opcode = (IntrinsicID == Intrinsic::ppc_tdw ||
5291 IntrinsicID == Intrinsic::ppc_trapd)
5296 if (IntrinsicID == Intrinsic::ppc_tdw ||
5297 IntrinsicID == Intrinsic::ppc_tw) {
5298 SDValue Ops[] = {
N->getOperand(4),
N->getOperand(2),
N->getOperand(3)};
5299 int16_t SImmOperand2;
5300 int16_t SImmOperand3;
5301 int16_t SImmOperand4;
5302 bool isOperand2IntS16Immediate =
5304 bool isOperand3IntS16Immediate =
5309 if (isOperand2IntS16Immediate == isOperand3IntS16Immediate)
5310 Opcode = IntrinsicID == Intrinsic::ppc_tdw ? PPC::TD : PPC::TW;
5311 else if (isOperand3IntS16Immediate)
5313 Ops[2] = getI32Imm(
int(SImmOperand3) & 0xFFFF, dl);
5316 bool isOperand4IntS16Immediate =
5318 (void)isOperand4IntS16Immediate;
5319 assert(isOperand4IntS16Immediate &&
5320 "The 4th operand is not an Immediate");
5322 int16_t TO = int(SImmOperand4) & 0x1F;
5324 if ((TO & 0x1) != ((TO & 0x2) >> 1))
5325 TO = (TO & 0x1) ? TO + 1 : TO - 1;
5327 if ((TO & 0x8) != ((TO & 0x10) >> 1))
5328 TO = (TO & 0x8) ? TO + 8 : TO - 8;
5329 Ops[0] = getI32Imm(TO, dl);
5330 Ops[1] =
N->getOperand(3);
5331 Ops[2] = getI32Imm(
int(SImmOperand2) & 0xFFFF, dl);
5336 OpsWithMD = {getI32Imm(24, dl),
N->getOperand(2), getI32Imm(0, dl)};
5340 if (
N->getNumOperands() > MDIndex) {
5341 SDValue MDV =
N->getOperand(MDIndex);
5346 "ppc-trap-reason") &&
5347 "Unsupported annotation data type!");
5350 "Invalid data type for annotation ppc-trap-reason!");
5353 MD->
getOperand(i))->getString().str()), dl));
5368 auto IntID =
N->getConstantOperandVal(0);
5369 if (IntID == Intrinsic::ppc_fsels) {
5370 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2),
N->getOperand(3)};
5375 if (IntID == Intrinsic::ppc_bcdadd_p || IntID == Intrinsic::ppc_bcdsub_p) {
5378 IntID == Intrinsic::ppc_bcdadd_p ? PPC::BCDADD_rec : PPC::BCDSUB_rec;
5379 unsigned SubReg = 0;
5380 unsigned ShiftVal = 0;
5384 SubReg = PPC::sub_eq;
5388 SubReg = PPC::sub_eq;
5393 SubReg = PPC::sub_lt;
5397 SubReg = PPC::sub_lt;
5402 SubReg = PPC::sub_gt;
5406 SubReg = PPC::sub_gt;
5411 SubReg = PPC::sub_un;
5414 SubReg = PPC::sub_un;
5419 EVT VTs[] = {MVT::v16i8, MVT::Glue};
5429 CurDAG->
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
5430 CR6Reg, SubRegIdx, BCDOp.
getValue(1)),
5439 SDValue Ops[] = {Move, getI32Imm((32 - (4 + ShiftVal)) & 31, dl),
5440 getI32Imm(31, dl), getI32Imm(31, dl)};
5446 CurDAG->
SelectNodeTo(
N, PPC::XORI, MVT::i32, Shift, getI32Imm(1, dl));
5454 unsigned Opcode = 0;
5458 case Intrinsic::ppc_altivec_vstribr_p:
5459 Opcode = PPC::VSTRIBR_rec;
5461 case Intrinsic::ppc_altivec_vstribl_p:
5462 Opcode = PPC::VSTRIBL_rec;
5464 case Intrinsic::ppc_altivec_vstrihr_p:
5465 Opcode = PPC::VSTRIHR_rec;
5467 case Intrinsic::ppc_altivec_vstrihl_p:
5468 Opcode = PPC::VSTRIHL_rec;
5475 EVT VTs[] = {MVT::v16i8, MVT::Glue};
5483 CurDAG->
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
5484 CR6Reg, SubRegIdx, VecStrOp.
getValue(1)),
5498 case PPCISD::ADDI_TLSLD_L_ADDR:
5499 case PPCISD::ADDI_TLSGD_L_ADDR: {
5501 if (PPCLowering->getPointerTy(CurDAG->
getDataLayout()) != MVT::i32 ||
5510 case PPCISD::CALL_RM: {
5528 ReplaceNode(
N, getGlobalBaseReg());
5532 selectFrameIndex(
N,
N);
5538 N->getOperand(0), InGlue));
5543 ReplaceNode(
N, CurDAG->
getMachineNode(PPC::ReadTB, dl, MVT::i32, MVT::i32,
5544 MVT::Other,
N->getOperand(0)));
5551 getConstantIntValue(), dl,
5552 N->getValueType(0));
5553 if (
N->getValueType(0) == MVT::i64) {
5561 assert(
N->getValueType(0) == MVT::i32 &&
5562 "Expecting i64 or i32 in PPCISD::SRA_ADDZE");
5578 if (tryTLSXFormStore(ST))
5585 EVT LoadedVT =
LD->getMemoryVT();
5592 if (tryTLSXFormLoad(LD))
5603 if (
LD->getValueType(0) != MVT::i64) {
5605 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5608 case MVT::f64: Opcode = PPC::LFDU;
break;
5609 case MVT::f32: Opcode = PPC::LFSU;
break;
5610 case MVT::i32: Opcode = PPC::LWZU;
break;
5611 case MVT::i16: Opcode = isSExt ? PPC::LHAU : PPC::LHZU;
break;
5613 case MVT::i8: Opcode = PPC::LBZU;
break;
5616 assert(
LD->getValueType(0) == MVT::i64 &&
"Unknown load result type!");
5617 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5620 case MVT::i64: Opcode = PPC::LDU;
break;
5621 case MVT::i32: Opcode = PPC::LWZU8;
break;
5622 case MVT::i16: Opcode = isSExt ? PPC::LHAU8 : PPC::LHZU8;
break;
5624 case MVT::i8: Opcode = PPC::LBZU8;
break;
5632 Opcode, dl,
LD->getValueType(0),
5634 transferMemOperands(
N, MN);
5640 if (
LD->getValueType(0) != MVT::i64) {
5642 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5645 case MVT::f64: Opcode = PPC::LFDUX;
break;
5646 case MVT::f32: Opcode = PPC::LFSUX;
break;
5647 case MVT::i32: Opcode = PPC::LWZUX;
break;
5648 case MVT::i16: Opcode = isSExt ? PPC::LHAUX : PPC::LHZUX;
break;
5650 case MVT::i8: Opcode = PPC::LBZUX;
break;
5653 assert(
LD->getValueType(0) == MVT::i64 &&
"Unknown load result type!");
5654 assert((!isSExt || LoadedVT == MVT::i16 || LoadedVT == MVT::i32) &&
5655 "Invalid sext update load");
5658 case MVT::i64: Opcode = PPC::LDUX;
break;
5659 case MVT::i32: Opcode = isSExt ? PPC::LWAUX : PPC::LWZUX8;
break;
5660 case MVT::i16: Opcode = isSExt ? PPC::LHAUX8 : PPC::LHZUX8;
break;
5662 case MVT::i8: Opcode = PPC::LBZUX8;
break;
5670 Opcode, dl,
LD->getValueType(0),
5672 transferMemOperands(
N, MN);
5680 if (tryAsSingleRLWINM(
N) || tryAsSingleRLWIMI(
N) || tryAsSingleRLDCL(
N) ||
5681 tryAsSingleRLDICL(
N) || tryAsSingleRLDICR(
N) || tryAsSingleRLWINM8(
N) ||
5682 tryAsPairOfRLDICL(
N))
5688 if (
N->getValueType(0) == MVT::i32)
5689 if (tryBitfieldInsert(
N))
5700 selectFrameIndex(
N,
N->getOperand(0).getNode(), (int64_t)
Imm);
5707 if (tryAsSingleRLDIMI(
N))
5715 (Imm64 & ~0xFFFFFFFFuLL) == 0) {
5719 if (ImmHi != 0 && ImmLo != 0) {
5722 getI16Imm(ImmLo, dl));
5738 (Imm64 & ~0xFFFFFFFFuLL) == 0) {
5742 if (ImmHi != 0 && ImmLo != 0) {
5745 getI16Imm(ImmLo, dl));
5758 selectFrameIndex(
N,
N->getOperand(0).getNode(), (int64_t)
Imm);
5765 unsigned Imm, SH, MB, ME;
5767 isRotateAndMask(
N,
Imm,
true, SH, MB, ME)) {
5769 getI32Imm(SH, dl), getI32Imm(MB, dl),
5770 getI32Imm(ME, dl) };
5779 unsigned Imm, SH, MB, ME;
5781 isRotateAndMask(
N,
Imm,
true, SH, MB, ME)) {
5783 getI32Imm(SH, dl), getI32Imm(MB, dl),
5784 getI32Imm(ME, dl) };
5814 SDNode *MulNode = CurDAG->
getMachineNode(PPC::MULLI8, dl, MVT::i64,
5815 N->getOperand(0), SDImm);
5818 getI32Imm(63 - Shift, dl)};
5823 SDNode *MulNode = CurDAG->
getMachineNode(PPC::MULLI, dl, MVT::i32,
5824 N->getOperand(0), SDImm);
5827 getI32Imm(0, dl), getI32Imm(31 - Shift, dl)};
5839 EVT InVT =
N->getOperand(0).getValueType();
5840 assert((InVT == MVT::i64 || InVT == MVT::i32) &&
5841 "Invalid input type for ANDI_rec_1_EQ_BIT");
5843 unsigned Opcode = (InVT == MVT::i64) ? PPC::ANDI8_rec : PPC::ANDI_rec;
5853 CurDAG->
SelectNodeTo(
N, TargetOpcode::EXTRACT_SUBREG, MVT::i1, CR0Reg,
5854 SRIdxVal,
SDValue(AndI.getNode(), 1) );
5861 bool isPPC64 = (PtrVT == MVT::i64);
5864 if (
Subtarget->useCRBits() &&
N->getOperand(0).getValueType() == MVT::i1)
5868 bool NeedSwapOps =
false;
5869 bool IsUnCmp =
false;
5885 N,
N->getSimpleValueType(0) == MVT::i64 ? PPC::SETB8 : PPC::SETB,
5886 N->getValueType(0), GenCC);
5897 N->getValueType(0) == MVT::i32) {
5900 N->getOperand(0), getI32Imm(~0U, dl));
5902 N->getOperand(0),
SDValue(Tmp, 1));
5906 SDValue CCReg = SelectCC(
N->getOperand(0),
N->getOperand(1),
CC, dl);
5908 if (
N->getValueType(0) == MVT::i1) {
5916 case 0: SRI = PPC::sub_lt;
break;
5917 case 1: SRI = PPC::sub_gt;
break;
5918 case 2: SRI = PPC::sub_eq;
break;
5919 case 3: SRI = PPC::sub_un;
break;
5926 SDValue C = Inv ? NotCCBit : CCBit,
5927 NotC = Inv ? CCBit : NotCCBit;
5930 C,
N->getOperand(2)), 0);
5932 NotC,
N->getOperand(3)), 0);
5934 CurDAG->
SelectNodeTo(
N, PPC::CROR, MVT::i1, CAndT, NotCAndF);
5941 unsigned SelectCCOp;
5942 if (
N->getValueType(0) == MVT::i32)
5943 SelectCCOp = PPC::SELECT_CC_I4;
5944 else if (
N->getValueType(0) == MVT::i64)
5945 SelectCCOp = PPC::SELECT_CC_I8;
5946 else if (
N->getValueType(0) == MVT::f32) {
5948 SelectCCOp = PPC::SELECT_CC_VSSRC;
5950 SelectCCOp = PPC::SELECT_CC_SPE4;
5952 SelectCCOp = PPC::SELECT_CC_F4;
5953 }
else if (
N->getValueType(0) == MVT::f64) {
5955 SelectCCOp = PPC::SELECT_CC_VSFRC;
5957 SelectCCOp = PPC::SELECT_CC_SPE;
5959 SelectCCOp = PPC::SELECT_CC_F8;
5960 }
else if (
N->getValueType(0) == MVT::f128)
5961 SelectCCOp = PPC::SELECT_CC_F16;
5963 SelectCCOp = PPC::SELECT_CC_SPE;
5964 else if (
N->getValueType(0) == MVT::v2f64 ||
5965 N->getValueType(0) == MVT::v2i64)
5966 SelectCCOp = PPC::SELECT_CC_VSRC;
5968 SelectCCOp = PPC::SELECT_CC_VRRC;
5971 getI32Imm(BROpc, dl) };
5976 if (
Subtarget->hasVSX() && (
N->getValueType(0) == MVT::v2f64 ||
5977 N->getValueType(0) == MVT::v2i64)) {
5984 for (
int i = 0; i < 2; ++i)
5990 if (Op1 == Op2 &&
DM[0] == 0 &&
DM[1] == 0 &&
5996 if (
LD->isUnindexed() &&
LD->hasOneUse() && Op1.
hasOneUse() &&
5997 (
LD->getMemoryVT() == MVT::f64 ||
5998 LD->getMemoryVT() == MVT::i64) &&
6002 MachineMemOperand *MemOp =
LD->getMemOperand();
6004 N->getValueType(0),
Ops);
6014 unsigned tmp =
DM[0];
6030 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(0) };
6032 ? (IsPPC64 ? PPC::BDNZ8 : PPC::BDNZ)
6033 : (IsPPC64 ? PPC::BDZ8 : PPC::BDZ),
6037 case PPCISD::COND_BRANCH: {
6044 unsigned PCC =
N->getConstantOperandVal(1);
6055 if (tryFoldSWTestBRCC(
N))
6057 if (trySelectLoopCountIntrinsic(
N))
6063 if (
N->getOperand(2).getValueType() == MVT::i1) {
6086 N->getOperand(
Swap ? 3 : 2),
6087 N->getOperand(
Swap ? 2 : 3)), 0);
6088 CurDAG->
SelectNodeTo(
N, PPC::BC, MVT::Other, BitComp,
N->getOperand(4),
6098 N->getOperand(4),
N->getOperand(0) };
6106 unsigned Opc =
Target.getValueType() == MVT::i32 ? PPC::MTCTR : PPC::MTCTR8;
6107 unsigned Reg =
Target.getValueType() == MVT::i32 ? PPC::BCTR : PPC::BCTR8;
6113 case PPCISD::TOC_ENTRY: {
6114 const bool isPPC64 =
Subtarget->isPPC64();
6115 const bool isELFABI =
Subtarget->isSVR4ABI();
6116 const bool isAIXABI =
Subtarget->isAIXABI();
6122 "PowerPC doesn't support tiny or kernel code models.");
6133 auto replaceWith = [
this, &dl](
unsigned OpCode, SDNode *TocEntry,
6135 SDValue GA = TocEntry->getOperand(0);
6136 SDValue TocBase = TocEntry->getOperand(1);
6137 SDNode *MN =
nullptr;
6138 if (OpCode == PPC::ADDItoc || OpCode == PPC::ADDItoc8)
6144 transferMemOperands(TocEntry, MN);
6146 ReplaceNode(TocEntry, MN);
6155 "32-bit ELF can only have TOC entries in position independent"
6158 replaceWith(PPC::LWZtoc,
N, MVT::i32);
6162 assert(isAIXABI &&
"ELF ABI already handled");
6165 replaceWith(PPC::ADDItoc,
N, MVT::i32);
6169 replaceWith(PPC::LWZtoc,
N, MVT::i32);
6174 assert(isAIXABI &&
"ELF ABI handled in common SelectCode");
6177 replaceWith(PPC::ADDItoc8,
N, MVT::i64);
6187 assert((isPPC64 || (isAIXABI && !isPPC64)) &&
"We are dealing with 64-bit"
6188 " ELF/AIX or 32-bit AIX in the following.");
6213 isPPC64 ? PPC::ADDIStocHA8 : PPC::ADDIStocHA, dl, VT, TOCbase, GA);
6220 dl, VT,
SDValue(Tmp, 0), GA));
6224 if (PPCLowering->isAccessedAsGotIndirect(GA)) {
6228 isPPC64 ? PPC::LDtocL : PPC::LWZtocL, dl, VT, GA,
SDValue(Tmp, 0));
6230 transferMemOperands(
N, MN);
6235 assert(isPPC64 &&
"TOC_ENTRY already handled for 32-bit.");
6244 "PPCISD::PPC32_PICGOT is only supported for 32-bit SVR4");
6255 "Invalid operand on VADD_SPLAT!");
6257 int Elt =
N->getConstantOperandVal(0);
6258 int EltSize =
N->getConstantOperandVal(1);
6259 unsigned Opc1, Opc2, Opc3;
6263 Opc1 = PPC::VSPLTISB;
6264 Opc2 = PPC::VADDUBM;
6265 Opc3 = PPC::VSUBUBM;
6267 }
else if (EltSize == 2) {
6268 Opc1 = PPC::VSPLTISH;
6269 Opc2 = PPC::VADDUHM;
6270 Opc3 = PPC::VSUBUHM;
6273 assert(EltSize == 4 &&
"Invalid element size on VADD_SPLAT!");
6274 Opc1 = PPC::VSPLTISW;
6275 Opc2 = PPC::VADDUWM;
6276 Opc3 = PPC::VSUBUWM;
6280 if ((Elt & 1) == 0) {
6287 SDValue EltVal = getI32Imm(Elt >> 1, dl);
6292 }
else if (Elt > 0) {
6299 SDValue EltVal = getI32Imm(Elt - 16, dl);
6301 EltVal = getI32Imm(-16, dl);
6313 SDValue EltVal = getI32Imm(Elt + 16, dl);
6315 EltVal = getI32Imm(-16, dl);
6322 case PPCISD::LD_SPLAT: {
6329 EVT
Type =
N->getValueType(0);
6330 if (
Type != MVT::v16i8 &&
Type != MVT::v8i16)
6339 isOffsetMultipleOf(
N, 16))
6345 unsigned LIOpcode =
Subtarget->isPPC64() ? PPC::LI8 : PPC::LI;
6360 unsigned SplatOp = (
Type == MVT::v16i8) ? PPC::VSPLTB : PPC::VSPLTH;
6361 unsigned SplatElemIndex =
6372 SDNode *LoadHigh = LoadLow;
6373 if (
Type == MVT::v8i16) {
6375 PPC::LVX, dl, MVT::v16i8, MVT::Other,
6377 LIOpcode, dl, MVT::i32,
6380 N->getOperand(1),
SDValue(LoadLow, 1)});
6384 transferMemOperands(
N, LoadHigh);
6405SDValue PPCDAGToDAGISel::combineToCMPB(SDNode *
N) {
6409 "Only OR nodes are supported for CMPB");
6415 if (
N->getValueType(0) != MVT::i32 &&
6416 N->getValueType(0) != MVT::i64)
6419 EVT VT =
N->getValueType(0);
6422 bool BytesFound[8] = {
false,
false,
false,
false,
false,
false,
false,
false};
6425 auto IsByteSelectCC = [
this](
SDValue O,
unsigned &
b,
6435 uint64_t PM =
O.getConstantOperandVal(2);
6436 uint64_t PAlt =
O.getConstantOperandVal(3);
6437 for (b = 0;
b < 8; ++
b) {
6439 if (PM && (PM & Mask) == PM && (PAlt & Mask) == PAlt)
6449 O.getConstantOperandVal(1) != 0) {
6450 SDValue Op0 =
O.getOperand(0), Op1 =
O.getOperand(1);
6482 uint64_t ULim =
O.getConstantOperandVal(1);
6483 if (ULim != (UINT64_C(1) << b*8))
6508 if (
Op.getConstantOperandVal(1) != (UINT64_C(0xFF) << (8*b)))
6523 unsigned Bits =
Op.getValueSizeInBits();
6526 if (
Op.getConstantOperandVal(1) != Bits-8)
6544 while (!
Queue.empty()) {
6547 for (
const SDValue &O :
V.getNode()->ops()) {
6553 }
else if (IsByteSelectCC(O, b, M,
A, OLHS, ORHS)) {
6557 BytesFound[
b] =
true;
6560 }
else if ((
LHS == ORHS &&
RHS == OLHS) ||
6561 (
RHS == ORHS &&
LHS == OLHS)) {
6562 BytesFound[
b] =
true;
6574 unsigned LastB = 0, BCnt = 0;
6575 for (
unsigned i = 0; i < 8; ++i)
6576 if (BytesFound[LastB]) {
6581 if (!LastB || BCnt < 2)
6586 if (
LHS.getValueType() != VT) {
6593 bool NonTrivialMask = ((int64_t)
Mask) != INT64_C(-1);
6594 if (NonTrivialMask && !Alt) {
6621void PPCDAGToDAGISel::foldBoolExts(
SDValue &Res, SDNode *&
N) {
6630 if (
N->getOperand(0).getValueType() != MVT::i1)
6633 if (!
N->hasOneUse())
6637 EVT VT =
N->getValueType(0);
6644 SDNode *
User = *
N->user_begin();
6645 if (
User->getNumOperands() != 2)
6654 User->getValueType(0), {O0, O1});
6659 SDValue TrueRes = TryFold(ConstTrue);
6660 if (!TrueRes || TrueRes.
isUndef())
6662 SDValue FalseRes = TryFold(ConstFalse);
6663 if (!FalseRes || FalseRes.
isUndef())
6676 ConstTrue = TrueRes;
6677 ConstFalse = FalseRes;
6678 }
while (
N->hasOneUse());
6681void PPCDAGToDAGISel::PreprocessISelDAG() {
6684 bool MadeChange =
false;
6686 SDNode *
N = &*--Position;
6691 switch (
N->getOpcode()) {
6694 Res = combineToCMPB(
N);
6699 foldBoolExts(Res,
N);
6719void PPCDAGToDAGISel::PostprocessISelDAG() {
6726 PeepholePPC64ZExt();
6734bool PPCDAGToDAGISel::AllUsersSelectZero(SDNode *
N) {
6735 for (
const SDNode *User :
N->users()) {
6736 if (!
User->isMachineOpcode())
6738 if (
User->getMachineOpcode() != PPC::SELECT_I4 &&
6739 User->getMachineOpcode() != PPC::SELECT_I8)
6742 SDNode *Op1 =
User->getOperand(1).getNode();
6743 SDNode *Op2 =
User->getOperand(2).getNode();
6763void PPCDAGToDAGISel::SwapAllSelectUsers(SDNode *
N) {
6765 for (SDNode *User :
N->users()) {
6766 assert((
User->getMachineOpcode() == PPC::SELECT_I4 ||
6767 User->getMachineOpcode() == PPC::SELECT_I8) &&
6768 "Must have all select users");
6772 for (SDNode *User : ToReplace) {
6775 User->getValueType(0),
User->getOperand(0),
6776 User->getOperand(2),
6777 User->getOperand(1));
6785 ReplaceUses(User, ResNode);
6789void PPCDAGToDAGISel::PeepholeCROps() {
6793 for (SDNode &Node : CurDAG->
allnodes()) {
6795 if (!MachineNode || MachineNode->
use_empty())
6797 SDNode *ResNode = MachineNode;
6799 bool Op1Set =
false, Op1Unset =
false,
6801 Op2Set =
false, Op2Unset =
false,
6816 if (
Op.isMachineOpcode()) {
6817 if (
Op.getMachineOpcode() == PPC::CRSET)
6819 else if (
Op.getMachineOpcode() == PPC::CRUNSET)
6821 else if ((
Op.getMachineOpcode() == PPC::CRNOR &&
6822 Op.getOperand(0) ==
Op.getOperand(1)) ||
6823 Op.getMachineOpcode() == PPC::CRNOT)
6830 case PPC::SELECT_I4:
6831 case PPC::SELECT_I8:
6832 case PPC::SELECT_F4:
6833 case PPC::SELECT_F8:
6834 case PPC::SELECT_SPE:
6835 case PPC::SELECT_SPE4:
6836 case PPC::SELECT_VRRC:
6837 case PPC::SELECT_VSFRC:
6838 case PPC::SELECT_VSSRC:
6839 case PPC::SELECT_VSRC: {
6841 if (
Op.isMachineOpcode()) {
6842 if (
Op.getMachineOpcode() == PPC::CRSET)
6844 else if (
Op.getMachineOpcode() == PPC::CRUNSET)
6846 else if ((
Op.getMachineOpcode() == PPC::CRNOR &&
6847 Op.getOperand(0) ==
Op.getOperand(1)) ||
6848 Op.getMachineOpcode() == PPC::CRNOT)
6855 bool SelectSwap =
false;
6868 else if (Op1Unset || Op2Unset)
6870 ResNode = CurDAG->
getMachineNode(PPC::CRUNSET, SDLoc(MachineNode),
6874 ResNode = CurDAG->
getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
6880 ResNode = CurDAG->
getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
6884 else if (AllUsersSelectZero(MachineNode)) {
6885 ResNode = CurDAG->
getMachineNode(PPC::CRNAND, SDLoc(MachineNode),
6907 else if (Op1Unset || Op2Unset)
6923 else if (AllUsersSelectZero(MachineNode)) {
6934 else if (Op1Set || Op2Set)
6956 else if (AllUsersSelectZero(MachineNode)) {
6966 ResNode = CurDAG->
getMachineNode(PPC::CRUNSET, SDLoc(MachineNode),
6996 else if (AllUsersSelectZero(MachineNode)) {
7004 if (Op1Set || Op2Set)
7006 ResNode = CurDAG->
getMachineNode(PPC::CRUNSET, SDLoc(MachineNode),
7020 ResNode = CurDAG->
getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
7026 ResNode = CurDAG->
getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
7030 else if (AllUsersSelectZero(MachineNode)) {
7070 else if (AllUsersSelectZero(MachineNode)) {
7080 ResNode = CurDAG->
getMachineNode(PPC::CRUNSET, SDLoc(MachineNode),
7087 else if (Op1Unset || Op2Set)
7089 ResNode = CurDAG->
getMachineNode(PPC::CRUNSET, SDLoc(MachineNode),
7106 else if (AllUsersSelectZero(MachineNode)) {
7118 else if (Op1Set || Op2Unset)
7132 ResNode = CurDAG->
getMachineNode(PPC::CRNAND, SDLoc(MachineNode),
7142 else if (AllUsersSelectZero(MachineNode)) {
7143 ResNode = CurDAG->
getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
7149 case PPC::SELECT_I4:
7150 case PPC::SELECT_I8:
7151 case PPC::SELECT_F4:
7152 case PPC::SELECT_F8:
7153 case PPC::SELECT_SPE:
7154 case PPC::SELECT_SPE4:
7155 case PPC::SELECT_VRRC:
7156 case PPC::SELECT_VSFRC:
7157 case PPC::SELECT_VSSRC:
7158 case PPC::SELECT_VSRC:
7190 SwapAllSelectUsers(MachineNode);
7192 if (ResNode != MachineNode) {
7199 ReplaceUses(MachineNode, ResNode);
7205 }
while (IsModified);
7316 if (!Op0OK && !Op1OK)
7339 if (!Op0OK && !Op1OK)
7353void PPCDAGToDAGISel::PeepholePPC64ZExt() {
7368 bool MadeChange =
false;
7370 SDNode *
N = &*--Position;
7372 if (
N->use_empty() || !
N->isMachineOpcode())
7375 if (
N->getMachineOpcode() != PPC::RLDICL)
7378 if (
N->getConstantOperandVal(1) != 0 ||
7379 N->getConstantOperandVal(2) != 32)
7408 SmallPtrSet<SDNode *, 16> ToPromote;
7414 bool OutsideUse =
false;
7415 for (SDNode *PN : ToPromote) {
7416 for (SDNode *UN : PN->users()) {
7417 if (!ToPromote.count(UN) && UN != ISR.
getNode()) {
7435 for (SDNode *PN : ToPromote) {
7437 switch (PN->getMachineOpcode()) {
7440 case PPC::RLWINM: NewOpcode = PPC::RLWINM8;
break;
7441 case PPC::RLWNM: NewOpcode = PPC::RLWNM8;
break;
7442 case PPC::SLW: NewOpcode = PPC::SLW8;
break;
7443 case PPC::SRW: NewOpcode = PPC::SRW8;
break;
7444 case PPC::LI: NewOpcode = PPC::LI8;
break;
7445 case PPC::LIS: NewOpcode = PPC::LIS8;
break;
7446 case PPC::LHBRX: NewOpcode = PPC::LHBRX8;
break;
7447 case PPC::LWBRX: NewOpcode = PPC::LWBRX8;
break;
7448 case PPC::CNTLZW: NewOpcode = PPC::CNTLZW8;
break;
7449 case PPC::CNTTZW: NewOpcode = PPC::CNTTZW8;
break;
7450 case PPC::RLWIMI: NewOpcode = PPC::RLWIMI8;
break;
7451 case PPC::OR: NewOpcode = PPC::OR8;
break;
7452 case PPC::SELECT_I4: NewOpcode = PPC::SELECT_I8;
break;
7453 case PPC::ORI: NewOpcode = PPC::ORI8;
break;
7454 case PPC::ORIS: NewOpcode = PPC::ORIS8;
break;
7455 case PPC::AND: NewOpcode = PPC::AND8;
break;
7457 NewOpcode = PPC::ANDI8_rec;
7459 case PPC::ANDIS_rec:
7460 NewOpcode = PPC::ANDIS8_rec;
7470 for (
const SDValue &
V : PN->ops()) {
7471 if (!ToPromote.count(
V.getNode()) &&
V.getValueType() == MVT::i32 &&
7488 SDVTList VTs = PN->getVTList();
7489 for (
unsigned i = 0, ie = VTs.
NumVTs; i != ie; ++i)
7490 if (VTs.
VTs[i] == MVT::i32)
7523 if (!
N->isMachineOpcode())
7525 unsigned Opc =
N->getMachineOpcode();
7529 if (
Opc == PPC::XXPERMDIs) {
7531 N->getConstantOperandVal(1) == 2;
7532 }
else if (
Opc == PPC::XXPERMDI ||
Opc == PPC::XXSLDWI) {
7533 return N->getOperand(0) ==
N->getOperand(1) &&
7535 N->getConstantOperandVal(2) == 2;
7543 if (!
N->isMachineOpcode())
7545 unsigned Opc =
N->getMachineOpcode();
7595 while (
V->isMachineOpcode() &&
7596 V->getMachineOpcode() == TargetOpcode::COPY_TO_REGCLASS) {
7598 if (
V->use_empty() || !
V->user_begin()->isOnlyUserOf(
V.getNode()))
7600 V =
V->getOperand(0);
7605 SDValue VecOp = SkipRCCopy(
N->getOperand(0));
7625 if (GV->hasAttribute(
"aix-small-tls"))
7646 if (!(
Subtarget.hasAIXSmallLocalDynamicTLS() ||
7663 if (!TPReg || (TPReg->
getReg() !=
Subtarget.getThreadPointerRegister()))
7687 if (
N->getMachineOpcode() != PPC::ADDI8)
7692 SDValue InitialADDI =
N->getOperand(0);
7703 assert(GA &&
"Expecting a valid GlobalAddressSDNode when folding addi into "
7704 "local-[exec|dynamic] accesses!");
7712 int Offset =
N->getConstantOperandVal(1);
7721void PPCDAGToDAGISel::PeepholePPC64() {
7725 SDNode *
N = &*--Position;
7727 if (
N->use_empty() || !
N->isMachineOpcode())
7738 unsigned StorageOpcode =
N->getMachineOpcode();
7739 bool RequiresMod4Offset =
false;
7741 switch (StorageOpcode) {
7746 case PPC::DFLOADf64:
7747 case PPC::DFLOADf32:
7748 RequiresMod4Offset =
true;
7764 case PPC::DFSTOREf64:
7765 case PPC::DFSTOREf32:
7766 RequiresMod4Offset =
true;
7788 if (!
Base.isMachineOpcode())
7792 bool ReplaceFlags =
true;
7804 switch (
Base.getMachineOpcode()) {
7812 ReplaceFlags =
false;
7814 case PPC::ADDIdtprelL:
7817 case PPC::ADDItlsldL:
7820 case PPC::ADDItocL8:
7835 int MaxDisplacement = 7;
7837 const GlobalValue *GV = GA->getGlobal();
7839 MaxDisplacement = std::min((
int)
Alignment.value() - 1, MaxDisplacement);
7842 bool UpdateHBase =
false;
7845 int Offset =
N->getConstantOperandVal(FirstOp);
7851 if (
Base.getMachineOpcode() != PPC::ADDItocL8)
7862 if (HImmOpnd != ImmOpnd)
7870 if (RequiresMod4Offset) {
7871 if (GlobalAddressSDNode *GA =
7873 const GlobalValue *GV = GA->getGlobal();
7888 if (RequiresMod4Offset && (
Offset % 4) != 0)
7896 }
else if (
Offset != 0) {
7904 assert(GA &&
"Expecting a valid GlobalAddressSDNode when folding "
7905 "addi into local-[exec|dynamic] accesses!");
7918 LLVM_DEBUG(
dbgs() <<
"Folding add-immediate into mem-op:\nBase: ");
7929 const GlobalValue *GV = GA->getGlobal();
7933 if (Alignment < 4 && (RequiresMod4Offset || (
Offset % 4) != 0)) {
7934 LLVM_DEBUG(
dbgs() <<
"Rejected this candidate for alignment.\n\n");
7938 }
else if (ConstantPoolSDNode *CP =
7948 Base.getOperand(0),
N->getOperand(3));
7958 if (
Base.getNode()->use_empty())
7968 return new PPCDAGToDAGISelLegacy(TM, OptLevel);
static bool isOpcWithIntImmediate(const SDNode *N, unsigned Opc, uint64_t &Imm)
const AArch64Subtarget & Subtarget
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
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
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)
cl::opt< bool > ANDIGlueBug("ppc-expose-andi-glue-bug", cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden)
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)
SmallVector< MachineOperand, 4 > Cond
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
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)
bool isLittleEndian() const
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.
const TargetRegisterClass * getInlineAsmMemoryOperandRegClass(InlineAsm::ConstraintCode C) const override
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)
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
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
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
ISD::CondCode getOperandCondCode(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.