50#include "llvm/IR/IntrinsicsPowerPC.h"
73#define DEBUG_TYPE "ppc-isel"
74#define PASS_NAME "PowerPC DAG->DAG Pattern Instruction Selection"
77 "Number of (sext(setcc)) nodes expanded into GPR sequence.");
79 "Number of (zext(setcc)) nodes expanded into GPR sequence.");
81 "Number of sign extensions for compare inputs added.");
83 "Number of zero extensions for compare inputs added.");
85 "Number of logical ops on i1 values calculated in GPR.");
87 "Number of compares not eliminated as they have non-extending uses.");
89 "Number of compares lowered to setb.");
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;
156 bool runOnMachineFunction(MachineFunction &MF)
override {
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);
192 inline SDValue getI64Imm(uint64_t Imm,
const SDLoc &dl) {
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 TargetRegisterInfo *
TRI = Subtarget->getRegisterInfo();
405 const TargetRegisterClass *TRC =
TRI->getPointerRegClass(1);
407 SDValue RC = CurDAG->getTargetConstant(TRC->
getID(), dl, MVT::i32);
409 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
410 dl,
Op.getValueType(),
413 OutOps.push_back(NewOp);
420#include "PPCGenDAGISel.inc"
423 bool trySETCC(SDNode *
N);
424 bool tryFoldSWTestBRCC(SDNode *
N);
425 bool trySelectLoopCountIntrinsic(SDNode *
N);
426 bool tryAsSingleRLDICL(SDNode *
N);
427 bool tryAsSingleRLDCL(SDNode *
N);
428 bool tryAsSingleRLDICR(SDNode *
N);
429 bool tryAsSingleRLWINM(SDNode *
N);
430 bool tryAsSingleRLWINM8(SDNode *
N);
431 bool tryAsSingleRLWIMI(SDNode *
N);
432 bool tryAsPairOfRLDICL(SDNode *
N);
433 bool tryAsSingleRLDIMI(SDNode *
N);
435 void PeepholePPC64();
436 void PeepholePPC64ZExt();
437 void PeepholeCROps();
440 void foldBoolExts(
SDValue &Res, SDNode *&
N);
442 bool AllUsersSelectZero(SDNode *
N);
443 void SwapAllSelectUsers(SDNode *
N);
445 bool isOffsetMultipleOf(SDNode *
N,
unsigned Val)
const;
446 void transferMemOperands(SDNode *
N, SDNode *Result);
452 explicit PPCDAGToDAGISelLegacy(PPCTargetMachine &tm,
454 : SelectionDAGISelLegacy(
455 ID, std::make_unique<PPCDAGToDAGISel>(tm, OptLevel)) {}
459char PPCDAGToDAGISelLegacy::ID = 0;
466SDNode *PPCDAGToDAGISel::getGlobalBaseReg() {
467 if (!GlobalBaseReg) {
475 if (PPCLowering->getPointerTy(CurDAG->getDataLayout()) == MVT::i32) {
478 if (!Subtarget->isSecurePlt() &&
488 TII.get(PPC::UpdateGBR), GlobalBaseReg)
494 RegInfo->createVirtualRegister(&PPC::GPRC_and_GPRC_NOR0RegClass);
514 return CurDAG->getRegister(GlobalBaseReg,
515 PPCLowering->getPointerTy(CurDAG->getDataLayout()))
555 if (
N->getOpcode() ==
ISD::Constant &&
N->getValueType(0) == MVT::i32) {
556 Imm =
N->getAsZExtVal();
565 if (
N->getOpcode() ==
ISD::Constant &&
N->getValueType(0) == MVT::i64) {
566 Imm =
N->getAsZExtVal();
617 if (std::max(TProb, FProb) / Threshold < std::min(TProb, FProb))
621 <<
"::" << BB->
getName() <<
"'\n"
622 <<
" -> " <<
TBB->getName() <<
": " << TProb <<
"\n"
623 <<
" -> " << FBB->
getName() <<
": " << FProb <<
"\n");
639 return N->getOpcode() ==
Opc
646 SDValue TFI = CurDAG->getTargetFrameIndex(FI,
N->getValueType(0));
647 unsigned Opc =
N->getValueType(0) == MVT::i32 ? PPC::ADDI : PPC::ADDI8;
649 CurDAG->SelectNodeTo(SN,
Opc,
N->getValueType(0), TFI,
650 getSmallIPtrImm(
Offset, dl));
652 ReplaceNode(SN, CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0), TFI,
653 getSmallIPtrImm(
Offset, dl)));
656bool PPCDAGToDAGISel::isRotateAndMask(SDNode *
N,
unsigned Mask,
657 bool isShiftMask,
unsigned &SH,
658 unsigned &MB,
unsigned &ME) {
661 if (
N->getValueType(0) != MVT::i32)
665 unsigned Indeterminant = ~0;
666 unsigned Opcode =
N->getOpcode();
667 if (
N->getNumOperands() != 2 ||
673 if (isShiftMask)
Mask =
Mask << Shift;
675 Indeterminant = ~(0xFFFFFFFFu << Shift);
678 if (isShiftMask)
Mask =
Mask >> Shift;
680 Indeterminant = ~(0xFFFFFFFFu >> Shift);
690 if (Mask && !(Mask & Indeterminant)) {
702 Base.getOpcode() == PPCISD::ADD_TLS &&
703 "Only expecting the ADD_TLS instruction to acquire the thread pointer!");
707 unsigned ADDTLSOp1Opcode = ADDTLSOp1.getOpcode();
716 if (ADDTLSOp1Opcode == PPCISD::LD_GOT_TPREL_L)
721 if (LD && LD->getBasePtr().getOpcode() == PPCISD::MAT_PCREL_ADDR)
727 if (ADDTLSOp1Opcode == PPCISD::GET_TPOINTER)
752 if (
Base.getOpcode() != PPCISD::ADD_TLS)
754 for (
auto *ADDTLSUse :
Base.getNode()->users()) {
759 if (LD->getSrcValueOffset() != 0 || !LD->getOffset().isUndef())
762 if (ST->getSrcValueOffset() != 0 || !ST->getOffset().isUndef())
768 if (
Base.getOperand(1).getOpcode() == PPCISD::TLS_LOCAL_EXEC_MAT_ADDR)
777bool PPCDAGToDAGISel::tryTLSXFormStore(StoreSDNode *ST) {
783 EVT MemVT =
ST->getMemoryVT();
784 EVT RegVT =
ST->getValue().getValueType();
791 Opcode = (RegVT == MVT::i32) ? PPC::STBXTLS_32 : PPC::STBXTLS;
795 Opcode = (RegVT == MVT::i32) ? PPC::STHXTLS_32 : PPC::STHXTLS;
799 Opcode = (RegVT == MVT::i32) ? PPC::STWXTLS_32 : PPC::STWXTLS;
803 Opcode = PPC::STDXTLS;
807 Opcode = PPC::STFSXTLS;
811 Opcode = PPC::STFDXTLS;
816 SDVTList VTs =
ST->getVTList();
819 SDNode *MN = CurDAG->getMachineNode(Opcode, dl, VTs,
Ops);
820 transferMemOperands(ST, MN);
825bool PPCDAGToDAGISel::tryTLSXFormLoad(LoadSDNode *LD) {
831 EVT MemVT =
LD->getMemoryVT();
832 EVT RegVT =
LD->getValueType(0);
839 Opcode = (RegVT == MVT::i32) ? PPC::LBZXTLS_32 : PPC::LBZXTLS;
843 if (RegVT == MVT::i32)
844 Opcode = isSExt ? PPC::LHAXTLS_32 : PPC::LHZXTLS_32;
846 Opcode = isSExt ? PPC::LHAXTLS : PPC::LHZXTLS;
850 if (RegVT == MVT::i32)
851 Opcode = isSExt ? PPC::LWAXTLS_32 : PPC::LWZXTLS_32;
853 Opcode = isSExt ? PPC::LWAXTLS : PPC::LWZXTLS;
857 Opcode = PPC::LDXTLS;
861 Opcode = PPC::LFSXTLS;
865 Opcode = PPC::LFDXTLS;
870 SDVTList VTs =
LD->getVTList();
872 SDNode *MN = CurDAG->getMachineNode(Opcode, dl, VTs,
Ops);
873 transferMemOperands(LD, MN);
880bool PPCDAGToDAGISel::tryBitfieldInsert(SDNode *
N) {
885 KnownBits LKnown = CurDAG->computeKnownBits(Op0);
886 KnownBits RKnown = CurDAG->computeKnownBits(Op1);
891 if ((TargetMask | InsertMask) == 0xFFFFFFFF) {
894 unsigned Value, SH = 0;
895 TargetMask = ~TargetMask;
896 InsertMask = ~InsertMask;
930 KnownBits MKnown = CurDAG->computeKnownBits(Op1.
getOperand(1));
944 SDValue Ops[] = { Op0, Op1, getI32Imm(SH, dl), getI32Imm(MB, dl),
946 ReplaceNode(
N, CurDAG->getMachineNode(PPC::RLWIMI, dl, MVT::i32,
Ops));
954 unsigned MaxTruncation = 0;
961 User->isMachineOpcode() ?
User->getMachineOpcode() :
User->getOpcode();
965 if (
User->isMachineOpcode())
967 MaxTruncation = std::max(MaxTruncation,
968 (
unsigned)
User->getValueType(0).getSizeInBits());
971 if (
User->isMachineOpcode())
977 MaxTruncation = std::max(MaxTruncation, MemVTSize);
986 MaxTruncation = std::max(MaxTruncation, 32u);
994 MaxTruncation = std::max(MaxTruncation, 16u);
1002 MaxTruncation = std::max(MaxTruncation, 8u);
1006 return MaxTruncation;
1014 if ((HiTZ + LoLZ) >= Num)
1026 unsigned Hi32 =
Hi_32(Imm);
1027 unsigned Lo32 =
Lo_32(Imm);
1028 SDNode *Result =
nullptr;
1031 auto getI32Imm = [CurDAG, dl](
unsigned Imm) {
1045 if (TZ > 15 && (LZ > 32 || LO > 32))
1047 getI32Imm((Imm >> 16) & 0xffff));
1051 assert(LZ < 64 &&
"Unexpected leading zeros here.");
1057 uint64_t ImmHi16 = (Imm >> 16) & 0xffff;
1058 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
1059 Result = CurDAG->
getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
1061 getI32Imm(Imm & 0xffff));
1069 if ((LZ + FO + TZ) > 48) {
1071 getI32Imm((Imm >> TZ) & 0xffff));
1073 getI32Imm(TZ), getI32Imm(LZ));
1090 if ((LZ + TO) > 48) {
1094 assert(LZ <= 32 &&
"Unexpected shift value.");
1096 getI32Imm((Imm >> (48 - LZ) & 0xffff)));
1098 getI32Imm(48 - LZ), getI32Imm(LZ));
1116 if ((LZ + FO + TO) > 48) {
1118 getI32Imm((Imm >> TO) & 0xffff));
1120 getI32Imm(TO), getI32Imm(LZ));
1126 if (LZ == 32 && ((Lo32 & 0x8000) == 0)) {
1128 getI32Imm(Lo32 & 0xffff));
1130 getI32Imm(Lo32 >> 16));
1154 getI32Imm(RotImm & 0xffff));
1156 getI32Imm(Shift), getI32Imm(0));
1163 uint64_t ImmHi16 = (Lo32 >> 16) & 0xffff;
1167 CurDAG->
getMachineNode(PPC::LI8, dl, MVT::i64, getI32Imm(ImmLo16));
1170 CurDAG->
getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(ImmHi16));
1174 CurDAG->
getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(ImmHi16));
1176 SDValue(Result, 0), getI32Imm(ImmLo16));
1193 if ((LZ + FO + TZ) > 32) {
1194 uint64_t ImmHi16 = (Imm >> (TZ + 16)) & 0xffff;
1195 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
1196 Result = CurDAG->
getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
1198 getI32Imm((Imm >> TZ) & 0xffff));
1200 getI32Imm(TZ), getI32Imm(LZ));
1207 if ((LZ + TO) > 32) {
1211 assert(LZ <= 32 &&
"Unexpected shift value.");
1213 getI32Imm((Imm >> (48 - LZ)) & 0xffff));
1215 getI32Imm((Imm >> (32 - LZ)) & 0xffff));
1217 getI32Imm(32 - LZ), getI32Imm(LZ));
1225 if ((LZ + FO + TO) > 32) {
1227 getI32Imm((Imm >> (TO + 16)) & 0xffff));
1229 getI32Imm((Imm >> TO) & 0xffff));
1231 getI32Imm(TO), getI32Imm(LZ));
1243 uint64_t ImmHi16 = (RotImm >> 16) & 0xffff;
1244 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
1245 Result = CurDAG->
getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
1247 getI32Imm(RotImm & 0xffff));
1249 getI32Imm(Shift), getI32Imm(0));
1267 unsigned Hi32 =
Hi_32(Imm);
1268 unsigned Lo32 =
Lo_32(Imm);
1270 auto getI32Imm = [CurDAG, dl](
unsigned Imm) {
1274 auto getI64Imm = [CurDAG, dl](
uint64_t Imm) {
1289 SDNode *Result =
nullptr;
1296 if ((LZ + FO + TZ) > 30) {
1297 APInt SignedInt34 =
APInt(34, (Imm >> TZ) & 0x3ffffffff);
1300 getI64Imm(Extended.getZExtValue()));
1302 getI32Imm(TZ), getI32Imm(LZ));
1318 if ((LZ + TO) > 30) {
1319 APInt SignedInt34 =
APInt(34, (Imm >> (30 - LZ)) & 0x3ffffffff);
1322 getI64Imm(Extended.getZExtValue()));
1324 getI32Imm(30 - LZ), getI32Imm(LZ));
1331 if ((LZ + FO + TO) > 30) {
1332 APInt SignedInt34 =
APInt(34, (Imm >> TO) & 0x3ffffffff);
1335 getI64Imm(Extended.getZExtValue()));
1337 getI32Imm(TO), getI32Imm(LZ));
1349 for (
unsigned Shift = 0; Shift < 63; ++Shift) {
1353 CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(RotImm));
1355 SDValue(Result, 0), getI32Imm(Shift),
1363 Result = CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(Hi32));
1373 CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(Hi32));
1375 CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(Lo32));
1382 unsigned *InstCnt =
nullptr) {
1383 unsigned InstCntDirect = 0;
1394 if (Subtarget.hasPrefixInstrs() && InstCntDirect != 1) {
1395 unsigned InstCntDirectP = 0;
1402 if (ResultP && (!Result || InstCntDirectP < InstCntDirect)) {
1404 *InstCnt = InstCntDirectP;
1411 *InstCnt = InstCntDirect;
1414 auto getI32Imm = [CurDAG, dl](
unsigned Imm) {
1423 if (Hi16OfLo32 && Lo16OfLo32) {
1426 bool IsSelected =
false;
1430 CurDAG->
getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(Hi16));
1432 SDValue(Result, 0), getI32Imm(Lo16));
1438 if (Hi16OfHi32 == Lo16OfHi32 && Lo16OfHi32 == Lo16OfLo32) {
1440 Result = getSplat(Hi16OfLo32, Lo16OfLo32);
1445 }
else if (Hi16OfHi32 == Hi16OfLo32 && Hi16OfLo32 == Lo16OfLo32) {
1447 Result = getSplat(Hi16OfHi32, Lo16OfHi32);
1450 getI32Imm(16), getI32Imm(31)};
1452 }
else if (Lo16OfHi32 == Lo16OfLo32 && Hi16OfLo32 == Lo16OfLo32) {
1454 Result = getSplat(Hi16OfHi32, Lo16OfHi32);
1457 getI32Imm(0), getI32Imm(15)};
1460 if (IsSelected ==
true) {
1473 SDValue(Result, 0), getI32Imm(Hi16OfLo32));
1478 getI32Imm(Lo16OfLo32));
1482 *InstCnt = InstCntDirect;
1491 int64_t Imm =
N->getAsZExtVal();
1503class BitPermutationSelector {
1518 VariableKnownToBeZero
1521 ValueBit(
SDValue V,
unsigned I, Kind K = Variable)
1522 :
V(
V), Idx(
I), K(K) {}
1523 ValueBit(Kind K = Variable) : Idx(UINT32_MAX), K(K) {}
1526 return K == ConstZero || K == VariableKnownToBeZero;
1529 bool hasValue()
const {
1530 return K == Variable || K == VariableKnownToBeZero;
1534 assert(hasValue() &&
"Cannot get the value of a constant bit");
1538 unsigned getValueBitIndex()
const {
1539 assert(hasValue() &&
"Cannot get the value bit index of a constant bit");
1548 unsigned StartIdx, EndIdx;
1558 bool Repl32Coalesced;
1560 BitGroup(
SDValue V,
unsigned R,
unsigned S,
unsigned E)
1561 :
V(
V), RLAmt(
R), StartIdx(S), EndIdx(
E), Repl32(
false), Repl32CR(
false),
1562 Repl32Coalesced(
false) {
1563 LLVM_DEBUG(
dbgs() <<
"\tbit group for " <<
V.getNode() <<
" RLAmt = " << R
1564 <<
" [" << S <<
", " <<
E <<
"]\n");
1570 struct ValueRotInfo {
1572 unsigned RLAmt = std::numeric_limits<unsigned>::max();
1573 unsigned NumGroups = 0;
1574 unsigned FirstGroupStartIdx = std::numeric_limits<unsigned>::max();
1575 bool Repl32 =
false;
1577 ValueRotInfo() =
default;
1585 if (Repl32 <
Other.Repl32)
1587 else if (Repl32 >
Other.Repl32)
1589 else if (NumGroups >
Other.NumGroups)
1591 else if (NumGroups <
Other.NumGroups)
1593 else if (RLAmt == 0 &&
Other.RLAmt != 0)
1595 else if (RLAmt != 0 &&
Other.RLAmt == 0)
1597 else if (FirstGroupStartIdx <
Other.FirstGroupStartIdx)
1603 using ValueBitsMemoizedValue = std::pair<bool, SmallVector<ValueBit, 64>>;
1604 using ValueBitsMemoizer =
1605 DenseMap<SDValue, std::unique_ptr<ValueBitsMemoizedValue>>;
1606 ValueBitsMemoizer Memoizer;
1612 std::pair<bool, SmallVector<ValueBit, 64> *> getValueBits(
SDValue V,
1614 auto &ValueEntry = Memoizer[
V];
1616 return std::make_pair(ValueEntry->first, &ValueEntry->second);
1617 ValueEntry.reset(
new ValueBitsMemoizedValue());
1618 bool &Interesting = ValueEntry->first;
1620 Bits.resize(NumBits);
1622 switch (
V.getOpcode()) {
1627 unsigned RotAmt =
V.getConstantOperandVal(1) & (NumBits - 1);
1629 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1631 for (
unsigned i = 0; i < NumBits; ++i)
1632 Bits[i] = LHSBits[i < RotAmt ? i + (NumBits - RotAmt) : i - RotAmt];
1634 return std::make_pair(Interesting =
true, &Bits);
1641 unsigned ShiftAmt =
V.getConstantOperandVal(1) & ((NumBits << 1) - 1);
1643 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1645 if (ShiftAmt >= NumBits) {
1646 for (
unsigned i = 0; i < NumBits; ++i)
1647 Bits[i] = ValueBit(ValueBit::ConstZero);
1649 for (
unsigned i = ShiftAmt; i < NumBits; ++i)
1650 Bits[i] = LHSBits[i - ShiftAmt];
1651 for (
unsigned i = 0; i < ShiftAmt; ++i)
1652 Bits[i] = ValueBit(ValueBit::ConstZero);
1655 return std::make_pair(Interesting =
true, &Bits);
1662 unsigned ShiftAmt =
V.getConstantOperandVal(1) & ((NumBits << 1) - 1);
1664 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1666 if (ShiftAmt >= NumBits) {
1667 for (
unsigned i = 0; i < NumBits; ++i)
1668 Bits[i] = ValueBit(ValueBit::ConstZero);
1670 for (
unsigned i = 0; i < NumBits - ShiftAmt; ++i)
1671 Bits[i] = LHSBits[i + ShiftAmt];
1672 for (
unsigned i = NumBits - ShiftAmt; i < NumBits; ++i)
1673 Bits[i] = ValueBit(ValueBit::ConstZero);
1676 return std::make_pair(Interesting =
true, &Bits);
1681 uint64_t
Mask =
V.getConstantOperandVal(1);
1688 std::tie(Interesting, LHSBits) = getValueBits(
V.getOperand(0), NumBits);
1690 for (
unsigned i = 0; i < NumBits; ++i)
1691 if (((Mask >> i) & 1) == 1)
1692 Bits[i] = (*LHSBits)[i];
1696 if ((*LHSBits)[i].
isZero())
1697 Bits[i] = (*LHSBits)[i];
1699 Bits[i] = ValueBit(ValueBit::ConstZero);
1702 return std::make_pair(Interesting, &Bits);
1706 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1707 const auto &RHSBits = *getValueBits(
V.getOperand(1), NumBits).second;
1709 bool AllDisjoint =
true;
1711 unsigned LastIdx = 0;
1712 for (
unsigned i = 0; i < NumBits; ++i) {
1720 if (LHSBits[i].hasValue() && LHSBits[i].getValue() == LastVal &&
1721 LHSBits[i].getValueBitIndex() == LastIdx + 1)
1722 Bits[i] = LHSBits[i];
1723 else if (RHSBits[i].hasValue() && RHSBits[i].getValue() == LastVal &&
1724 RHSBits[i].getValueBitIndex() == LastIdx + 1)
1725 Bits[i] = RHSBits[i];
1727 Bits[i] = ValueBit(ValueBit::ConstZero);
1729 else if (LHSBits[i].
isZero())
1730 Bits[i] = RHSBits[i];
1731 else if (RHSBits[i].
isZero())
1732 Bits[i] = LHSBits[i];
1734 AllDisjoint =
false;
1738 if (Bits[i].hasValue()) {
1739 LastVal =
Bits[i].getValue();
1740 LastIdx =
Bits[i].getValueBitIndex();
1743 if (LastVal) LastVal =
SDValue();
1751 return std::make_pair(Interesting =
true, &Bits);
1755 if (
V.getValueType() != MVT::i64 ||
1756 V.getOperand(0).getValueType() != MVT::i32)
1760 const unsigned NumOperandBits = 32;
1761 std::tie(Interesting, LHSBits) = getValueBits(
V.getOperand(0),
1764 for (
unsigned i = 0; i < NumOperandBits; ++i)
1765 Bits[i] = (*LHSBits)[i];
1767 for (
unsigned i = NumOperandBits; i < NumBits; ++i)
1768 Bits[i] = ValueBit(ValueBit::ConstZero);
1770 return std::make_pair(Interesting, &Bits);
1773 EVT
FromType =
V.getOperand(0).getValueType();
1774 EVT ToType =
V.getValueType();
1776 if (FromType != MVT::i64 || ToType != MVT::i32)
1778 const unsigned NumAllBits =
FromType.getSizeInBits();
1780 std::tie(Interesting, InBits) = getValueBits(
V.getOperand(0),
1786 bool UseUpper32bit =
false;
1787 for (
unsigned i = 0; i < NumValidBits; ++i)
1788 if ((*InBits)[i].hasValue() && (*InBits)[i].getValueBitIndex() >= 32) {
1789 UseUpper32bit =
true;
1795 for (
unsigned i = 0; i < NumValidBits; ++i)
1796 Bits[i] = (*InBits)[i];
1798 return std::make_pair(Interesting, &Bits);
1804 std::tie(Interesting, LHSBits) = getValueBits(
V.getOperand(0),
1808 const unsigned NumValidBits =
FromType.getSizeInBits();
1809 for (
unsigned i = 0; i < NumValidBits; ++i)
1810 Bits[i] = (*LHSBits)[i];
1814 for (
unsigned i = NumValidBits; i < NumBits; ++i)
1815 Bits[i] = (*LHSBits)[i].hasValue()
1816 ? ValueBit((*LHSBits)[i].getValue(),
1817 (*LHSBits)[i].getValueBitIndex(),
1818 ValueBit::VariableKnownToBeZero)
1819 : ValueBit(ValueBit::ConstZero);
1821 return std::make_pair(Interesting, &Bits);
1826 EVT VT =
LD->getMemoryVT();
1829 for (
unsigned i = 0; i < NumValidBits; ++i)
1830 Bits[i] = ValueBit(V, i);
1833 for (
unsigned i = NumValidBits; i < NumBits; ++i)
1834 Bits[i] = ValueBit(V, i, ValueBit::VariableKnownToBeZero);
1838 return std::make_pair(Interesting =
false, &Bits);
1843 for (
unsigned i = 0; i < NumBits; ++i)
1844 Bits[i] = ValueBit(V, i);
1846 return std::make_pair(Interesting =
false, &Bits);
1851 void computeRotationAmounts() {
1853 RLAmt.resize(
Bits.size());
1854 for (
unsigned i = 0; i <
Bits.size(); ++i)
1855 if (Bits[i].hasValue()) {
1856 unsigned VBI =
Bits[i].getValueBitIndex();
1860 RLAmt[i] =
Bits.size() - (VBI - i);
1861 }
else if (Bits[i].
isZero()) {
1863 RLAmt[i] = UINT32_MAX;
1872 void collectBitGroups(
bool LateMask) {
1875 unsigned LastRLAmt = RLAmt[0];
1877 unsigned LastGroupStartIdx = 0;
1878 bool IsGroupOfZeros = !
Bits[LastGroupStartIdx].hasValue();
1879 for (
unsigned i = 1; i <
Bits.size(); ++i) {
1880 unsigned ThisRLAmt = RLAmt[i];
1882 if (LateMask && !ThisValue) {
1883 ThisValue = LastValue;
1884 ThisRLAmt = LastRLAmt;
1887 if (BitGroups.empty())
1888 LastGroupStartIdx = 0;
1895 if (IsGroupOfZeros && Bits[i].
isZero())
1900 if (ThisRLAmt == LastRLAmt && ThisValue == LastValue)
1903 if (!(IsGroupOfZeros && ThisValue && !Bits[i].
isZero()))
1907 BitGroups.push_back(BitGroup(LastValue, LastRLAmt, LastGroupStartIdx,
1909 LastRLAmt = ThisRLAmt;
1910 LastValue = ThisValue;
1911 LastGroupStartIdx = i;
1912 IsGroupOfZeros = !
Bits[LastGroupStartIdx].hasValue();
1915 BitGroups.push_back(BitGroup(LastValue, LastRLAmt, LastGroupStartIdx,
1918 if (BitGroups.empty())
1922 if (BitGroups.size() > 1) {
1926 if (BitGroups[0].StartIdx == 0 &&
1927 BitGroups[BitGroups.size()-1].EndIdx ==
Bits.size()-1 &&
1928 BitGroups[0].V == BitGroups[BitGroups.size()-1].V &&
1929 BitGroups[0].RLAmt == BitGroups[BitGroups.size()-1].RLAmt) {
1930 LLVM_DEBUG(
dbgs() <<
"\tcombining final bit group with initial one\n");
1931 BitGroups[BitGroups.size()-1].EndIdx = BitGroups[0].EndIdx;
1932 BitGroups.erase(BitGroups.begin());
1942 void collectValueRotInfo() {
1945 for (
auto &BG : BitGroups) {
1946 unsigned RLAmtKey = BG.RLAmt + (BG.Repl32 ? 64 : 0);
1947 ValueRotInfo &VRI = ValueRots[std::make_pair(BG.V, RLAmtKey)];
1949 VRI.RLAmt = BG.RLAmt;
1950 VRI.Repl32 = BG.Repl32;
1952 VRI.FirstGroupStartIdx = std::min(VRI.FirstGroupStartIdx, BG.StartIdx);
1957 ValueRotsVec.clear();
1958 for (
auto &
I : ValueRots) {
1959 ValueRotsVec.push_back(
I.second);
1972 void assignRepl32BitGroups() {
1983 auto IsAllLow32 = [
this](BitGroup & BG) {
1984 if (BG.StartIdx <= BG.EndIdx) {
1985 for (
unsigned i = BG.StartIdx; i <= BG.EndIdx; ++i) {
1986 if (!Bits[i].hasValue())
1988 if (Bits[i].getValueBitIndex() >= 32)
1992 for (
unsigned i = BG.StartIdx; i <
Bits.size(); ++i) {
1993 if (!Bits[i].hasValue())
1995 if (Bits[i].getValueBitIndex() >= 32)
1998 for (
unsigned i = 0; i <= BG.EndIdx; ++i) {
1999 if (!Bits[i].hasValue())
2001 if (Bits[i].getValueBitIndex() >= 32)
2009 for (
auto &BG : BitGroups) {
2013 if (BG.RLAmt == 0) {
2014 auto PotentiallyMerged = [
this](BitGroup & BG) {
2015 for (
auto &BG2 : BitGroups)
2016 if (&BG != &BG2 && BG.V == BG2.V &&
2017 (BG2.RLAmt == 0 || BG2.RLAmt == 32))
2021 if (!PotentiallyMerged(BG))
2024 if (BG.StartIdx < 32 && BG.EndIdx < 32) {
2025 if (IsAllLow32(BG)) {
2026 if (BG.RLAmt >= 32) {
2034 << BG.V.getNode() <<
" RLAmt = " << BG.RLAmt <<
" ["
2035 << BG.StartIdx <<
", " << BG.EndIdx <<
"]\n");
2041 for (
auto I = BitGroups.begin();
I != BitGroups.end();) {
2044 auto IP = (
I == BitGroups.begin()) ?
2045 std::prev(BitGroups.end()) : std::prev(
I);
2046 if (
I->Repl32 && IP->Repl32 &&
I->V == IP->V &&
I->RLAmt == IP->RLAmt &&
2047 I->StartIdx == (IP->EndIdx + 1) % 64 &&
I != IP) {
2049 LLVM_DEBUG(dbgs() <<
"\tcombining 32-bit replicated bit group for "
2050 << I->V.getNode() <<
" RLAmt = " << I->RLAmt <<
" ["
2051 << I->StartIdx <<
", " << I->EndIdx
2052 <<
"] with group with range [" << IP->StartIdx <<
", "
2053 << IP->EndIdx <<
"]\n");
2055 IP->EndIdx = I->EndIdx;
2056 IP->Repl32CR = IP->Repl32CR || I->Repl32CR;
2057 IP->Repl32Coalesced = true;
2058 I = BitGroups.erase(I);
2067 if (I->StartIdx == 32 && I->EndIdx == 63) {
2068 assert(std::next(I) == BitGroups.end() &&
2069 "bit group ends at index 63 but there is another?");
2070 auto IN = BitGroups.begin();
2072 if (IP->Repl32 && IN->Repl32 && I->V == IP->V && I->V == IN->V &&
2073 (I->RLAmt % 32) == IP->RLAmt && (I->RLAmt % 32) == IN->RLAmt &&
2074 IP->EndIdx == 31 && IN->StartIdx == 0 && I != IP &&
2077 LLVM_DEBUG(dbgs() <<
"\tcombining bit group for " << I->V.getNode()
2078 <<
" RLAmt = " << I->RLAmt <<
" [" << I->StartIdx
2079 <<
", " << I->EndIdx
2080 <<
"] with 32-bit replicated groups with ranges ["
2081 << IP->StartIdx <<
", " << IP->EndIdx <<
"] and ["
2082 << IN->StartIdx <<
", " << IN->EndIdx <<
"]\n");
2090 IP->Repl32CR = IP->Repl32CR || I->RLAmt >= 32;
2091 IP->Repl32Coalesced = true;
2092 I = BitGroups.erase(I);
2097 IP->EndIdx = IN->EndIdx;
2098 IP->Repl32CR = IP->Repl32CR || IN->Repl32CR || I->RLAmt >= 32;
2099 IP->Repl32Coalesced = true;
2100 I = BitGroups.erase(I);
2101 BitGroups.erase(BitGroups.begin());
2115 SDValue getI32Imm(
unsigned Imm,
const SDLoc &dl) {
2116 return CurDAG->getTargetConstant(Imm, dl, MVT::i32);
2119 uint64_t getZerosMask() {
2121 for (
unsigned i = 0; i <
Bits.size(); ++i) {
2122 if (Bits[i].hasValue())
2124 Mask |= (UINT64_C(1) << i);
2135 if (
V.getValueSizeInBits() == 64)
2138 assert(
V.getValueSizeInBits() == 32);
2139 SDValue SubRegIdx = CurDAG->getTargetConstant(PPC::sub_32, dl, MVT::i32);
2140 SDValue ImDef =
SDValue(CurDAG->getMachineNode(PPC::IMPLICIT_DEF, dl,
2142 SDValue ExtVal =
SDValue(CurDAG->getMachineNode(PPC::INSERT_SUBREG, dl,
2149 if (
V.getValueSizeInBits() == 32)
2152 assert(
V.getValueSizeInBits() == 64);
2153 SDValue SubRegIdx = CurDAG->getTargetConstant(PPC::sub_32, dl, MVT::i32);
2154 SDValue SubVal =
SDValue(CurDAG->getMachineNode(PPC::EXTRACT_SUBREG, dl,
2155 MVT::i32, V, SubRegIdx), 0);
2162 void SelectAndParts32(
const SDLoc &dl,
SDValue &Res,
unsigned *InstCnt) {
2166 for (ValueRotInfo &VRI : ValueRotsVec) {
2168 for (
unsigned i = 0; i <
Bits.size(); ++i) {
2169 if (!Bits[i].hasValue() || Bits[i].getValue() != VRI.V)
2171 if (RLAmt[i] != VRI.RLAmt)
2177 unsigned ANDIMask = (
Mask & UINT16_MAX), ANDISMask = Mask >> 16;
2178 assert((ANDIMask != 0 || ANDISMask != 0) &&
2179 "No set bits in mask for value bit groups");
2180 bool NeedsRotate = VRI.RLAmt != 0;
2196 unsigned NumAndInsts = (unsigned) NeedsRotate +
2197 (
unsigned) (ANDIMask != 0) +
2198 (
unsigned) (ANDISMask != 0) +
2199 (
unsigned) (ANDIMask != 0 && ANDISMask != 0) +
2200 (
unsigned) (bool) Res;
2202 LLVM_DEBUG(
dbgs() <<
"\t\trotation groups for " << VRI.V.getNode()
2203 <<
" RL: " << VRI.RLAmt <<
":"
2204 <<
"\n\t\t\tisel using masking: " << NumAndInsts
2205 <<
" using rotates: " << VRI.NumGroups <<
"\n");
2207 if (NumAndInsts >= VRI.NumGroups)
2212 if (InstCnt) *InstCnt += NumAndInsts;
2217 { TruncateToInt32(VRI.V, dl), getI32Imm(VRI.RLAmt, dl),
2218 getI32Imm(0, dl), getI32Imm(31, dl) };
2219 VRot =
SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32,
2222 VRot = TruncateToInt32(VRI.V, dl);
2227 ANDIVal =
SDValue(CurDAG->getMachineNode(PPC::ANDI_rec, dl, MVT::i32,
2228 VRot, getI32Imm(ANDIMask, dl)),
2232 SDValue(CurDAG->getMachineNode(PPC::ANDIS_rec, dl, MVT::i32, VRot,
2233 getI32Imm(ANDISMask, dl)),
2238 TotalVal = ANDISVal;
2242 TotalVal =
SDValue(CurDAG->getMachineNode(PPC::OR, dl, MVT::i32,
2243 ANDIVal, ANDISVal), 0);
2248 Res =
SDValue(CurDAG->getMachineNode(PPC::OR, dl, MVT::i32,
2253 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
2254 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt;
2260 SDNode *Select32(SDNode *
N,
bool LateMask,
unsigned *InstCnt) {
2264 if (InstCnt) *InstCnt = 0;
2267 SelectAndParts32(dl, Res, InstCnt);
2272 if ((!NeedMask || LateMask) && !Res) {
2273 ValueRotInfo &VRI = ValueRotsVec[0];
2275 if (InstCnt) *InstCnt += 1;
2277 { TruncateToInt32(VRI.V, dl), getI32Imm(VRI.RLAmt, dl),
2278 getI32Imm(0, dl), getI32Imm(31, dl) };
2279 Res =
SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32,
Ops),
2282 Res = TruncateToInt32(VRI.V, dl);
2286 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
2287 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt;
2291 if (InstCnt) *InstCnt += BitGroups.size();
2294 for (
auto &BG : BitGroups) {
2297 { TruncateToInt32(BG.V, dl), getI32Imm(BG.RLAmt, dl),
2298 getI32Imm(
Bits.size() - BG.EndIdx - 1, dl),
2299 getI32Imm(
Bits.size() - BG.StartIdx - 1, dl) };
2300 Res =
SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32,
Ops), 0);
2303 { Res, TruncateToInt32(BG.V, dl), getI32Imm(BG.RLAmt, dl),
2304 getI32Imm(
Bits.size() - BG.EndIdx - 1, dl),
2305 getI32Imm(
Bits.size() - BG.StartIdx - 1, dl) };
2306 Res =
SDValue(CurDAG->getMachineNode(PPC::RLWIMI, dl, MVT::i32,
Ops), 0);
2311 unsigned Mask = (unsigned) getZerosMask();
2313 unsigned ANDIMask = (
Mask & UINT16_MAX), ANDISMask = Mask >> 16;
2314 assert((ANDIMask != 0 || ANDISMask != 0) &&
2315 "No set bits in zeros mask?");
2317 if (InstCnt) *InstCnt += (unsigned) (ANDIMask != 0) +
2318 (unsigned) (ANDISMask != 0) +
2319 (unsigned) (ANDIMask != 0 && ANDISMask != 0);
2323 ANDIVal =
SDValue(CurDAG->getMachineNode(PPC::ANDI_rec, dl, MVT::i32,
2324 Res, getI32Imm(ANDIMask, dl)),
2328 SDValue(CurDAG->getMachineNode(PPC::ANDIS_rec, dl, MVT::i32, Res,
2329 getI32Imm(ANDISMask, dl)),
2337 Res =
SDValue(CurDAG->getMachineNode(PPC::OR, dl, MVT::i32,
2338 ANDIVal, ANDISVal), 0);
2344 unsigned SelectRotMask64Count(
unsigned RLAmt,
bool Repl32,
2345 unsigned MaskStart,
unsigned MaskEnd,
2349 unsigned InstMaskStart = 64 - MaskEnd - 1,
2350 InstMaskEnd = 64 - MaskStart - 1;
2355 if ((!IsIns && (InstMaskEnd == 63 || InstMaskStart == 0)) ||
2356 InstMaskEnd == 63 - RLAmt)
2364 SDValue SelectRotMask64(
SDValue V,
const SDLoc &dl,
unsigned RLAmt,
2365 bool Repl32,
unsigned MaskStart,
unsigned MaskEnd,
2366 unsigned *InstCnt =
nullptr) {
2369 unsigned InstMaskStart = 64 - MaskEnd - 1,
2370 InstMaskEnd = 64 - MaskStart - 1;
2372 if (InstCnt) *InstCnt += 1;
2378 assert(InstMaskStart >= 32 &&
"Mask cannot start out of range");
2379 assert(InstMaskEnd >= 32 &&
"Mask cannot end out of range");
2381 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2382 getI32Imm(InstMaskStart - 32, dl), getI32Imm(InstMaskEnd - 32, dl) };
2383 return SDValue(CurDAG->getMachineNode(PPC::RLWINM8, dl, MVT::i64,
2387 if (InstMaskEnd == 63) {
2389 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2390 getI32Imm(InstMaskStart, dl) };
2391 return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64,
Ops), 0);
2394 if (InstMaskStart == 0) {
2396 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2397 getI32Imm(InstMaskEnd, dl) };
2398 return SDValue(CurDAG->getMachineNode(PPC::RLDICR, dl, MVT::i64,
Ops), 0);
2401 if (InstMaskEnd == 63 - RLAmt) {
2403 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2404 getI32Imm(InstMaskStart, dl) };
2405 return SDValue(CurDAG->getMachineNode(PPC::RLDIC, dl, MVT::i64,
Ops), 0);
2414 if (InstCnt) *InstCnt += 1;
2417 unsigned RLAmt2 = MaskStart;
2420 unsigned RLAmt1 = (64 + RLAmt - RLAmt2) % 64;
2422 V = SelectRotMask64(V, dl, RLAmt1,
false, 0, 63);
2423 return SelectRotMask64(V, dl, RLAmt2,
false, MaskStart, MaskEnd);
2429 unsigned RLAmt,
bool Repl32,
unsigned MaskStart,
2430 unsigned MaskEnd,
unsigned *InstCnt =
nullptr) {
2433 unsigned InstMaskStart = 64 - MaskEnd - 1,
2434 InstMaskEnd = 64 - MaskStart - 1;
2436 if (InstCnt) *InstCnt += 1;
2442 assert(InstMaskStart >= 32 &&
"Mask cannot start out of range");
2443 assert(InstMaskEnd >= 32 &&
"Mask cannot end out of range");
2445 { ExtendToInt64(
Base, dl), ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2446 getI32Imm(InstMaskStart - 32, dl), getI32Imm(InstMaskEnd - 32, dl) };
2447 return SDValue(CurDAG->getMachineNode(PPC::RLWIMI8, dl, MVT::i64,
2451 if (InstMaskEnd == 63 - RLAmt) {
2453 { ExtendToInt64(
Base, dl), ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2454 getI32Imm(InstMaskStart, dl) };
2455 return SDValue(CurDAG->getMachineNode(PPC::RLDIMI, dl, MVT::i64,
Ops), 0);
2464 if (InstCnt) *InstCnt += 1;
2467 unsigned RLAmt2 = MaskStart;
2470 unsigned RLAmt1 = (64 + RLAmt - RLAmt2) % 64;
2472 V = SelectRotMask64(V, dl, RLAmt1,
false, 0, 63);
2473 return SelectRotMaskIns64(
Base, V, dl, RLAmt2,
false, MaskStart, MaskEnd);
2476 void SelectAndParts64(
const SDLoc &dl,
SDValue &Res,
unsigned *InstCnt) {
2489 for (ValueRotInfo &VRI : ValueRotsVec) {
2497 auto MatchingBG = [VRI](
const BitGroup &BG) {
2501 unsigned EffRLAmt = BG.RLAmt;
2502 if (!VRI.Repl32 && BG.Repl32) {
2503 if (BG.StartIdx < 32 && BG.EndIdx < 32 && BG.StartIdx <= BG.EndIdx &&
2504 !BG.Repl32Coalesced) {
2510 }
else if (VRI.Repl32 != BG.Repl32) {
2514 return VRI.RLAmt == EffRLAmt;
2517 for (
auto &BG : BitGroups) {
2518 if (!MatchingBG(BG))
2521 if (BG.StartIdx <= BG.EndIdx) {
2522 for (
unsigned i = BG.StartIdx; i <= BG.EndIdx; ++i)
2523 Mask |= (UINT64_C(1) << i);
2525 for (
unsigned i = BG.StartIdx; i <
Bits.size(); ++i)
2526 Mask |= (UINT64_C(1) << i);
2527 for (
unsigned i = 0; i <= BG.EndIdx; ++i)
2528 Mask |= (UINT64_C(1) << i);
2537 unsigned ANDIMask = (
Mask & UINT16_MAX),
2538 ANDISMask = (Mask >> 16) & UINT16_MAX;
2540 bool NeedsRotate = VRI.RLAmt || (VRI.Repl32 && !
isUInt<32>(Mask));
2542 unsigned NumAndInsts = (unsigned) NeedsRotate +
2543 (
unsigned) (bool) Res;
2544 unsigned NumOfSelectInsts = 0;
2546 assert(NumOfSelectInsts > 0 &&
"Failed to select an i64 constant.");
2548 NumAndInsts += (unsigned) (ANDIMask != 0) + (unsigned) (ANDISMask != 0) +
2549 (unsigned) (ANDIMask != 0 && ANDISMask != 0);
2551 NumAndInsts += NumOfSelectInsts + 1;
2553 unsigned NumRLInsts = 0;
2554 bool FirstBG =
true;
2555 bool MoreBG =
false;
2556 for (
auto &BG : BitGroups) {
2557 if (!MatchingBG(BG)) {
2562 SelectRotMask64Count(BG.RLAmt, BG.Repl32, BG.StartIdx, BG.EndIdx,
2567 LLVM_DEBUG(
dbgs() <<
"\t\trotation groups for " << VRI.V.getNode()
2568 <<
" RL: " << VRI.RLAmt << (VRI.Repl32 ?
" (32):" :
":")
2569 <<
"\n\t\t\tisel using masking: " << NumAndInsts
2570 <<
" using rotates: " << NumRLInsts <<
"\n");
2576 if (NumAndInsts > NumRLInsts)
2581 if ((Use32BitInsts || MoreBG) && NumAndInsts == NumRLInsts)
2586 if (InstCnt) *InstCnt += NumAndInsts;
2593 if (VRI.RLAmt || (VRI.Repl32 && !
isUInt<32>(Mask)))
2594 VRot = SelectRotMask64(VRI.V, dl, VRI.RLAmt, VRI.Repl32,
2595 VRI.Repl32 ? 31 : 0, VRI.Repl32 ? 30 : 63);
2600 if (Use32BitInsts) {
2601 assert((ANDIMask != 0 || ANDISMask != 0) &&
2602 "No set bits in mask when using 32-bit ands for 64-bit value");
2606 ANDIVal =
SDValue(CurDAG->getMachineNode(PPC::ANDI8_rec, dl, MVT::i64,
2607 ExtendToInt64(VRot, dl),
2608 getI32Imm(ANDIMask, dl)),
2612 SDValue(CurDAG->getMachineNode(PPC::ANDIS8_rec, dl, MVT::i64,
2613 ExtendToInt64(VRot, dl),
2614 getI32Imm(ANDISMask, dl)),
2618 TotalVal = ANDISVal;
2622 TotalVal =
SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64,
2623 ExtendToInt64(ANDIVal, dl), ANDISVal), 0);
2627 SDValue(CurDAG->getMachineNode(PPC::AND8, dl, MVT::i64,
2628 ExtendToInt64(VRot, dl), TotalVal),
2635 Res =
SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64,
2636 ExtendToInt64(Res, dl), TotalVal),
2641 eraseMatchingBitGroups(MatchingBG);
2646 SDNode *Select64(SDNode *
N,
bool LateMask,
unsigned *InstCnt) {
2650 if (InstCnt) *InstCnt = 0;
2653 SelectAndParts64(dl, Res, InstCnt);
2658 if ((!NeedMask || LateMask) && !Res) {
2662 unsigned MaxGroupsIdx = 0;
2663 if (!ValueRotsVec[0].Repl32) {
2664 for (
unsigned i = 0, ie = ValueRotsVec.size(); i < ie; ++i)
2665 if (ValueRotsVec[i].Repl32) {
2666 if (ValueRotsVec[i].NumGroups > ValueRotsVec[0].NumGroups)
2672 ValueRotInfo &VRI = ValueRotsVec[MaxGroupsIdx];
2673 bool NeedsRotate =
false;
2676 }
else if (VRI.Repl32) {
2677 for (
auto &BG : BitGroups) {
2678 if (BG.V != VRI.V || BG.RLAmt != VRI.RLAmt ||
2679 BG.Repl32 != VRI.Repl32)
2684 if (BG.StartIdx < 32 && BG.EndIdx < 32 && BG.StartIdx < BG.EndIdx)
2693 Res = SelectRotMask64(VRI.V, dl, VRI.RLAmt, VRI.Repl32,
2694 VRI.Repl32 ? 31 : 0, VRI.Repl32 ? 30 : 63,
2701 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
2702 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt &&
2703 BG.Repl32 == VRI.Repl32;
2710 for (
auto I = BitGroups.begin(), IE = BitGroups.end();
I != IE; ++
I) {
2711 if (SelectRotMask64Count(
I->RLAmt,
I->Repl32,
I->StartIdx,
I->EndIdx,
2713 SelectRotMask64Count(
I->RLAmt,
I->Repl32,
I->StartIdx,
I->EndIdx,
2715 if (
I != BitGroups.begin()) {
2718 BitGroups.insert(BitGroups.begin(), BG);
2726 for (
auto &BG : BitGroups) {
2728 Res = SelectRotMask64(BG.V, dl, BG.RLAmt, BG.Repl32, BG.StartIdx,
2729 BG.EndIdx, InstCnt);
2731 Res = SelectRotMaskIns64(Res, BG.V, dl, BG.RLAmt, BG.Repl32,
2732 BG.StartIdx, BG.EndIdx, InstCnt);
2736 uint64_t
Mask = getZerosMask();
2743 unsigned ANDIMask = (
Mask & UINT16_MAX),
2744 ANDISMask = (Mask >> 16) & UINT16_MAX;
2746 if (Use32BitInsts) {
2747 assert((ANDIMask != 0 || ANDISMask != 0) &&
2748 "No set bits in mask when using 32-bit ands for 64-bit value");
2750 if (InstCnt) *InstCnt += (unsigned) (ANDIMask != 0) +
2751 (unsigned) (ANDISMask != 0) +
2752 (unsigned) (ANDIMask != 0 && ANDISMask != 0);
2756 ANDIVal =
SDValue(CurDAG->getMachineNode(PPC::ANDI8_rec, dl, MVT::i64,
2757 ExtendToInt64(Res, dl),
2758 getI32Imm(ANDIMask, dl)),
2762 SDValue(CurDAG->getMachineNode(PPC::ANDIS8_rec, dl, MVT::i64,
2763 ExtendToInt64(Res, dl),
2764 getI32Imm(ANDISMask, dl)),
2772 Res =
SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64,
2773 ExtendToInt64(ANDIVal, dl), ANDISVal), 0);
2775 unsigned NumOfSelectInsts = 0;
2778 Res =
SDValue(CurDAG->getMachineNode(PPC::AND8, dl, MVT::i64,
2779 ExtendToInt64(Res, dl), MaskVal),
2782 *InstCnt += NumOfSelectInsts + 1;
2789 SDNode *
Select(SDNode *
N,
bool LateMask,
unsigned *InstCnt =
nullptr) {
2791 collectBitGroups(LateMask);
2792 if (BitGroups.empty())
2796 if (
Bits.size() == 64)
2797 assignRepl32BitGroups();
2800 collectValueRotInfo();
2802 if (
Bits.size() == 32) {
2803 return Select32(
N, LateMask, InstCnt);
2805 assert(
Bits.size() == 64 &&
"Not 64 bits here?");
2806 return Select64(
N, LateMask, InstCnt);
2812 void eraseMatchingBitGroups(function_ref<
bool(
const BitGroup &)>
F) {
2818 bool NeedMask =
false;
2823 DenseMap<std::pair<SDValue, unsigned>, ValueRotInfo> ValueRots;
2826 SelectionDAG *CurDAG =
nullptr;
2829 BitPermutationSelector(SelectionDAG *DAG)
2838 getValueBits(
SDValue(
N, 0),
N->getValueType(0).getSizeInBits());
2843 LLVM_DEBUG(
dbgs() <<
"Considering bit-permutation-based instruction"
2844 " selection for: ");
2848 computeRotationAmounts();
2861 unsigned InstCnt = 0, InstCntLateMask = 0;
2863 SDNode *
RN =
Select(
N,
false, &InstCnt);
2864 LLVM_DEBUG(
dbgs() <<
"\t\tisel would use " << InstCnt <<
" instructions\n");
2867 SDNode *RNLM =
Select(
N,
true, &InstCntLateMask);
2869 <<
" instructions\n");
2871 if (InstCnt <= InstCntLateMask) {
2881class IntegerCompareEliminator {
2882 SelectionDAG *CurDAG;
2886 enum ExtOrTruncConversion { Ext, Trunc };
2894 enum SetccInGPROpts { ZExtOrig, ZExtInvert, SExtOrig, SExtInvert };
2904 enum ZeroCompare { GEZExt, GESExt, LEZExt, LESExt };
2906 SDNode *tryEXTEND(SDNode *
N);
2907 SDNode *tryLogicOpOfCompares(SDNode *
N);
2911 SDValue addExtOrTrunc(
SDValue NatWidthRes, ExtOrTruncConversion Conv);
2915 int64_t RHSValue, SDLoc dl);
2917 int64_t RHSValue, SDLoc dl);
2919 int64_t RHSValue, SDLoc dl);
2921 int64_t RHSValue, SDLoc dl);
2925 IntegerCompareEliminator(SelectionDAG *DAG,
2926 PPCDAGToDAGISel *Sel) : CurDAG(DAG), S(Sel) {
2929 "Only expecting to use this on 64 bit targets.");
2934 switch (
N->getOpcode()) {
2945 return tryEXTEND(
N);
2949 return tryLogicOpOfCompares(
N);
2957SDNode *IntegerCompareEliminator::tryEXTEND(SDNode *
N) {
2960 "Expecting a zero/sign extend node!");
2965 N->getOperand(0).getValueType() == MVT::i1 &&
2967 WideRes = computeLogicOpInGPR(
N->getOperand(0));
2968 else if (
N->getOperand(0).getOpcode() !=
ISD::SETCC)
2972 getSETCCInGPR(
N->getOperand(0),
2974 SetccInGPROpts::SExtOrig : SetccInGPROpts::ZExtOrig);
2980 bool Output32Bit =
N->getValueType(0) == MVT::i32;
2986 if (Input32Bit != Output32Bit)
2987 ConvOp = addExtOrTrunc(WideRes, Input32Bit ? ExtOrTruncConversion::Ext :
2988 ExtOrTruncConversion::Trunc);
2996SDNode *IntegerCompareEliminator::tryLogicOpOfCompares(SDNode *
N) {
2997 if (
N->getValueType(0) != MVT::i1)
3000 "Expected a logic operation on setcc results.");
3002 if (!LoweredLogical)
3007 unsigned SubRegToExtract = IsBitwiseNegate ? PPC::sub_eq : PPC::sub_gt;
3016 if (IsBitwiseNegate &&
3019 else if (IsBitwiseNegate)
3021 OpToConvToRecForm = LoweredLogical.
getOperand(0);
3025 OpToConvToRecForm = LoweredLogical;
3035 if (NewOpc != -1 && IsBitwiseNegate) {
3038 "Expected a PPC::XORI8 only for bitwise negation.");
3040 std::vector<SDValue>
Ops;
3041 for (
int i = 0, e = OpToConvToRecForm.
getNumOperands(); i < e; i++)
3047 MVT::Glue,
Ops), 0);
3049 assert((NewOpc != -1 || !IsBitwiseNegate) &&
3050 "No record form available for AND8/OR8/XOR8?");
3053 dl, MVT::i64, MVT::Glue,
LHS,
RHS),
3065 MVT::i1, CR0Reg, SRIdxVal,
3078SDValue IntegerCompareEliminator::computeLogicOpInGPR(
SDValue LogicOp) {
3080 "Can only handle logic operations here.");
3082 "Can only handle logic operations on i1 values here.");
3094 unsigned OperandOpcode = Operand.getOpcode();
3096 return getSETCCInGPR(Operand, SetccInGPROpts::ZExtOrig);
3098 SDValue InputOp = Operand.getOperand(0);
3101 PPC::RLDICL, dl, InVT, InputOp,
3102 S->getI64Imm(0, dl),
3103 S->getI64Imm(63, dl)), 0);
3105 return computeLogicOpInGPR(Operand);
3114 if (!
LHS || (!
RHS && !IsBitwiseNegation))
3117 NumLogicOpsOnComparison++;
3120 if (
LHS.getValueType() == MVT::i32)
3121 LHS = addExtOrTrunc(
LHS, ExtOrTruncConversion::Ext);
3122 if (!IsBitwiseNegation &&
RHS.getValueType() == MVT::i32)
3123 RHS = addExtOrTrunc(
RHS, ExtOrTruncConversion::Ext);
3128 case ISD::AND: NewOpc = PPC::AND8;
break;
3129 case ISD::OR: NewOpc = PPC::OR8;
break;
3130 case ISD::XOR: NewOpc = PPC::XOR8;
break;
3133 if (IsBitwiseNegation) {
3134 RHS = S->getI64Imm(1, dl);
3135 NewOpc = PPC::XORI8;
3146SDValue IntegerCompareEliminator::signExtendInputIfNeeded(
SDValue Input) {
3148 "Can only sign-extend 32-bit values here.");
3156 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3162 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3167 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3170 SignExtensionsAdded++;
3172 MVT::i64, Input), 0);
3179SDValue IntegerCompareEliminator::zeroExtendInputIfNeeded(
SDValue Input) {
3181 "Can only zero-extend 32-bit values here.");
3191 if (IsTruncateOfZExt)
3192 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3196 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3201 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3205 ZeroExtensionsAdded++;
3207 S->getI64Imm(0, dl),
3208 S->getI64Imm(32, dl)), 0);
3215SDValue IntegerCompareEliminator::addExtOrTrunc(
SDValue NatWidthRes,
3216 ExtOrTruncConversion Conv) {
3217 SDLoc dl(NatWidthRes);
3221 if (Conv == ExtOrTruncConversion::Ext) {
3226 ImDef, NatWidthRes, SubRegIdx), 0);
3229 assert(Conv == ExtOrTruncConversion::Trunc &&
3230 "Unknown convertion between 32 and 64 bit values.");
3236 NatWidthRes, SubRegIdx), 0);
3242IntegerCompareEliminator::getCompoundZeroComparisonInGPR(
SDValue LHS, SDLoc dl,
3243 ZeroCompare CmpTy) {
3244 EVT InVT =
LHS.getValueType();
3245 bool Is32Bit = InVT == MVT::i32;
3250 case ZeroCompare::GEZExt:
3251 case ZeroCompare::GESExt:
3255 case ZeroCompare::LEZExt:
3256 case ZeroCompare::LESExt: {
3259 LHS = signExtendInputIfNeeded(
LHS);
3264 Neg, S->getI64Imm(1, dl),
3265 S->getI64Imm(63, dl)), 0);
3269 S->getI64Imm(~0ULL, dl)), 0);
3279 (CmpTy == ZeroCompare::GEZExt || CmpTy == ZeroCompare::LEZExt))
3281 ToExtend, S->getI64Imm(1, dl),
3282 S->getI64Imm(63, dl)), 0);
3284 (CmpTy == ZeroCompare::GESExt || CmpTy == ZeroCompare::LESExt))
3286 S->getI64Imm(63, dl)), 0);
3288 assert(Is32Bit &&
"Should have handled the 32-bit sequences above.");
3291 case ZeroCompare::GEZExt: {
3292 SDValue ShiftOps[] = { ToExtend, S->getI32Imm(1, dl), S->getI32Imm(31, dl),
3293 S->getI32Imm(31, dl) };
3297 case ZeroCompare::GESExt:
3299 S->getI32Imm(31, dl)), 0);
3300 case ZeroCompare::LEZExt:
3302 S->getI32Imm(1, dl)), 0);
3303 case ZeroCompare::LESExt:
3305 S->getI32Imm(-1, dl)), 0);
3318 int64_t RHSValue, SDLoc dl) {
3322 bool IsRHSZero = RHSValue == 0;
3323 bool IsRHSOne = RHSValue == 1;
3324 bool IsRHSNegOne = RHSValue == -1LL;
3334 SDValue ShiftOps[] = { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl),
3335 S->getI32Imm(31, dl) };
3346 SDValue ShiftOps[] = { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl),
3347 S->getI32Imm(31, dl) };
3351 S->getI32Imm(1, dl)), 0);
3357 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GEZExt);
3363 IsRHSZero = RHSConst && RHSConst->
isZero();
3374 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LEZExt);
3378 LHS = signExtendInputIfNeeded(
LHS);
3379 RHS = signExtendInputIfNeeded(
RHS);
3384 S->getI64Imm(1, dl), S->getI64Imm(63, dl)),
3388 MVT::i64, Shift, S->getI32Imm(1, dl)), 0);
3396 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GEZExt);
3402 LHS = signExtendInputIfNeeded(
LHS);
3403 RHS = signExtendInputIfNeeded(
RHS);
3407 Neg, S->getI32Imm(1, dl), S->getI32Imm(63, dl)), 0);
3413 IsRHSZero = RHSConst && RHSConst->
isZero();
3425 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LEZExt);
3429 SDValue ShiftOps[] = {
LHS, S->getI32Imm(1, dl), S->getI32Imm(31, dl),
3430 S->getI32Imm(31, dl) };
3438 LHS = signExtendInputIfNeeded(
LHS);
3439 RHS = signExtendInputIfNeeded(
RHS);
3443 SUBFNode, S->getI64Imm(1, dl),
3444 S->getI64Imm(63, dl)), 0);
3455 LHS = zeroExtendInputIfNeeded(
LHS);
3456 RHS = zeroExtendInputIfNeeded(
RHS);
3461 Subtract, S->getI64Imm(1, dl),
3462 S->getI64Imm(63, dl)), 0);
3464 S->getI32Imm(1, dl)), 0);
3475 LHS = zeroExtendInputIfNeeded(
LHS);
3476 RHS = zeroExtendInputIfNeeded(
RHS);
3480 Subtract, S->getI64Imm(1, dl),
3481 S->getI64Imm(63, dl)), 0);
3491 int64_t RHSValue, SDLoc dl) {
3495 bool IsRHSZero = RHSValue == 0;
3496 bool IsRHSOne = RHSValue == 1;
3497 bool IsRHSNegOne = RHSValue == -1LL;
3510 SDValue SHLOps[] = { Cntlzw, S->getI32Imm(27, dl),
3511 S->getI32Imm(5, dl), S->getI32Imm(31, dl) };
3529 { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl), S->getI32Imm(31, dl) };
3534 S->getI32Imm(1, dl)), 0);
3541 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GESExt);
3547 IsRHSZero = RHSConst && RHSConst->
isZero();
3556 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LESExt);
3559 LHS = signExtendInputIfNeeded(
LHS);
3560 RHS = signExtendInputIfNeeded(
RHS);
3566 SUBFNode, S->getI64Imm(1, dl),
3567 S->getI64Imm(63, dl)), 0);
3569 S->getI32Imm(-1, dl)), 0);
3576 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GESExt);
3581 LHS = signExtendInputIfNeeded(
LHS);
3582 RHS = signExtendInputIfNeeded(
RHS);
3586 S->getI64Imm(63, dl)), 0);
3592 IsRHSZero = RHSConst && RHSConst->
isZero();
3603 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LESExt);
3607 S->getI32Imm(31, dl)), 0);
3612 LHS = signExtendInputIfNeeded(
LHS);
3613 RHS = signExtendInputIfNeeded(
RHS);
3617 SUBFNode, S->getI64Imm(63, dl)), 0);
3628 LHS = zeroExtendInputIfNeeded(
LHS);
3629 RHS = zeroExtendInputIfNeeded(
RHS);
3634 S->getI32Imm(1, dl), S->getI32Imm(63,dl)),
3637 S->getI32Imm(-1, dl)), 0);
3648 LHS = zeroExtendInputIfNeeded(
LHS);
3649 RHS = zeroExtendInputIfNeeded(
RHS);
3653 Subtract, S->getI64Imm(63, dl)), 0);
3663 int64_t RHSValue, SDLoc dl) {
3667 bool IsRHSZero = RHSValue == 0;
3668 bool IsRHSOne = RHSValue == 1;
3669 bool IsRHSNegOne = RHSValue == -1LL;
3680 S->getI64Imm(58, dl),
3681 S->getI64Imm(63, dl)), 0);
3692 Xor, S->getI32Imm(~0U, dl)), 0);
3702 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GEZExt);
3705 IsRHSZero = RHSConst && RHSConst->
isZero();
3714 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LEZExt);
3717 S->getI64Imm(1, dl),
3718 S->getI64Imm(63, dl)), 0);
3721 S->getI64Imm(63, dl)), 0);
3726 ShiftR, ShiftL, SubtractCarry), 0);
3734 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GEZExt);
3738 S->getI64Imm(~0ULL, dl)), 0);
3742 S->getI64Imm(1, dl),
3743 S->getI64Imm(63, dl)), 0);
3747 IsRHSZero = RHSConst && RHSConst->
isZero();
3757 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LEZExt);
3760 S->getI64Imm(1, dl),
3761 S->getI64Imm(63, dl)), 0);
3764 LHS, S->getI64Imm(63, dl)), 0);
3767 RHS, S->getI64Imm(1, dl),
3768 S->getI64Imm(63, dl)), 0);
3774 SRDINode, SRADINode, SUBFC8Carry), 0);
3776 ADDE8Node, S->getI64Imm(1, dl)), 0);
3791 LHS,
LHS, SUBFC8Carry), 0);
3793 SUBFE8Node, S->getI64Imm(1, dl)), 0);
3808 LHS,
LHS, SubtractCarry), 0);
3820 int64_t RHSValue, SDLoc dl) {
3824 bool IsRHSZero = RHSValue == 0;
3825 bool IsRHSOne = RHSValue == 1;
3826 bool IsRHSNegOne = RHSValue == -1LL;
3838 AddInput, S->getI32Imm(~0U, dl)), 0);
3851 Xor, S->getI32Imm(0, dl)), 0);
3861 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GESExt);
3864 IsRHSZero = RHSConst && RHSConst->
isZero();
3873 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LESExt);
3876 S->getI64Imm(63, dl)), 0);
3879 S->getI64Imm(1, dl),
3880 S->getI64Imm(63, dl)), 0);
3886 ShiftR, ShiftL, SubtractCarry), 0);
3895 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GESExt);
3899 S->getI64Imm(-1, dl)), 0);
3903 S->getI64Imm(63, dl)), 0);
3907 IsRHSZero = RHSConst && RHSConst->
isZero();
3917 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LESExt);
3920 S->getI64Imm(63, dl)), 0);
3924 LHS, S->getI64Imm(63, dl)), 0);
3927 RHS, S->getI64Imm(1, dl),
3928 S->getI64Imm(63, dl)), 0);
3934 SRDINode, SRADINode, SUBFC8Carry), 0);
3937 ADDE8Node, S->getI64Imm(1, dl)), 0);
3954 LHS, SubtractCarry), 0);
3956 ExtSub, ExtSub), 0);
3979static bool allUsesExtend(
SDValue Compare, SelectionDAG *CurDAG) {
3981 "An ISD::SETCC node required here.");
3989 for (
auto *CompareUse :
Compare.getNode()->users())
3994 OmittedForNonExtendUses++;
4004 SetccInGPROpts ConvOpts) {
4007 "An ISD::SETCC node required here.");
4021 EVT InputVT =
LHS.getValueType();
4022 if (InputVT != MVT::i32 && InputVT != MVT::i64)
4025 if (ConvOpts == SetccInGPROpts::ZExtInvert ||
4026 ConvOpts == SetccInGPROpts::SExtInvert)
4029 bool Inputs32Bit = InputVT == MVT::i32;
4034 bool IsSext = ConvOpts == SetccInGPROpts::SExtOrig ||
4035 ConvOpts == SetccInGPROpts::SExtInvert;
4037 if (IsSext && Inputs32Bit)
4038 return get32BitSExtCompare(
LHS,
RHS, CC, RHSValue, dl);
4039 else if (Inputs32Bit)
4040 return get32BitZExtCompare(
LHS,
RHS, CC, RHSValue, dl);
4042 return get64BitSExtCompare(
LHS,
RHS, CC, RHSValue, dl);
4043 return get64BitZExtCompare(
LHS,
RHS, CC, RHSValue, dl);
4048bool PPCDAGToDAGISel::tryIntCompareInGPR(SDNode *
N) {
4049 if (
N->getValueType(0) != MVT::i32 &&
4050 N->getValueType(0) != MVT::i64)
4062 if (!(
CmpInGPR.getNumOccurrences() > 0) && Subtarget->isISA3_1())
4065 switch (
N->getOpcode()) {
4072 IntegerCompareEliminator ICmpElim(CurDAG,
this);
4073 if (SDNode *New = ICmpElim.Select(
N)) {
4074 ReplaceNode(
N, New);
4082bool PPCDAGToDAGISel::tryBitPermutation(SDNode *
N) {
4083 if (
N->getValueType(0) != MVT::i32 &&
4084 N->getValueType(0) != MVT::i64)
4090 switch (
N->getOpcode()) {
4095 if (Subtarget->isISA3_1() &&
N->getValueType(0) == MVT::i32 &&
4097 auto &OpRight =
N->getOperand(1);
4107 BitPermutationSelector BPS(CurDAG);
4108 if (SDNode *New = BPS.Select(
N)) {
4109 ReplaceNode(
N, New);
4122 const SDLoc &dl,
SDValue Chain) {
4126 if (
LHS.getValueType() == MVT::i32) {
4133 getI32Imm(Imm & 0xFFFF, dl)),
4138 getI32Imm(Imm & 0xFFFF, dl)),
4151 getI32Imm(Imm >> 16, dl)), 0);
4153 getI32Imm(Imm & 0xFFFF, dl)), 0);
4159 getI32Imm(Imm & 0xFFFF, dl)), 0);
4165 getI32Imm((
int)SImm & 0xFFFF,
4170 }
else if (
LHS.getValueType() == MVT::i64) {
4177 getI32Imm(Imm & 0xFFFF, dl)),
4182 getI32Imm(Imm & 0xFFFF, dl)),
4196 getI64Imm(Imm >> 16, dl)), 0);
4198 getI64Imm(Imm & 0xFFFF, dl)),
4206 getI64Imm(Imm & 0xFFFF, dl)), 0);
4212 getI64Imm(SImm & 0xFFFF, dl)),
4216 }
else if (
LHS.getValueType() == MVT::f32) {
4217 if (Subtarget->hasSPE()) {
4222 Opc = PPC::EFSCMPEQ;
4230 Opc = PPC::EFSCMPLT;
4238 Opc = PPC::EFSCMPGT;
4243 }
else if (
LHS.getValueType() == MVT::f64) {
4244 if (Subtarget->hasSPE()) {
4249 Opc = PPC::EFDCMPEQ;
4257 Opc = PPC::EFDCMPLT;
4265 Opc = PPC::EFDCMPGT;
4269 Opc = Subtarget->hasVSX() ? PPC::XSCMPUDP : PPC::FCMPUD;
4271 assert(
LHS.getValueType() == MVT::f128 &&
"Unknown vt!");
4272 assert(Subtarget->hasP9Vector() &&
"XSCMPUQP requires Power9 Vector");
4273 Opc = PPC::XSCMPUQP;
4341 case ISD::SETO: Invert =
true;
return 3;
4358 bool HasVSX,
bool &Swap,
bool &Negate) {
4385 if (VecVT == MVT::v4f32)
4386 return HasVSX ? PPC::XVCMPEQSP : PPC::VCMPEQFP;
4387 else if (VecVT == MVT::v2f64)
4388 return PPC::XVCMPEQDP;
4392 if (VecVT == MVT::v4f32)
4393 return HasVSX ? PPC::XVCMPGTSP : PPC::VCMPGTFP;
4394 else if (VecVT == MVT::v2f64)
4395 return PPC::XVCMPGTDP;
4399 if (VecVT == MVT::v4f32)
4400 return HasVSX ? PPC::XVCMPGESP : PPC::VCMPGEFP;
4401 else if (VecVT == MVT::v2f64)
4402 return PPC::XVCMPGEDP;
4429 if (VecVT == MVT::v16i8)
4430 return PPC::VCMPEQUB;
4431 else if (VecVT == MVT::v8i16)
4432 return PPC::VCMPEQUH;
4433 else if (VecVT == MVT::v4i32)
4434 return PPC::VCMPEQUW;
4435 else if (VecVT == MVT::v2i64)
4436 return PPC::VCMPEQUD;
4437 else if (VecVT == MVT::v1i128)
4438 return PPC::VCMPEQUQ;
4441 if (VecVT == MVT::v16i8)
4442 return PPC::VCMPGTSB;
4443 else if (VecVT == MVT::v8i16)
4444 return PPC::VCMPGTSH;
4445 else if (VecVT == MVT::v4i32)
4446 return PPC::VCMPGTSW;
4447 else if (VecVT == MVT::v2i64)
4448 return PPC::VCMPGTSD;
4449 else if (VecVT == MVT::v1i128)
4450 return PPC::VCMPGTSQ;
4453 if (VecVT == MVT::v16i8)
4454 return PPC::VCMPGTUB;
4455 else if (VecVT == MVT::v8i16)
4456 return PPC::VCMPGTUH;
4457 else if (VecVT == MVT::v4i32)
4458 return PPC::VCMPGTUW;
4459 else if (VecVT == MVT::v2i64)
4460 return PPC::VCMPGTUD;
4461 else if (VecVT == MVT::v1i128)
4462 return PPC::VCMPGTUQ;
4471bool PPCDAGToDAGISel::trySETCC(SDNode *
N) {
4474 bool IsStrict =
N->isStrictFPOpcode();
4479 bool isPPC64 = (PtrVT == MVT::i64);
4495 SDValue Ops[] = {
Op, getI32Imm(27, dl), getI32Imm(5, dl),
4496 getI32Imm(31, dl) };
4504 Op, getI32Imm(~0U, dl)), 0);
4509 SDValue Ops[] = {
Op, getI32Imm(1, dl), getI32Imm(31, dl),
4510 getI32Imm(31, dl) };
4518 SDValue Ops[] = {
T, getI32Imm(1, dl), getI32Imm(31, dl),
4519 getI32Imm(31, dl) };
4524 }
else if (Imm == ~0U) {
4531 Op, getI32Imm(1, dl)), 0);
4536 0),
Op.getValue(1));
4541 SDNode *AD = CurDAG->
getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Glue,
4542 Op, getI32Imm(~0U, dl));
4549 getI32Imm(1, dl)), 0);
4552 SDValue Ops[] = { AN, getI32Imm(1, dl), getI32Imm(31, dl),
4553 getI32Imm(31, dl) };
4558 SDValue Ops[] = {
Op, getI32Imm(1, dl), getI32Imm(31, dl),
4559 getI32Imm(31, dl) };
4570 if (!IsStrict &&
LHS.getValueType().isVector()) {
4571 if (Subtarget->hasSPE())
4574 EVT VecVT =
LHS.getValueType();
4576 unsigned int VCmpInst =
4584 CurDAG->
SelectNodeTo(
N, Subtarget->hasVSX() ? PPC::XXLNOR : PPC::VNOR,
4593 if (Subtarget->useCRBits())
4605 if (Subtarget->hasSPE() &&
LHS.getValueType().isFloatingPoint()) {
4619 SDValue Ops[] = { IntCR, getI32Imm((32 - (3 - Idx)) & 31, dl),
4620 getI32Imm(31, dl), getI32Imm(31, dl) };
4629 CurDAG->
SelectNodeTo(
N, PPC::XORI, MVT::i32, Tmp, getI32Imm(1, dl));
4635bool PPCDAGToDAGISel::isOffsetMultipleOf(SDNode *
N,
unsigned Val)
const {
4640 if (LDN || (MIN &&
MIN->getOpcode() == PPCISD::LD_SPLAT))
4656 if ((SlotAlign % Val) != 0)
4671void PPCDAGToDAGISel::transferMemOperands(SDNode *
N, SDNode *Result) {
4678 bool &NeedSwapOps,
bool &IsUnCmp) {
4684 SDValue TrueRes =
N->getOperand(2);
4685 SDValue FalseRes =
N->getOperand(3);
4687 if (!TrueConst || (
N->getSimpleValueType(0) != MVT::i64 &&
4688 N->getSimpleValueType(0) != MVT::i32))
4697 if ((TrueResVal < -1 || TrueResVal > 1) ||
4734 if (!SelCCTrueConst || !SelCCFalseConst)
4739 if (SelCCTVal == -1 && SelCCFVal == 1) {
4741 }
else if (SelCCTVal != 1 || SelCCFVal != -1)
4751 bool InnerSwapped =
false;
4752 if (
LHS == InnerRHS &&
RHS == InnerLHS)
4753 InnerSwapped =
true;
4754 else if (
LHS != InnerLHS ||
RHS != InnerRHS)
4765 NeedSwapOps = (InnerCC ==
ISD::SETGT) ? InnerSwapped : !InnerSwapped;
4782 NeedSwapOps = (TrueResVal == 1);
4801 NeedSwapOps = (TrueResVal == -1);
4810 LLVM_DEBUG(
dbgs() <<
"Found a node that can be lowered to a SETB: ");
4818 if (
N.getOpcode() == PPCISD::FTSQRT)
4823 switch (
N.getConstantOperandVal(0)) {
4824 case Intrinsic::ppc_vsx_xvtdivdp:
4825 case Intrinsic::ppc_vsx_xvtdivsp:
4826 case Intrinsic::ppc_vsx_xvtsqrtdp:
4827 case Intrinsic::ppc_vsx_xvtsqrtsp:
4833bool PPCDAGToDAGISel::tryFoldSWTestBRCC(SDNode *
N) {
4834 assert(
N->getOpcode() == ISD::BR_CC &&
"ISD::BR_CC is expected.");
4891bool PPCDAGToDAGISel::trySelectLoopCountIntrinsic(SDNode *
N) {
4903 LHS.getOperand(0).getConstantOperandVal(1) != Intrinsic::loop_decrement)
4910 "Counter decrement comparison is not EQ or NE");
4913 assert(OldDecrement.
hasOneUse() &&
"loop decrement has more than one use!");
4915 SDLoc DecrementLoc(OldDecrement);
4917 SDValue DecrementOps[] = {Subtarget->isPPC64() ? getI64Imm(1, DecrementLoc)
4918 : getI32Imm(1, DecrementLoc)};
4919 unsigned DecrementOpcode =
4920 Subtarget->isPPC64() ? PPC::DecreaseCTR8loop : PPC::DecreaseCTRloop;
4921 SDNode *NewDecrement = CurDAG->
getMachineNode(DecrementOpcode, DecrementLoc,
4922 MVT::i1, DecrementOps);
4924 unsigned Val =
RHS->getAsZExtVal();
4926 unsigned Opcode = IsBranchOnTrue ? PPC::BC : PPC::BCn;
4928 ReplaceUses(
LHS.getValue(0),
LHS.getOperand(1));
4932 ReplaceUses(OldDecrement.
getValue(1), ChainInput);
4936 ChainInput,
N->getOperand(0));
4939 N->getOperand(4), Chain);
4943bool PPCDAGToDAGISel::tryAsSingleRLWINM(SDNode *
N) {
4951 unsigned SH, MB, ME;
4954 if (isRotateAndMask(Val.
getNode(), Imm,
false, SH, MB, ME)) {
4956 SDValue Ops[] = {Val, getI32Imm(SH, dl), getI32Imm(MB, dl),
4967 unsigned AlreadyCleared = 0;
4970 if (IntrinsicID == Intrinsic::ppc_lbarx)
4971 AlreadyCleared = 24;
4972 else if (IntrinsicID == Intrinsic::ppc_lharx)
4973 AlreadyCleared = 16;
4974 if (AlreadyCleared != 0 && AlreadyCleared == MB && ME == 31) {
4975 ReplaceUses(
SDValue(
N, 0),
N->getOperand(0));
4980 SDValue Ops[] = {Val, getI32Imm(0, dl), getI32Imm(MB, dl),
4988 ReplaceUses(
SDValue(
N, 0),
N->getOperand(1));
4995bool PPCDAGToDAGISel::tryAsSingleRLWINM8(SDNode *
N) {
5012 SDValue Ops[] = {
N->getOperand(0), getI64Imm(0, dl), getI64Imm(MB - 32, dl),
5013 getI64Imm(ME - 32, dl)};
5021bool PPCDAGToDAGISel::tryAsPairOfRLDICL(SDNode *
N) {
5041 if (NumOfLeadingZeros != 0)
5054 unsigned OnesOnLeft = ME + 1;
5055 unsigned ZerosInBetween = (MB - ME + 63) & 63;
5059 getI64Imm(OnesOnLeft, Loc),
5060 getI64Imm(ZerosInBetween, Loc)),
5069 SDValue Ops[] = {Val, getI64Imm(64 - OnesOnLeft, Loc),
5070 getI64Imm(NumOfLeadingZeros, Loc)};
5075bool PPCDAGToDAGISel::tryAsSingleRLWIMI(SDNode *
N) {
5102 if (
isRunOfOnes(~(Imm ^ Imm2), MB, ME) && !(~Imm & Imm2)) {
5105 getI32Imm(MB, dl), getI32Imm(ME, dl)};
5113bool PPCDAGToDAGISel::tryAsSingleRLDCL(SDNode *
N) {
5142bool PPCDAGToDAGISel::tryAsSingleRLDICL(SDNode *
N) {
5161 auto ImDef = CurDAG->
getMachineNode(PPC::IMPLICIT_DEF, dl, ResultType);
5179 assert(Imm < 64 &&
"Illegal shift amount");
5184 SDValue Ops[] = {Val, getI32Imm(SH, dl), getI32Imm(MB, dl)};
5189bool PPCDAGToDAGISel::tryAsSingleRLDICR(SDNode *
N) {
5202 SDValue Ops[] = {
N->getOperand(0), getI32Imm(SH, dl), getI32Imm(MB, dl)};
5207bool PPCDAGToDAGISel::tryAsSingleRLDIMI(SDNode *
N) {
5221 unsigned SH = 63 - ME;
5227 getI32Imm(SH, Dl), getI32Imm(MB, Dl)};
5234void PPCDAGToDAGISel::Select(SDNode *
N) {
5236 if (
N->isMachineOpcode()) {
5249 if (tryBitPermutation(
N))
5253 if (tryIntCompareInGPR(
N))
5256 switch (
N->getOpcode()) {
5260 if (
N->getValueType(0) == MVT::i64) {
5267 auto IntrinsicID =
N->getConstantOperandVal(1);
5268 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
5269 IntrinsicID != Intrinsic::ppc_trapd &&
5270 IntrinsicID != Intrinsic::ppc_trap)
5272 unsigned Opcode = (IntrinsicID == Intrinsic::ppc_tdw ||
5273 IntrinsicID == Intrinsic::ppc_trapd)
5278 if (IntrinsicID == Intrinsic::ppc_tdw ||
5279 IntrinsicID == Intrinsic::ppc_tw) {
5280 SDValue Ops[] = {
N->getOperand(4),
N->getOperand(2),
N->getOperand(3)};
5281 int16_t SImmOperand2;
5282 int16_t SImmOperand3;
5283 int16_t SImmOperand4;
5284 bool isOperand2IntS16Immediate =
5286 bool isOperand3IntS16Immediate =
5291 if (isOperand2IntS16Immediate == isOperand3IntS16Immediate)
5292 Opcode = IntrinsicID == Intrinsic::ppc_tdw ? PPC::TD : PPC::TW;
5293 else if (isOperand3IntS16Immediate)
5295 Ops[2] = getI32Imm(
int(SImmOperand3) & 0xFFFF, dl);
5298 bool isOperand4IntS16Immediate =
5300 (void)isOperand4IntS16Immediate;
5301 assert(isOperand4IntS16Immediate &&
5302 "The 4th operand is not an Immediate");
5304 int16_t TO = int(SImmOperand4) & 0x1F;
5306 if ((TO & 0x1) != ((TO & 0x2) >> 1))
5307 TO = (TO & 0x1) ? TO + 1 : TO - 1;
5309 if ((TO & 0x8) != ((TO & 0x10) >> 1))
5310 TO = (TO & 0x8) ? TO + 8 : TO - 8;
5311 Ops[0] = getI32Imm(TO, dl);
5312 Ops[1] =
N->getOperand(3);
5313 Ops[2] = getI32Imm(
int(SImmOperand2) & 0xFFFF, dl);
5318 OpsWithMD = {getI32Imm(24, dl),
N->getOperand(2), getI32Imm(0, dl)};
5322 if (
N->getNumOperands() > MDIndex) {
5323 SDValue MDV =
N->getOperand(MDIndex);
5328 "ppc-trap-reason") &&
5329 "Unsupported annotation data type!");
5332 "Invalid data type for annotation ppc-trap-reason!");
5335 MD->
getOperand(i))->getString().str()), dl));
5350 auto IntID =
N->getConstantOperandVal(0);
5351 if (IntID == Intrinsic::ppc_fsels) {
5352 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2),
N->getOperand(3)};
5357 if (IntID == Intrinsic::ppc_bcdadd_p || IntID == Intrinsic::ppc_bcdsub_p) {
5358 auto Pred =
N->getConstantOperandVal(1);
5360 IntID == Intrinsic::ppc_bcdadd_p ? PPC::BCDADD_rec : PPC::BCDSUB_rec;
5362 unsigned ShiftVal = 0;
5401 EVT VTs[] = {MVT::v16i8, MVT::Glue};
5408 if (Subtarget->isISA3_1()) {
5411 CurDAG->
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
5412 CR6Reg, SubRegIdx, BCDOp.
getValue(1)),
5421 SDValue Ops[] = {Move, getI32Imm((32 - (4 + ShiftVal)) & 31, dl),
5422 getI32Imm(31, dl), getI32Imm(31, dl)};
5428 CurDAG->
SelectNodeTo(
N, PPC::XORI, MVT::i32, Shift, getI32Imm(1, dl));
5434 if (!Subtarget->isISA3_1())
5436 unsigned Opcode = 0;
5440 case Intrinsic::ppc_altivec_vstribr_p:
5441 Opcode = PPC::VSTRIBR_rec;
5443 case Intrinsic::ppc_altivec_vstribl_p:
5444 Opcode = PPC::VSTRIBL_rec;
5446 case Intrinsic::ppc_altivec_vstrihr_p:
5447 Opcode = PPC::VSTRIHR_rec;
5449 case Intrinsic::ppc_altivec_vstrihl_p:
5450 Opcode = PPC::VSTRIHL_rec;
5457 EVT VTs[] = {MVT::v16i8, MVT::Glue};
5465 CurDAG->
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
5466 CR6Reg, SubRegIdx, VecStrOp.
getValue(1)),
5480 case PPCISD::ADDI_TLSLD_L_ADDR:
5481 case PPCISD::ADDI_TLSGD_L_ADDR: {
5483 if (PPCLowering->getPointerTy(CurDAG->
getDataLayout()) != MVT::i32 ||
5484 !Subtarget->isSecurePlt() || !Subtarget->
isTargetELF() ||
5492 case PPCISD::CALL_RM: {
5494 !Subtarget->isSecurePlt() || !Subtarget->
isTargetELF())
5510 ReplaceNode(
N, getGlobalBaseReg());
5514 selectFrameIndex(
N,
N);
5520 N->getOperand(0), InGlue));
5525 ReplaceNode(
N, CurDAG->
getMachineNode(PPC::ReadTB, dl, MVT::i32, MVT::i32,
5526 MVT::Other,
N->getOperand(0)));
5533 getConstantIntValue(), dl,
5534 N->getValueType(0));
5535 if (
N->getValueType(0) == MVT::i64) {
5543 assert(
N->getValueType(0) == MVT::i32 &&
5544 "Expecting i64 or i32 in PPCISD::SRA_ADDZE");
5560 if (tryTLSXFormStore(ST))
5567 EVT LoadedVT =
LD->getMemoryVT();
5574 if (tryTLSXFormLoad(LD))
5585 if (
LD->getValueType(0) != MVT::i64) {
5587 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5590 case MVT::f64: Opcode = PPC::LFDU;
break;
5591 case MVT::f32: Opcode = PPC::LFSU;
break;
5592 case MVT::i32: Opcode = PPC::LWZU;
break;
5593 case MVT::i16: Opcode = isSExt ? PPC::LHAU : PPC::LHZU;
break;
5595 case MVT::i8: Opcode = PPC::LBZU;
break;
5598 assert(
LD->getValueType(0) == MVT::i64 &&
"Unknown load result type!");
5599 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5602 case MVT::i64: Opcode = PPC::LDU;
break;
5603 case MVT::i32: Opcode = PPC::LWZU8;
break;
5604 case MVT::i16: Opcode = isSExt ? PPC::LHAU8 : PPC::LHZU8;
break;
5606 case MVT::i8: Opcode = PPC::LBZU8;
break;
5614 Opcode, dl,
LD->getValueType(0),
5616 transferMemOperands(
N, MN);
5622 if (
LD->getValueType(0) != MVT::i64) {
5624 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5627 case MVT::f64: Opcode = PPC::LFDUX;
break;
5628 case MVT::f32: Opcode = PPC::LFSUX;
break;
5629 case MVT::i32: Opcode = PPC::LWZUX;
break;
5630 case MVT::i16: Opcode = isSExt ? PPC::LHAUX : PPC::LHZUX;
break;
5632 case MVT::i8: Opcode = PPC::LBZUX;
break;
5635 assert(
LD->getValueType(0) == MVT::i64 &&
"Unknown load result type!");
5636 assert((!isSExt || LoadedVT == MVT::i16 || LoadedVT == MVT::i32) &&
5637 "Invalid sext update load");
5640 case MVT::i64: Opcode = PPC::LDUX;
break;
5641 case MVT::i32: Opcode = isSExt ? PPC::LWAUX : PPC::LWZUX8;
break;
5642 case MVT::i16: Opcode = isSExt ? PPC::LHAUX8 : PPC::LHZUX8;
break;
5644 case MVT::i8: Opcode = PPC::LBZUX8;
break;
5652 Opcode, dl,
LD->getValueType(0),
5654 transferMemOperands(
N, MN);
5662 if (tryAsSingleRLWINM(
N) || tryAsSingleRLWIMI(
N) || tryAsSingleRLDCL(
N) ||
5663 tryAsSingleRLDICL(
N) || tryAsSingleRLDICR(
N) || tryAsSingleRLWINM8(
N) ||
5664 tryAsPairOfRLDICL(
N))
5670 if (
N->getValueType(0) == MVT::i32)
5671 if (tryBitfieldInsert(
N))
5682 selectFrameIndex(
N,
N->getOperand(0).getNode(), (int64_t)Imm);
5689 if (tryAsSingleRLDIMI(
N))
5695 bool IsPPC64 = Subtarget->isPPC64();
5697 (Imm64 & ~0xFFFFFFFFuLL) == 0) {
5699 uint64_t ImmHi =
Imm64 >> 16;
5700 uint64_t ImmLo =
Imm64 & 0xFFFF;
5701 if (ImmHi != 0 && ImmLo != 0) {
5704 getI16Imm(ImmLo, dl));
5718 bool IsPPC64 = Subtarget->isPPC64();
5720 (Imm64 & ~0xFFFFFFFFuLL) == 0) {
5722 uint64_t ImmHi =
Imm64 >> 16;
5723 uint64_t ImmLo =
Imm64 & 0xFFFF;
5724 if (ImmHi != 0 && ImmLo != 0) {
5727 getI16Imm(ImmLo, dl));
5740 selectFrameIndex(
N,
N->getOperand(0).getNode(), (int64_t)Imm);
5747 unsigned Imm, SH, MB, ME;
5749 isRotateAndMask(
N, Imm,
true, SH, MB, ME)) {
5751 getI32Imm(SH, dl), getI32Imm(MB, dl),
5752 getI32Imm(ME, dl) };
5761 unsigned Imm, SH, MB, ME;
5763 isRotateAndMask(
N, Imm,
true, SH, MB, ME)) {
5765 getI32Imm(SH, dl), getI32Imm(MB, dl),
5766 getI32Imm(ME, dl) };
5789 uint64_t ImmSh =
Imm >> Shift;
5796 SDNode *MulNode = CurDAG->
getMachineNode(PPC::MULLI8, dl, MVT::i64,
5797 N->getOperand(0), SDImm);
5800 getI32Imm(63 - Shift, dl)};
5805 SDNode *MulNode = CurDAG->
getMachineNode(PPC::MULLI, dl, MVT::i32,
5806 N->getOperand(0), SDImm);
5809 getI32Imm(0, dl), getI32Imm(31 - Shift, dl)};
5821 EVT InVT =
N->getOperand(0).getValueType();
5822 assert((InVT == MVT::i64 || InVT == MVT::i32) &&
5823 "Invalid input type for ANDI_rec_1_EQ_BIT");
5825 unsigned Opcode = (InVT == MVT::i64) ? PPC::ANDI8_rec : PPC::ANDI_rec;
5835 CurDAG->
SelectNodeTo(
N, TargetOpcode::EXTRACT_SUBREG, MVT::i1, CR0Reg,
5836 SRIdxVal,
SDValue(AndI.getNode(), 1) );
5843 bool isPPC64 = (PtrVT == MVT::i64);
5846 if (Subtarget->useCRBits() &&
N->getOperand(0).getValueType() == MVT::i1)
5849 if (Subtarget->isISA3_0() && Subtarget->isPPC64()) {
5850 bool NeedSwapOps =
false;
5851 bool IsUnCmp =
false;
5867 N,
N->getSimpleValueType(0) == MVT::i64 ? PPC::SETB8 : PPC::SETB,
5868 N->getValueType(0), GenCC);
5879 N->getValueType(0) == MVT::i32) {
5882 N->getOperand(0), getI32Imm(~0U, dl));
5884 N->getOperand(0),
SDValue(Tmp, 1));
5888 SDValue CCReg = SelectCC(
N->getOperand(0),
N->getOperand(1), CC, dl);
5890 if (
N->getValueType(0) == MVT::i1) {
5898 case 0: SRI = PPC::sub_lt;
break;
5899 case 1: SRI = PPC::sub_gt;
break;
5900 case 2: SRI = PPC::sub_eq;
break;
5901 case 3: SRI = PPC::sub_un;
break;
5908 SDValue C = Inv ? NotCCBit : CCBit,
5909 NotC = Inv ? CCBit : NotCCBit;
5912 C,
N->getOperand(2)), 0);
5914 NotC,
N->getOperand(3)), 0);
5916 CurDAG->
SelectNodeTo(
N, PPC::CROR, MVT::i1, CAndT, NotCAndF);
5923 unsigned SelectCCOp;
5924 if (
N->getValueType(0) == MVT::i32)
5925 SelectCCOp = PPC::SELECT_CC_I4;
5926 else if (
N->getValueType(0) == MVT::i64)
5927 SelectCCOp = PPC::SELECT_CC_I8;
5928 else if (
N->getValueType(0) == MVT::f32) {
5929 if (Subtarget->hasP8Vector())
5930 SelectCCOp = PPC::SELECT_CC_VSSRC;
5931 else if (Subtarget->hasSPE())
5932 SelectCCOp = PPC::SELECT_CC_SPE4;
5934 SelectCCOp = PPC::SELECT_CC_F4;
5935 }
else if (
N->getValueType(0) == MVT::f64) {
5936 if (Subtarget->hasVSX())
5937 SelectCCOp = PPC::SELECT_CC_VSFRC;
5938 else if (Subtarget->hasSPE())
5939 SelectCCOp = PPC::SELECT_CC_SPE;
5941 SelectCCOp = PPC::SELECT_CC_F8;
5942 }
else if (
N->getValueType(0) == MVT::f128)
5943 SelectCCOp = PPC::SELECT_CC_F16;
5944 else if (Subtarget->hasSPE())
5945 SelectCCOp = PPC::SELECT_CC_SPE;
5946 else if (
N->getValueType(0) == MVT::v2f64 ||
5947 N->getValueType(0) == MVT::v2i64)
5948 SelectCCOp = PPC::SELECT_CC_VSRC;
5950 SelectCCOp = PPC::SELECT_CC_VRRC;
5953 getI32Imm(BROpc, dl) };
5958 if (Subtarget->hasVSX() && (
N->getValueType(0) == MVT::v2f64 ||
5959 N->getValueType(0) == MVT::v2i64)) {
5966 for (
int i = 0; i < 2; ++i)
5972 if (Op1 == Op2 &&
DM[0] == 0 &&
DM[1] == 0 &&
5978 if (
LD->isUnindexed() &&
LD->hasOneUse() && Op1.
hasOneUse() &&
5979 (
LD->getMemoryVT() == MVT::f64 ||
5980 LD->getMemoryVT() == MVT::i64) &&
5984 MachineMemOperand *MemOp =
LD->getMemOperand();
5986 N->getValueType(0),
Ops);
5996 unsigned tmp =
DM[0];
6011 bool IsPPC64 = Subtarget->isPPC64();
6012 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(0) };
6014 ? (IsPPC64 ? PPC::BDNZ8 : PPC::BDNZ)
6015 : (IsPPC64 ? PPC::BDZ8 : PPC::BDZ),
6019 case PPCISD::COND_BRANCH: {
6026 unsigned PCC =
N->getConstantOperandVal(1);
6030 SDValue Pred = getI32Imm(PCC, dl);
6037 if (tryFoldSWTestBRCC(
N))
6039 if (trySelectLoopCountIntrinsic(
N))
6045 if (
N->getOperand(2).getValueType() == MVT::i1) {
6068 N->getOperand(Swap ? 3 : 2),
6069 N->getOperand(Swap ? 2 : 3)), 0);
6070 CurDAG->
SelectNodeTo(
N, PPC::BC, MVT::Other, BitComp,
N->getOperand(4),
6080 N->getOperand(4),
N->getOperand(0) };
6088 unsigned Opc =
Target.getValueType() == MVT::i32 ? PPC::MTCTR : PPC::MTCTR8;
6089 unsigned Reg =
Target.getValueType() == MVT::i32 ? PPC::BCTR : PPC::BCTR8;
6095 case PPCISD::TOC_ENTRY: {
6096 const bool isPPC64 = Subtarget->isPPC64();
6097 const bool isELFABI = Subtarget->
isSVR4ABI();
6098 const bool isAIXABI = Subtarget->
isAIXABI();
6104 "PowerPC doesn't support tiny or kernel code models.");
6115 auto replaceWith = [
this, &dl](
unsigned OpCode, SDNode *TocEntry,
6117 SDValue GA = TocEntry->getOperand(0);
6118 SDValue TocBase = TocEntry->getOperand(1);
6119 SDNode *MN =
nullptr;
6120 if (OpCode == PPC::ADDItoc || OpCode == PPC::ADDItoc8)
6126 transferMemOperands(TocEntry, MN);
6128 ReplaceNode(TocEntry, MN);
6137 "32-bit ELF can only have TOC entries in position independent"
6140 replaceWith(PPC::LWZtoc,
N, MVT::i32);
6144 assert(isAIXABI &&
"ELF ABI already handled");
6147 replaceWith(PPC::ADDItoc,
N, MVT::i32);
6151 replaceWith(PPC::LWZtoc,
N, MVT::i32);
6156 assert(isAIXABI &&
"ELF ABI handled in common SelectCode");
6159 replaceWith(PPC::ADDItoc8,
N, MVT::i64);
6169 assert((isPPC64 || (isAIXABI && !isPPC64)) &&
"We are dealing with 64-bit"
6170 " ELF/AIX or 32-bit AIX in the following.");
6195 isPPC64 ? PPC::ADDIStocHA8 : PPC::ADDIStocHA, dl, VT, TOCbase, GA);
6202 dl, VT,
SDValue(Tmp, 0), GA));
6206 if (PPCLowering->isAccessedAsGotIndirect(GA)) {
6210 isPPC64 ? PPC::LDtocL : PPC::LWZtocL, dl, VT, GA,
SDValue(Tmp, 0));
6212 transferMemOperands(
N, MN);
6217 assert(isPPC64 &&
"TOC_ENTRY already handled for 32-bit.");
6226 "PPCISD::PPC32_PICGOT is only supported for 32-bit SVR4");
6237 "Invalid operand on VADD_SPLAT!");
6239 int Elt =
N->getConstantOperandVal(0);
6240 int EltSize =
N->getConstantOperandVal(1);
6241 unsigned Opc1, Opc2, Opc3;
6245 Opc1 = PPC::VSPLTISB;
6246 Opc2 = PPC::VADDUBM;
6247 Opc3 = PPC::VSUBUBM;
6249 }
else if (EltSize == 2) {
6250 Opc1 = PPC::VSPLTISH;
6251 Opc2 = PPC::VADDUHM;
6252 Opc3 = PPC::VSUBUHM;
6255 assert(EltSize == 4 &&
"Invalid element size on VADD_SPLAT!");
6256 Opc1 = PPC::VSPLTISW;
6257 Opc2 = PPC::VADDUWM;
6258 Opc3 = PPC::VSUBUWM;
6262 if ((Elt & 1) == 0) {
6269 SDValue EltVal = getI32Imm(Elt >> 1, dl);
6274 }
else if (Elt > 0) {
6281 SDValue EltVal = getI32Imm(Elt - 16, dl);
6283 EltVal = getI32Imm(-16, dl);
6295 SDValue EltVal = getI32Imm(Elt + 16, dl);
6297 EltVal = getI32Imm(-16, dl);
6304 case PPCISD::LD_SPLAT: {
6308 if (!Subtarget->hasAltivec() || Subtarget->hasDirectMove())
6311 EVT
Type =
N->getValueType(0);
6312 if (
Type != MVT::v16i8 &&
Type != MVT::v8i16)
6321 isOffsetMultipleOf(
N, 16))
6325 CurDAG->
getRegister(Subtarget->isPPC64() ? PPC::ZERO8 : PPC::ZERO,
6327 unsigned LIOpcode = Subtarget->isPPC64() ? PPC::LI8 : PPC::LI;
6342 unsigned SplatOp = (
Type == MVT::v16i8) ? PPC::VSPLTB : PPC::VSPLTH;
6343 unsigned SplatElemIndex =
6354 SDNode *LoadHigh = LoadLow;
6355 if (
Type == MVT::v8i16) {
6357 PPC::LVX, dl, MVT::v16i8, MVT::Other,
6359 LIOpcode, dl, MVT::i32,
6362 N->getOperand(1),
SDValue(LoadLow, 1)});
6366 transferMemOperands(
N, LoadHigh);
6387SDValue PPCDAGToDAGISel::combineToCMPB(SDNode *
N) {
6391 "Only OR nodes are supported for CMPB");
6394 if (!Subtarget->hasCMPB())
6397 if (
N->getValueType(0) != MVT::i32 &&
6398 N->getValueType(0) != MVT::i64)
6401 EVT VT =
N->getValueType(0);
6404 bool BytesFound[8] = {
false,
false,
false,
false,
false,
false,
false,
false};
6405 uint64_t
Mask = 0, Alt = 0;
6407 auto IsByteSelectCC = [
this](
SDValue O,
unsigned &
b,
6408 uint64_t &
Mask, uint64_t &Alt,
6418 uint64_t PM =
O.getConstantOperandVal(2);
6419 uint64_t PAlt =
O.getConstantOperandVal(3);
6420 for (b = 0;
b < 8; ++
b) {
6421 uint64_t
Mask = UINT64_C(0xFF) << (8*
b);
6422 if (PM && (PM & Mask) == PM && (PAlt & Mask) == PAlt)
6432 O.getConstantOperandVal(1) != 0) {
6433 SDValue Op0 =
O.getOperand(0), Op1 =
O.getOperand(1);
6465 uint64_t ULim =
O.getConstantOperandVal(1);
6466 if (ULim != (UINT64_C(1) << b*8))
6491 if (
Op.getConstantOperandVal(1) != (UINT64_C(0xFF) << (8*b)))
6506 unsigned Bits =
Op.getValueSizeInBits();
6509 if (
Op.getConstantOperandVal(1) != Bits-8)
6527 while (!
Queue.empty()) {
6530 for (
const SDValue &O :
V.getNode()->ops()) {
6532 uint64_t
M = 0,
A = 0;
6536 }
else if (IsByteSelectCC(O, b, M,
A, OLHS, ORHS)) {
6540 BytesFound[
b] =
true;
6543 }
else if ((
LHS == ORHS &&
RHS == OLHS) ||
6544 (
RHS == ORHS &&
LHS == OLHS)) {
6545 BytesFound[
b] =
true;
6557 unsigned LastB = 0, BCnt = 0;
6558 for (
unsigned i = 0; i < 8; ++i)
6559 if (BytesFound[LastB]) {
6564 if (!LastB || BCnt < 2)
6569 if (
LHS.getValueType() != VT) {
6576 bool NonTrivialMask = ((int64_t)
Mask) != INT64_C(-1);
6577 if (NonTrivialMask && !Alt) {
6604void PPCDAGToDAGISel::foldBoolExts(
SDValue &Res, SDNode *&
N) {
6605 if (!Subtarget->useCRBits())
6613 if (
N->getOperand(0).getValueType() != MVT::i1)
6616 if (!
N->hasOneUse())
6620 EVT VT =
N->getValueType(0);
6627 SDNode *
User = *
N->user_begin();
6628 if (
User->getNumOperands() != 2)
6637 User->getValueType(0), {O0, O1});
6642 SDValue TrueRes = TryFold(ConstTrue);
6643 if (!TrueRes || TrueRes.
isUndef())
6645 SDValue FalseRes = TryFold(ConstFalse);
6646 if (!FalseRes || FalseRes.
isUndef())
6659 ConstTrue = TrueRes;
6660 ConstFalse = FalseRes;
6661 }
while (
N->hasOneUse());
6664void PPCDAGToDAGISel::PreprocessISelDAG() {
6667 bool MadeChange =
false;
6669 SDNode *
N = &*--Position;
6674 switch (
N->getOpcode()) {
6677 Res = combineToCMPB(
N);
6682 foldBoolExts(Res,
N);
6702void PPCDAGToDAGISel::PostprocessISelDAG() {
6709 PeepholePPC64ZExt();
6717bool PPCDAGToDAGISel::AllUsersSelectZero(SDNode *
N) {
6718 for (
const SDNode *User :
N->users()) {
6719 if (!
User->isMachineOpcode())
6721 if (
User->getMachineOpcode() != PPC::SELECT_I4 &&
6722 User->getMachineOpcode() != PPC::SELECT_I8)
6725 SDNode *Op1 =
User->getOperand(1).getNode();
6726 SDNode *Op2 =
User->getOperand(2).getNode();
6746void PPCDAGToDAGISel::SwapAllSelectUsers(SDNode *
N) {
6748 for (SDNode *User :
N->users()) {
6749 assert((
User->getMachineOpcode() == PPC::SELECT_I4 ||
6750 User->getMachineOpcode() == PPC::SELECT_I8) &&
6751 "Must have all select users");
6755 for (SDNode *User : ToReplace) {
6758 User->getValueType(0),
User->getOperand(0),
6759 User->getOperand(2),
6760 User->getOperand(1));
6768 ReplaceUses(User, ResNode);
6772void PPCDAGToDAGISel::PeepholeCROps() {
6776 for (SDNode &Node : CurDAG->
allnodes()) {
6778 if (!MachineNode || MachineNode->
use_empty())
6780 SDNode *ResNode = MachineNode;
6782 bool Op1Set =
false, Op1Unset =
false,
6784 Op2Set =
false, Op2Unset =
false,
6799 if (
Op.isMachineOpcode()) {
6800 if (
Op.getMachineOpcode() == PPC::CRSET)
6802 else if (
Op.getMachineOpcode() == PPC::CRUNSET)
6804 else if ((
Op.getMachineOpcode() == PPC::CRNOR &&
6805 Op.getOperand(0) ==
Op.getOperand(1)) ||
6806 Op.getMachineOpcode() == PPC::CRNOT)
6813 case PPC::SELECT_I4:
6814 case PPC::SELECT_I8:
6815 case PPC::SELECT_F4:
6816 case PPC::SELECT_F8:
6817 case PPC::SELECT_SPE:
6818 case PPC::SELECT_SPE4:
6819 case PPC::SELECT_VRRC:
6820 case PPC::SELECT_VSFRC:
6821 case PPC::SELECT_VSSRC:
6822 case PPC::SELECT_VSRC: {
6824 if (
Op.isMachineOpcode()) {
6825 if (
Op.getMachineOpcode() == PPC::CRSET)
6827 else if (
Op.getMachineOpcode() == PPC::CRUNSET)
6829 else if ((
Op.getMachineOpcode() == PPC::CRNOR &&
6830 Op.getOperand(0) ==
Op.getOperand(1)) ||
6831 Op.getMachineOpcode() == PPC::CRNOT)
6838 bool SelectSwap =
false;
6851 else if (Op1Unset || Op2Unset)
6853 ResNode = CurDAG->
getMachineNode(PPC::CRUNSET, SDLoc(MachineNode),
6857 ResNode = CurDAG->
getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
6863 ResNode = CurDAG->
getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
6867 else if (AllUsersSelectZero(MachineNode)) {
6868 ResNode = CurDAG->
getMachineNode(PPC::CRNAND, SDLoc(MachineNode),
6890 else if (Op1Unset || Op2Unset)
6906 else if (AllUsersSelectZero(MachineNode)) {
6917 else if (Op1Set || Op2Set)
6939 else if (AllUsersSelectZero(MachineNode)) {
6949 ResNode = CurDAG->
getMachineNode(PPC::CRUNSET, SDLoc(MachineNode),
6979 else if (AllUsersSelectZero(MachineNode)) {
6987 if (Op1Set || Op2Set)
6989 ResNode = CurDAG->
getMachineNode(PPC::CRUNSET, SDLoc(MachineNode),
7003 ResNode = CurDAG->
getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
7009 ResNode = CurDAG->
getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
7013 else if (AllUsersSelectZero(MachineNode)) {
7053 else if (AllUsersSelectZero(MachineNode)) {
7063 ResNode = CurDAG->
getMachineNode(PPC::CRUNSET, SDLoc(MachineNode),
7070 else if (Op1Unset || Op2Set)
7072 ResNode = CurDAG->
getMachineNode(PPC::CRUNSET, SDLoc(MachineNode),
7089 else if (AllUsersSelectZero(MachineNode)) {
7101 else if (Op1Set || Op2Unset)
7115 ResNode = CurDAG->
getMachineNode(PPC::CRNAND, SDLoc(MachineNode),
7125 else if (AllUsersSelectZero(MachineNode)) {
7126 ResNode = CurDAG->
getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
7132 case PPC::SELECT_I4:
7133 case PPC::SELECT_I8:
7134 case PPC::SELECT_F4:
7135 case PPC::SELECT_F8:
7136 case PPC::SELECT_SPE:
7137 case PPC::SELECT_SPE4:
7138 case PPC::SELECT_VRRC:
7139 case PPC::SELECT_VSFRC:
7140 case PPC::SELECT_VSSRC:
7141 case PPC::SELECT_VSRC:
7173 SwapAllSelectUsers(MachineNode);
7175 if (ResNode != MachineNode) {
7182 ReplaceUses(MachineNode, ResNode);
7188 }
while (IsModified);
7299 if (!Op0OK && !Op1OK)
7322 if (!Op0OK && !Op1OK)
7336void PPCDAGToDAGISel::PeepholePPC64ZExt() {
7337 if (!Subtarget->isPPC64())
7351 bool MadeChange =
false;
7353 SDNode *
N = &*--Position;
7355 if (
N->use_empty() || !
N->isMachineOpcode())
7358 if (
N->getMachineOpcode() != PPC::RLDICL)
7361 if (
N->getConstantOperandVal(1) != 0 ||
7362 N->getConstantOperandVal(2) != 32)
7391 SmallPtrSet<SDNode *, 16> ToPromote;
7397 bool OutsideUse =
false;
7398 for (SDNode *PN : ToPromote) {
7399 for (SDNode *UN : PN->users()) {
7400 if (!ToPromote.count(UN) && UN != ISR.
getNode()) {
7418 for (SDNode *PN : ToPromote) {
7420 switch (PN->getMachineOpcode()) {
7423 case PPC::RLWINM: NewOpcode = PPC::RLWINM8;
break;
7424 case PPC::RLWNM: NewOpcode = PPC::RLWNM8;
break;
7425 case PPC::SLW: NewOpcode = PPC::SLW8;
break;
7426 case PPC::SRW: NewOpcode = PPC::SRW8;
break;
7427 case PPC::LI: NewOpcode = PPC::LI8;
break;
7428 case PPC::LIS: NewOpcode = PPC::LIS8;
break;
7429 case PPC::LHBRX: NewOpcode = PPC::LHBRX8;
break;
7430 case PPC::LWBRX: NewOpcode = PPC::LWBRX8;
break;
7431 case PPC::CNTLZW: NewOpcode = PPC::CNTLZW8;
break;
7432 case PPC::CNTTZW: NewOpcode = PPC::CNTTZW8;
break;
7433 case PPC::RLWIMI: NewOpcode = PPC::RLWIMI8;
break;
7434 case PPC::OR: NewOpcode = PPC::OR8;
break;
7435 case PPC::SELECT_I4: NewOpcode = PPC::SELECT_I8;
break;
7436 case PPC::ORI: NewOpcode = PPC::ORI8;
break;
7437 case PPC::ORIS: NewOpcode = PPC::ORIS8;
break;
7438 case PPC::AND: NewOpcode = PPC::AND8;
break;
7440 NewOpcode = PPC::ANDI8_rec;
7442 case PPC::ANDIS_rec:
7443 NewOpcode = PPC::ANDIS8_rec;
7453 for (
const SDValue &V : PN->ops()) {
7454 if (!ToPromote.count(
V.getNode()) &&
V.getValueType() == MVT::i32 &&
7471 SDVTList VTs = PN->getVTList();
7472 for (
unsigned i = 0, ie = VTs.
NumVTs; i != ie; ++i)
7473 if (VTs.
VTs[i] == MVT::i32)
7506 if (!
N->isMachineOpcode())
7508 unsigned Opc =
N->getMachineOpcode();
7512 if (
Opc == PPC::XXPERMDIs) {
7514 N->getConstantOperandVal(1) == 2;
7515 }
else if (
Opc == PPC::XXPERMDI ||
Opc == PPC::XXSLDWI) {
7516 return N->getOperand(0) ==
N->getOperand(1) &&
7518 N->getConstantOperandVal(2) == 2;
7526 if (!
N->isMachineOpcode())
7528 unsigned Opc =
N->getMachineOpcode();
7577 auto SkipRCCopy = [](
SDValue V) {
7578 while (V->isMachineOpcode() &&
7579 V->getMachineOpcode() == TargetOpcode::COPY_TO_REGCLASS) {
7581 if (V->use_empty() || !V->user_begin()->isOnlyUserOf(V.getNode()))
7583 V = V->getOperand(0);
7585 return V.hasOneUse() ? V :
SDValue();
7588 SDValue VecOp = SkipRCCopy(
N->getOperand(0));
7608 if (GV->hasAttribute(
"aix-small-tls"))
7629 if (!(Subtarget.hasAIXSmallLocalDynamicTLS() ||
7670 if (
N->getMachineOpcode() != PPC::ADDI8)
7675 SDValue InitialADDI =
N->getOperand(0);
7686 assert(GA &&
"Expecting a valid GlobalAddressSDNode when folding addi into "
7687 "local-[exec|dynamic] accesses!");
7695 int Offset =
N->getConstantOperandVal(1);
7704void PPCDAGToDAGISel::PeepholePPC64() {
7708 SDNode *
N = &*--Position;
7710 if (
N->use_empty() || !
N->isMachineOpcode())
7721 unsigned StorageOpcode =
N->getMachineOpcode();
7722 bool RequiresMod4Offset =
false;
7724 switch (StorageOpcode) {
7729 case PPC::DFLOADf64:
7730 case PPC::DFLOADf32:
7731 RequiresMod4Offset =
true;
7747 case PPC::DFSTOREf64:
7748 case PPC::DFSTOREf32:
7749 RequiresMod4Offset =
true;
7771 if (!
Base.isMachineOpcode())
7775 bool ReplaceFlags =
true;
7787 switch (
Base.getMachineOpcode()) {
7795 ReplaceFlags =
false;
7797 case PPC::ADDIdtprelL:
7800 case PPC::ADDItlsldL:
7803 case PPC::ADDItocL8:
7818 int MaxDisplacement = 7;
7820 const GlobalValue *GV = GA->getGlobal();
7822 MaxDisplacement = std::min((
int)Alignment.
value() - 1, MaxDisplacement);
7825 bool UpdateHBase =
false;
7828 int Offset =
N->getConstantOperandVal(FirstOp);
7834 if (
Base.getMachineOpcode() != PPC::ADDItocL8)
7845 if (HImmOpnd != ImmOpnd)
7853 if (RequiresMod4Offset) {
7854 if (GlobalAddressSDNode *GA =
7856 const GlobalValue *GV = GA->getGlobal();
7871 if (RequiresMod4Offset && (
Offset % 4) != 0)
7879 }
else if (
Offset != 0) {
7887 assert(GA &&
"Expecting a valid GlobalAddressSDNode when folding "
7888 "addi into local-[exec|dynamic] accesses!");
7901 LLVM_DEBUG(
dbgs() <<
"Folding add-immediate into mem-op:\nBase: ");
7912 const GlobalValue *GV = GA->getGlobal();
7916 if (Alignment < 4 && (RequiresMod4Offset || (
Offset % 4) != 0)) {
7917 LLVM_DEBUG(
dbgs() <<
"Rejected this candidate for alignment.\n\n");
7921 }
else if (ConstantPoolSDNode *CP =
7931 Base.getOperand(0),
N->getOperand(3));
7941 if (
Base.getNode()->use_empty())
7951 return new PPCDAGToDAGISelLegacy(TM, OptLevel);
static bool isOpcWithIntImmediate(const SDNode *N, unsigned Opc, uint64_t &Imm)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
AMDGPU Register Bank Select
This file implements a class to represent arbitrary precision integral constant values and operations...
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
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< 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.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
Machine Check Debug Module
Register const TargetRegisterInfo * TRI
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
cl::opt< bool > ANDIGlueBug("expose-ppc-andi-glue-bug", cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden)
static cl::opt< bool > UseBitPermRewriter("ppc-use-bit-perm-rewriter", cl::init(true), cl::desc("use aggressive ppc isel for bit permutations"), cl::Hidden)
static bool isEligibleToFoldADDIForFasterLocalAccesses(SelectionDAG *DAG, SDValue ADDIToFold)
static bool canOptimizeTLSDFormToXForm(SelectionDAG *CurDAG, SDValue Base)
static cl::opt< bool > EnableBranchHint("ppc-use-branch-hint", cl::init(true), cl::desc("Enable static hinting of branches on ppc"), cl::Hidden)
static bool hasTocDataAttr(SDValue Val)
static void foldADDIForFasterLocalAccesses(SDNode *N, SelectionDAG *DAG)
static bool isThreadPointerAcquisitionNode(SDValue Base, SelectionDAG *CurDAG)
static bool PeepholePPC64ZExtGather(SDValue Op32, SmallPtrSetImpl< SDNode * > &ToPromote)
static bool isLaneInsensitive(SDValue N)
static unsigned allUsesTruncate(SelectionDAG *CurDAG, SDNode *N)
static CodeModel::Model getCodeModel(const PPCSubtarget &Subtarget, const TargetMachine &TM, const SDNode *Node)
static void reduceVSXSwap(SDNode *N, SelectionDAG *DAG)
static bool isOpcWithIntImmediate(SDNode *N, unsigned Opc, unsigned &Imm)
static PPC::Predicate getPredicateForSetCC(ISD::CondCode CC, const EVT &VT, const PPCSubtarget *Subtarget)
static unsigned getCRIdxForSetCC(ISD::CondCode CC, bool &Invert)
getCRIdxForSetCC - Return the index of the condition register field associated with the SetCC conditi...
static bool isInt64Immediate(SDNode *N, uint64_t &Imm)
isInt64Immediate - This method tests to see if the node is a 64-bit constant operand.
static bool isInt32Immediate(SDNode *N, unsigned &Imm)
isInt32Immediate - This method tests to see if the node is a 32-bit constant operand.
static unsigned getBranchHint(unsigned PCC, const FunctionLoweringInfo &FuncInfo, const SDValue &DestMBB)
static bool mayUseP9Setb(SDNode *N, const ISD::CondCode &CC, SelectionDAG *DAG, bool &NeedSwapOps, bool &IsUnCmp)
static cl::opt< bool > EnableTLSOpt("ppc-tls-opt", cl::init(true), cl::desc("Enable tls optimization peephole"), cl::Hidden)
static unsigned int getVCmpInst(MVT VecVT, ISD::CondCode CC, bool HasVSX, bool &Swap, bool &Negate)
static cl::opt< ICmpInGPRType > CmpInGPR("ppc-gpr-icmps", cl::Hidden, cl::init(ICGPR_All), cl::desc("Specify the types of comparisons to emit GPR-only code for."), cl::values(clEnumValN(ICGPR_None, "none", "Do not modify integer comparisons."), clEnumValN(ICGPR_All, "all", "All possible int comparisons in GPRs."), clEnumValN(ICGPR_I32, "i32", "Only i32 comparisons in GPRs."), clEnumValN(ICGPR_I64, "i64", "Only i64 comparisons in GPRs."), clEnumValN(ICGPR_NonExtIn, "nonextin", "Only comparisons where inputs don't need [sz]ext."), clEnumValN(ICGPR_Zext, "zext", "Only comparisons with zext result."), clEnumValN(ICGPR_ZextI32, "zexti32", "Only i32 comparisons with zext result."), clEnumValN(ICGPR_ZextI64, "zexti64", "Only i64 comparisons with zext result."), clEnumValN(ICGPR_Sext, "sext", "Only comparisons with sext result."), clEnumValN(ICGPR_SextI32, "sexti32", "Only i32 comparisons with sext result."), clEnumValN(ICGPR_SextI64, "sexti64", "Only i64 comparisons with sext result.")))
static SDNode * selectI64ImmDirectPrefix(SelectionDAG *CurDAG, const SDLoc &dl, uint64_t Imm, unsigned &InstCnt)
static SDNode * selectI64ImmDirect(SelectionDAG *CurDAG, const SDLoc &dl, uint64_t Imm, unsigned &InstCnt)
static bool hasAIXSmallTLSAttr(SDValue Val)
static cl::opt< bool > BPermRewriterNoMasking("ppc-bit-perm-rewriter-stress-rotates", cl::desc("stress rotate selection in aggressive ppc isel for " "bit permutations"), cl::Hidden)
static bool isSWTestOp(SDValue N)
static SDNode * selectI64Imm(SelectionDAG *CurDAG, const SDLoc &dl, uint64_t Imm, unsigned *InstCnt=nullptr)
static bool isVSXSwap(SDValue N)
static uint32_t findContiguousZerosAtLeast(uint64_t Imm, unsigned Num)
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
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 if the block is well formed or null if the block is not well forme...
LLVM_ABI BranchProbability getEdgeProbability(const BasicBlock *Src, unsigned IndexInSuccessors) const
Get an edge's probability, relative to other out-edges of the Src.
int64_t getSExtValue() const
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
BranchProbabilityInfo * BPI
MachineBasicBlock * MBB
MBB - The current block.
FunctionPass class - This class is used to implement most global optimizations.
unsigned getTargetFlags() const
const GlobalValue * getGlobal() const
Module * getParent()
Get the module that this global value is contained inside of...
bool hasAttribute(Attribute::AttrKind Kind) const
Return true if the attribute exists.
static StringRef getMemConstraintName(ConstraintCode C)
LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
This class is used to represent ISD::LOAD nodes.
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
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, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
void setROPProtectionHashSaveIndex(int Idx)
static int getRecordFormOpcode(unsigned Opcode)
bool is32BitELFABI() const
MVT getScalarIntVT() const
const PPCInstrInfo * getInstrInfo() const override
MCRegister getThreadPointerRegister() const
bool isLittleEndian() const
CodeModel::Model getCodeModel(const TargetMachine &TM, const GlobalValue *GV) const
Calculates the effective code model for argument GV.
Common code between 32-bit and 64-bit PowerPC targets.
Wrapper class representing virtual and physical registers.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.
LLVM_ABI void dump() const
Dump this node, for debugging.
bool hasOneUse() const
Return true if there is exactly one use of this node.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
bool use_empty() const
Return true if there are no uses of this node.
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
SDVTList getVTList() const
const SDValue & getOperand(unsigned Num) const
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
bool isMachineOpcode() const
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
unsigned getMachineOpcode() const
unsigned getOpcode() const
unsigned getNumOperands() const
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
virtual bool runOnMachineFunction(MachineFunction &mf)
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDNode * SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT)
These are used for target selectors to mutate the specified node to have the specified return type,...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
const TargetLowering & getTargetLoweringInfo() const
allnodes_const_iterator allnodes_begin() const
allnodes_const_iterator allnodes_end() const
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
LLVM_ABI void setNodeMemRefs(MachineSDNode *N, ArrayRef< MachineMemOperand * > NewMemRefs)
Mutate the specified machine node's memory references to the provided list.
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
LLVM_ABI void RemoveDeadNodes()
This method deletes all unreachable nodes in the SelectionDAG.
LLVM_ABI void RemoveDeadNode(SDNode *N)
Remove the specified node from the system.
LLVM_ABI SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
LLVM_ABI SDValue FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDValue > Ops, SDNodeFlags Flags=SDNodeFlags())
const TargetMachine & getTarget() const
LLVM_ABI SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
iterator_range< allnodes_iterator > allnodes()
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
LLVM_ABI SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
ilist< SDNode >::iterator allnodes_iterator
int getMaskElt(unsigned Idx) const
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This class is used to represent ISD::STORE nodes.
TargetInstrInfo - Interface to description of machine instruction set.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
Primary interface to the complete machine description for the target machine.
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
bool isPositionIndependent() const
CodeModel::Model getCodeModel() const
Returns the code model.
unsigned getID() const
Return the register class ID number.
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.
@ C
The default llvm calling convention, compatible with C.
@ 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.
@ 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...
@ 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.
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.
@ Define
Register definition.
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
This is an optimization pass for GlobalISel generic memory operations.
bool operator<(int64_t V1, const APSInt &V2)
FunctionAddr VTableAddr Value
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.
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.
static bool isRunOfOnes64(uint64_t Val, unsigned &MB, unsigned &ME)
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.
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.