49#include "llvm/IR/IntrinsicsPowerPC.h"
72#define DEBUG_TYPE "ppc-isel"
73#define PASS_NAME "PowerPC DAG->DAG Pattern Instruction Selection"
76 "Number of (sext(setcc)) nodes expanded into GPR sequence.");
78 "Number of (zext(setcc)) nodes expanded into GPR sequence.");
80 "Number of sign extensions for compare inputs added.");
82 "Number of zero extensions for compare inputs added.");
84 "Number of logical ops on i1 values calculated in GPR.");
86 "Number of compares not eliminated as they have non-extending uses.");
88 "Number of compares lowered to setb.");
96 cl::desc(
"use aggressive ppc isel for bit permutations"),
99 "ppc-bit-perm-rewriter-stress-rotates",
100 cl::desc(
"stress rotate selection in aggressive ppc isel for "
105 "ppc-use-branch-hint",
cl::init(
true),
106 cl::desc(
"Enable static hinting of branches on ppc"),
111 cl::desc(
"Enable tls optimization peephole"),
120 cl::desc(
"Specify the types of comparisons to emit GPR-only code for."),
126 "Only comparisons where inputs don't need [sz]ext."),
129 "Only i32 comparisons with zext result."),
131 "Only i64 comparisons with zext result."),
134 "Only i32 comparisons with sext result."),
136 "Only i64 comparisons with sext result.")));
147 unsigned GlobalBaseReg = 0;
152 PPCDAGToDAGISel() =
delete;
162 if (Subtarget->hasROPProtect()) {
181 inline SDValue getI16Imm(
unsigned Imm,
const SDLoc &dl) {
182 return CurDAG->getTargetConstant(Imm, dl, MVT::i16);
187 inline SDValue getI32Imm(
unsigned Imm,
const SDLoc &dl) {
188 return CurDAG->getTargetConstant(Imm, dl, MVT::i32);
194 return CurDAG->getTargetConstant(Imm, dl, MVT::i64);
199 return CurDAG->getTargetConstant(
200 Imm, dl, PPCLowering->getPointerTy(CurDAG->getDataLayout()));
205 static bool isRotateAndMask(
SDNode *
N,
unsigned Mask,
bool isShiftMask,
206 unsigned &SH,
unsigned &MB,
unsigned &ME);
210 SDNode *getGlobalBaseReg();
218 bool tryBitfieldInsert(
SDNode *
N);
219 bool tryBitPermutation(
SDNode *
N);
220 bool tryIntCompareInGPR(
SDNode *
N);
252 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
260 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
268 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
276 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
283 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
291 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
299 return PPCLowering->SelectForceXFormMode(
N, Disp,
Base, *CurDAG) ==
310 return PPCLowering->SelectAddressRegReg(
N,
Base,
Index, *CurDAG,
321 return PPCLowering->SelectAddressRegReg(
N,
Base,
Index, *CurDAG,
332 return PPCLowering->SelectAddressRegReg(
N,
Base,
Index, *CurDAG,
339 return PPCLowering->SelectAddressRegRegOnly(
N,
Base,
Index, *CurDAG);
348 return PPCLowering->SelectAddressRegImm(
N, Disp,
Base, *CurDAG,
356 return PPCLowering->SelectAddressRegImm(
N, Disp,
Base, *CurDAG,
Align(4));
363 return PPCLowering->SelectAddressRegImm(
N, Disp,
Base, *CurDAG,
371 return PPCLowering->SelectAddressRegImm34(
N, Disp,
Base, *CurDAG);
381 return PPCLowering->SelectAddressPCRel(
N,
Base);
391 std::vector<SDValue> &OutOps)
override {
392 switch(ConstraintID) {
394 errs() <<
"ConstraintID: "
408 SDValue RC = CurDAG->getTargetConstant(TRC->
getID(), dl, MVT::i32);
410 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
411 dl,
Op.getValueType(),
414 OutOps.push_back(NewOp);
421#include "PPCGenDAGISel.inc"
425 bool tryFoldSWTestBRCC(
SDNode *
N);
426 bool trySelectLoopCountIntrinsic(
SDNode *
N);
427 bool tryAsSingleRLDICL(
SDNode *
N);
428 bool tryAsSingleRLDCL(
SDNode *
N);
429 bool tryAsSingleRLDICR(
SDNode *
N);
430 bool tryAsSingleRLWINM(
SDNode *
N);
431 bool tryAsSingleRLWINM8(
SDNode *
N);
432 bool tryAsSingleRLWIMI(
SDNode *
N);
433 bool tryAsPairOfRLDICL(
SDNode *
N);
434 bool tryAsSingleRLDIMI(
SDNode *
N);
436 void PeepholePPC64();
437 void PeepholePPC64ZExt();
438 void PeepholeCROps();
443 bool AllUsersSelectZero(
SDNode *
N);
444 void SwapAllSelectUsers(
SDNode *
N);
446 bool isOffsetMultipleOf(
SDNode *
N,
unsigned Val)
const;
452char PPCDAGToDAGISel::ID = 0;
459SDNode *PPCDAGToDAGISel::getGlobalBaseReg() {
460 if (!GlobalBaseReg) {
468 if (PPCLowering->getPointerTy(CurDAG->getDataLayout()) == MVT::i32) {
471 if (!Subtarget->isSecurePlt() &&
481 TII.get(PPC::UpdateGBR), GlobalBaseReg)
487 RegInfo->createVirtualRegister(&PPC::GPRC_and_GPRC_NOR0RegClass);
507 return CurDAG->getRegister(GlobalBaseReg,
508 PPCLowering->getPointerTy(CurDAG->getDataLayout()))
548 if (
N->getOpcode() ==
ISD::Constant &&
N->getValueType(0) == MVT::i32) {
549 Imm =
N->getAsZExtVal();
558 if (
N->getOpcode() ==
ISD::Constant &&
N->getValueType(0) == MVT::i64) {
559 Imm =
N->getAsZExtVal();
580 assert(isa<BasicBlockSDNode>(DestMBB));
610 if (std::max(TProb, FProb) / Threshold < std::min(TProb, FProb))
614 <<
"::" << BB->
getName() <<
"'\n"
615 <<
" -> " <<
TBB->
getName() <<
": " << TProb <<
"\n"
616 <<
" -> " << FBB->
getName() <<
": " << FProb <<
"\n");
632 return N->getOpcode() == Opc
638 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
639 SDValue TFI = CurDAG->getTargetFrameIndex(FI,
N->getValueType(0));
640 unsigned Opc =
N->getValueType(0) == MVT::i32 ? PPC::ADDI : PPC::ADDI8;
642 CurDAG->SelectNodeTo(SN, Opc,
N->getValueType(0), TFI,
643 getSmallIPtrImm(
Offset, dl));
645 ReplaceNode(SN, CurDAG->getMachineNode(Opc, dl,
N->getValueType(0), TFI,
646 getSmallIPtrImm(
Offset, dl)));
649bool PPCDAGToDAGISel::isRotateAndMask(
SDNode *
N,
unsigned Mask,
650 bool isShiftMask,
unsigned &SH,
651 unsigned &MB,
unsigned &ME) {
654 if (
N->getValueType(0) != MVT::i32)
658 unsigned Indeterminant = ~0;
659 unsigned Opcode =
N->getOpcode();
660 if (
N->getNumOperands() != 2 ||
666 if (isShiftMask)
Mask =
Mask << Shift;
668 Indeterminant = ~(0xFFFFFFFFu << Shift);
671 if (isShiftMask)
Mask =
Mask >> Shift;
673 Indeterminant = ~(0xFFFFFFFFu >> Shift);
683 if (Mask && !(Mask & Indeterminant)) {
696 "Only expecting the ADD_TLS instruction to acquire the thread pointer!");
700 unsigned ADDTLSOp1Opcode = ADDTLSOp1.getOpcode();
713 LoadSDNode *LD = dyn_cast<LoadSDNode>(ADDTLSOp1);
725 dyn_cast_or_null<RegisterSDNode>(ADDTLSOp1.getNode());
747 for (
auto *ADDTLSUse :
Base.getNode()->uses()) {
751 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(ADDTLSUse)) {
752 if (LD->getSrcValueOffset() != 0 || !LD->getOffset().isUndef())
754 }
else if (
StoreSDNode *ST = dyn_cast<StoreSDNode>(ADDTLSUse)) {
755 if (ST->getSrcValueOffset() != 0 || !ST->getOffset().isUndef())
770bool PPCDAGToDAGISel::tryTLSXFormStore(
StoreSDNode *ST) {
776 EVT MemVT =
ST->getMemoryVT();
777 EVT RegVT =
ST->getValue().getValueType();
784 Opcode = (RegVT == MVT::i32) ? PPC::STBXTLS_32 : PPC::STBXTLS;
788 Opcode = (RegVT == MVT::i32) ? PPC::STHXTLS_32 : PPC::STHXTLS;
792 Opcode = (RegVT == MVT::i32) ? PPC::STWXTLS_32 : PPC::STWXTLS;
796 Opcode = PPC::STDXTLS;
800 Opcode = PPC::STFSXTLS;
804 Opcode = PPC::STFDXTLS;
812 SDNode *MN = CurDAG->getMachineNode(Opcode, dl, VTs, Ops);
813 transferMemOperands(ST, MN);
818bool PPCDAGToDAGISel::tryTLSXFormLoad(
LoadSDNode *LD) {
824 EVT MemVT =
LD->getMemoryVT();
825 EVT RegVT =
LD->getValueType(0);
832 Opcode = (RegVT == MVT::i32) ? PPC::LBZXTLS_32 : PPC::LBZXTLS;
836 if (RegVT == MVT::i32)
837 Opcode = isSExt ? PPC::LHAXTLS_32 : PPC::LHZXTLS_32;
839 Opcode = isSExt ? PPC::LHAXTLS : PPC::LHZXTLS;
843 if (RegVT == MVT::i32)
844 Opcode = isSExt ? PPC::LWAXTLS_32 : PPC::LWZXTLS_32;
846 Opcode = isSExt ? PPC::LWAXTLS : PPC::LWZXTLS;
850 Opcode = PPC::LDXTLS;
854 Opcode = PPC::LFSXTLS;
858 Opcode = PPC::LFDXTLS;
865 SDNode *MN = CurDAG->getMachineNode(Opcode, dl, VTs, Ops);
866 transferMemOperands(LD, MN);
873bool PPCDAGToDAGISel::tryBitfieldInsert(
SDNode *
N) {
878 KnownBits LKnown = CurDAG->computeKnownBits(Op0);
879 KnownBits RKnown = CurDAG->computeKnownBits(Op1);
884 if ((TargetMask | InsertMask) == 0xFFFFFFFF) {
887 unsigned Value, SH = 0;
888 TargetMask = ~TargetMask;
889 InsertMask = ~InsertMask;
937 SDValue Ops[] = { Op0, Op1, getI32Imm(SH, dl), getI32Imm(MB, dl),
939 ReplaceNode(
N, CurDAG->getMachineNode(PPC::RLWIMI, dl, MVT::i32, Ops));
947 unsigned MaxTruncation = 0;
954 Use->isMachineOpcode() ?
Use->getMachineOpcode() :
Use->getOpcode();
958 if (
Use->isMachineOpcode())
961 std::max(MaxTruncation, (
unsigned)
Use->getValueType(0).getSizeInBits());
964 if (
Use->isMachineOpcode())
970 MaxTruncation = std::max(MaxTruncation, MemVTSize);
979 MaxTruncation = std::max(MaxTruncation, 32u);
987 MaxTruncation = std::max(MaxTruncation, 16u);
995 MaxTruncation = std::max(MaxTruncation, 8u);
999 return MaxTruncation;
1005 unsigned HiTZ = llvm::countr_zero<uint32_t>(
Hi_32(Imm));
1006 unsigned LoLZ = llvm::countl_zero<uint32_t>(
Lo_32(Imm));
1007 if ((HiTZ + LoLZ) >= Num)
1015 unsigned TZ = llvm::countr_zero<uint64_t>(Imm);
1016 unsigned LZ = llvm::countl_zero<uint64_t>(Imm);
1017 unsigned TO = llvm::countr_one<uint64_t>(Imm);
1018 unsigned LO = llvm::countl_one<uint64_t>(Imm);
1019 unsigned Hi32 =
Hi_32(Imm);
1020 unsigned Lo32 =
Lo_32(Imm);
1021 SDNode *Result =
nullptr;
1024 auto getI32Imm = [CurDAG, dl](
unsigned Imm) {
1032 if (isInt<16>(Imm)) {
1038 if (TZ > 15 && (LZ > 32 || LO > 32))
1040 getI32Imm((Imm >> 16) & 0xffff));
1044 assert(LZ < 64 &&
"Unexpected leading zeros here.");
1046 unsigned FO = llvm::countl_one<uint64_t>(Imm << LZ);
1049 if (isInt<32>(Imm)) {
1050 uint64_t ImmHi16 = (Imm >> 16) & 0xffff;
1051 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
1052 Result = CurDAG->
getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
1054 getI32Imm(Imm & 0xffff));
1062 if ((LZ + FO + TZ) > 48) {
1064 getI32Imm((Imm >> TZ) & 0xffff));
1066 getI32Imm(TZ), getI32Imm(LZ));
1083 if ((LZ + TO) > 48) {
1087 assert(LZ <= 32 &&
"Unexpected shift value.");
1089 getI32Imm((Imm >> (48 - LZ) & 0xffff)));
1091 getI32Imm(48 - LZ), getI32Imm(LZ));
1109 if ((LZ + FO + TO) > 48) {
1111 getI32Imm((Imm >> TO) & 0xffff));
1113 getI32Imm(TO), getI32Imm(LZ));
1119 if (LZ == 32 && ((Lo32 & 0x8000) == 0)) {
1121 getI32Imm(Lo32 & 0xffff));
1123 getI32Imm(Lo32 >> 16));
1147 getI32Imm(RotImm & 0xffff));
1149 getI32Imm(Shift), getI32Imm(0));
1156 uint64_t ImmHi16 = (Lo32 >> 16) & 0xffff;
1158 if (isInt<16>(Lo32))
1160 CurDAG->
getMachineNode(PPC::LI8, dl, MVT::i64, getI32Imm(ImmLo16));
1163 CurDAG->
getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(ImmHi16));
1167 CurDAG->
getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(ImmHi16));
1169 SDValue(Result, 0), getI32Imm(ImmLo16));
1186 if ((LZ + FO + TZ) > 32) {
1187 uint64_t ImmHi16 = (Imm >> (TZ + 16)) & 0xffff;
1188 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
1189 Result = CurDAG->
getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
1191 getI32Imm((Imm >> TZ) & 0xffff));
1193 getI32Imm(TZ), getI32Imm(LZ));
1200 if ((LZ + TO) > 32) {
1204 assert(LZ <= 32 &&
"Unexpected shift value.");
1206 getI32Imm((Imm >> (48 - LZ)) & 0xffff));
1208 getI32Imm((Imm >> (32 - LZ)) & 0xffff));
1210 getI32Imm(32 - LZ), getI32Imm(LZ));
1218 if ((LZ + FO + TO) > 32) {
1220 getI32Imm((Imm >> (TO + 16)) & 0xffff));
1222 getI32Imm((Imm >> TO) & 0xffff));
1224 getI32Imm(TO), getI32Imm(LZ));
1236 uint64_t ImmHi16 = (RotImm >> 16) & 0xffff;
1237 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
1238 Result = CurDAG->
getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
1240 getI32Imm(RotImm & 0xffff));
1242 getI32Imm(Shift), getI32Imm(0));
1256 unsigned TZ = llvm::countr_zero<uint64_t>(Imm);
1257 unsigned LZ = llvm::countl_zero<uint64_t>(Imm);
1258 unsigned TO = llvm::countr_one<uint64_t>(Imm);
1259 unsigned FO = llvm::countl_one<uint64_t>(LZ == 64 ? 0 : (Imm << LZ));
1260 unsigned Hi32 =
Hi_32(Imm);
1261 unsigned Lo32 =
Lo_32(Imm);
1263 auto getI32Imm = [CurDAG, dl](
unsigned Imm) {
1267 auto getI64Imm = [CurDAG, dl](
uint64_t Imm) {
1282 SDNode *Result =
nullptr;
1289 if ((LZ + FO + TZ) > 30) {
1290 APInt SignedInt34 =
APInt(34, (Imm >> TZ) & 0x3ffffffff);
1293 getI64Imm(*Extended.getRawData()));
1295 getI32Imm(TZ), getI32Imm(LZ));
1311 if ((LZ + TO) > 30) {
1312 APInt SignedInt34 =
APInt(34, (Imm >> (30 - LZ)) & 0x3ffffffff);
1315 getI64Imm(*Extended.getRawData()));
1317 getI32Imm(30 - LZ), getI32Imm(LZ));
1324 if ((LZ + FO + TO) > 30) {
1325 APInt SignedInt34 =
APInt(34, (Imm >> TO) & 0x3ffffffff);
1328 getI64Imm(*Extended.getRawData()));
1330 getI32Imm(TO), getI32Imm(LZ));
1342 for (
unsigned Shift = 0; Shift < 63; ++Shift) {
1344 if (isInt<34>(RotImm)) {
1346 CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(RotImm));
1348 SDValue(Result, 0), getI32Imm(Shift),
1356 Result = CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(Hi32));
1366 CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(Hi32));
1368 CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(Lo32));
1375 unsigned *InstCnt =
nullptr) {
1376 unsigned InstCntDirect = 0;
1387 if (Subtarget.hasPrefixInstrs() && InstCntDirect != 1) {
1388 unsigned InstCntDirectP = 0;
1395 if (ResultP && (!Result || InstCntDirectP < InstCntDirect)) {
1397 *InstCnt = InstCntDirectP;
1404 *InstCnt = InstCntDirect;
1407 auto getI32Imm = [CurDAG, dl](
unsigned Imm) {
1416 if (Hi16OfLo32 && Lo16OfLo32) {
1419 bool IsSelected =
false;
1423 CurDAG->
getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(Hi16));
1425 SDValue(Result, 0), getI32Imm(Lo16));
1431 if (Hi16OfHi32 == Lo16OfHi32 && Lo16OfHi32 == Lo16OfLo32) {
1433 Result = getSplat(Hi16OfLo32, Lo16OfLo32);
1438 }
else if (Hi16OfHi32 == Hi16OfLo32 && Hi16OfLo32 == Lo16OfLo32) {
1440 Result = getSplat(Hi16OfHi32, Lo16OfHi32);
1443 getI32Imm(16), getI32Imm(31)};
1444 Result = CurDAG->
getMachineNode(PPC::RLWIMI8, dl, MVT::i64, Ops);
1445 }
else if (Lo16OfHi32 == Lo16OfLo32 && Hi16OfLo32 == Lo16OfLo32) {
1447 Result = getSplat(Hi16OfHi32, Lo16OfHi32);
1450 getI32Imm(0), getI32Imm(15)};
1451 Result = CurDAG->
getMachineNode(PPC::RLWIMI8, dl, MVT::i64, Ops);
1453 if (IsSelected ==
true) {
1466 SDValue(Result, 0), getI32Imm(Hi16OfLo32));
1471 getI32Imm(Lo16OfLo32));
1475 *InstCnt = InstCntDirect;
1484 int64_t Imm =
N->getAsZExtVal();
1488 if (isInt<16>(SextImm))
1496class BitPermutationSelector {
1511 VariableKnownToBeZero
1514 ValueBit(
SDValue V,
unsigned I, Kind K = Variable)
1516 ValueBit(Kind K = Variable) :
Idx(UINT32_MAX),
K(
K) {}
1519 return K == ConstZero ||
K == VariableKnownToBeZero;
1522 bool hasValue()
const {
1523 return K == Variable ||
K == VariableKnownToBeZero;
1527 assert(hasValue() &&
"Cannot get the value of a constant bit");
1531 unsigned getValueBitIndex()
const {
1532 assert(hasValue() &&
"Cannot get the value bit index of a constant bit");
1541 unsigned StartIdx, EndIdx;
1551 bool Repl32Coalesced;
1553 BitGroup(
SDValue V,
unsigned R,
unsigned S,
unsigned E)
1554 :
V(
V), RLAmt(
R), StartIdx(S), EndIdx(E), Repl32(
false), Repl32CR(
false),
1555 Repl32Coalesced(
false) {
1556 LLVM_DEBUG(
dbgs() <<
"\tbit group for " <<
V.getNode() <<
" RLAmt = " << R
1557 <<
" [" << S <<
", " << E <<
"]\n");
1563 struct ValueRotInfo {
1565 unsigned RLAmt = std::numeric_limits<unsigned>::max();
1566 unsigned NumGroups = 0;
1567 unsigned FirstGroupStartIdx = std::numeric_limits<unsigned>::max();
1568 bool Repl32 =
false;
1570 ValueRotInfo() =
default;
1578 if (Repl32 <
Other.Repl32)
1580 else if (Repl32 >
Other.Repl32)
1582 else if (NumGroups >
Other.NumGroups)
1584 else if (NumGroups <
Other.NumGroups)
1586 else if (RLAmt == 0 &&
Other.RLAmt != 0)
1588 else if (RLAmt != 0 &&
Other.RLAmt == 0)
1590 else if (FirstGroupStartIdx <
Other.FirstGroupStartIdx)
1596 using ValueBitsMemoizedValue = std::pair<bool, SmallVector<ValueBit, 64>>;
1597 using ValueBitsMemoizer =
1599 ValueBitsMemoizer Memoizer;
1605 std::pair<bool, SmallVector<ValueBit, 64> *> getValueBits(
SDValue V,
1607 auto &ValueEntry = Memoizer[
V];
1609 return std::make_pair(ValueEntry->first, &ValueEntry->second);
1610 ValueEntry.reset(
new ValueBitsMemoizedValue());
1611 bool &Interesting = ValueEntry->first;
1613 Bits.resize(NumBits);
1615 switch (
V.getOpcode()) {
1618 if (isa<ConstantSDNode>(
V.getOperand(1))) {
1620 unsigned RotAmt =
V.getConstantOperandVal(1) & (NumBits - 1);
1622 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1624 for (
unsigned i = 0; i < NumBits; ++i)
1625 Bits[i] = LHSBits[i < RotAmt ? i + (NumBits - RotAmt) : i - RotAmt];
1627 return std::make_pair(Interesting =
true, &Bits);
1632 if (isa<ConstantSDNode>(
V.getOperand(1))) {
1634 unsigned ShiftAmt =
V.getConstantOperandVal(1) & ((NumBits << 1) - 1);
1636 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1638 if (ShiftAmt >= NumBits) {
1639 for (
unsigned i = 0; i < NumBits; ++i)
1640 Bits[i] = ValueBit(ValueBit::ConstZero);
1642 for (
unsigned i = ShiftAmt; i < NumBits; ++i)
1643 Bits[i] = LHSBits[i - ShiftAmt];
1644 for (
unsigned i = 0; i < ShiftAmt; ++i)
1645 Bits[i] = ValueBit(ValueBit::ConstZero);
1648 return std::make_pair(Interesting =
true, &Bits);
1653 if (isa<ConstantSDNode>(
V.getOperand(1))) {
1655 unsigned ShiftAmt =
V.getConstantOperandVal(1) & ((NumBits << 1) - 1);
1657 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1659 if (ShiftAmt >= NumBits) {
1660 for (
unsigned i = 0; i < NumBits; ++i)
1661 Bits[i] = ValueBit(ValueBit::ConstZero);
1663 for (
unsigned i = 0; i < NumBits - ShiftAmt; ++i)
1664 Bits[i] = LHSBits[i + ShiftAmt];
1665 for (
unsigned i = NumBits - ShiftAmt; i < NumBits; ++i)
1666 Bits[i] = ValueBit(ValueBit::ConstZero);
1669 return std::make_pair(Interesting =
true, &Bits);
1673 if (isa<ConstantSDNode>(
V.getOperand(1))) {
1681 std::tie(Interesting, LHSBits) = getValueBits(
V.getOperand(0), NumBits);
1683 for (
unsigned i = 0; i < NumBits; ++i)
1684 if (((Mask >> i) & 1) == 1)
1685 Bits[i] = (*LHSBits)[i];
1689 if ((*LHSBits)[i].
isZero())
1690 Bits[i] = (*LHSBits)[i];
1692 Bits[i] = ValueBit(ValueBit::ConstZero);
1695 return std::make_pair(Interesting, &Bits);
1699 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1700 const auto &RHSBits = *getValueBits(
V.getOperand(1), NumBits).second;
1702 bool AllDisjoint =
true;
1704 unsigned LastIdx = 0;
1705 for (
unsigned i = 0; i < NumBits; ++i) {
1713 if (LHSBits[i].hasValue() && LHSBits[i].getValue() == LastVal &&
1714 LHSBits[i].getValueBitIndex() == LastIdx + 1)
1715 Bits[i] = LHSBits[i];
1716 else if (RHSBits[i].hasValue() && RHSBits[i].getValue() == LastVal &&
1717 RHSBits[i].getValueBitIndex() == LastIdx + 1)
1718 Bits[i] = RHSBits[i];
1720 Bits[i] = ValueBit(ValueBit::ConstZero);
1722 else if (LHSBits[i].
isZero())
1723 Bits[i] = RHSBits[i];
1724 else if (RHSBits[i].
isZero())
1725 Bits[i] = LHSBits[i];
1727 AllDisjoint =
false;
1731 if (Bits[i].hasValue()) {
1732 LastVal =
Bits[i].getValue();
1733 LastIdx =
Bits[i].getValueBitIndex();
1736 if (LastVal) LastVal =
SDValue();
1744 return std::make_pair(Interesting =
true, &Bits);
1748 if (
V.getValueType() != MVT::i64 ||
1749 V.getOperand(0).getValueType() != MVT::i32)
1753 const unsigned NumOperandBits = 32;
1754 std::tie(Interesting, LHSBits) = getValueBits(
V.getOperand(0),
1757 for (
unsigned i = 0; i < NumOperandBits; ++i)
1758 Bits[i] = (*LHSBits)[i];
1760 for (
unsigned i = NumOperandBits; i < NumBits; ++i)
1761 Bits[i] = ValueBit(ValueBit::ConstZero);
1763 return std::make_pair(Interesting, &Bits);
1767 EVT ToType =
V.getValueType();
1769 if (FromType != MVT::i64 || ToType != MVT::i32)
1771 const unsigned NumAllBits =
FromType.getSizeInBits();
1773 std::tie(Interesting, InBits) = getValueBits(
V.getOperand(0),
1779 bool UseUpper32bit =
false;
1780 for (
unsigned i = 0; i < NumValidBits; ++i)
1781 if ((*InBits)[i].hasValue() && (*InBits)[i].getValueBitIndex() >= 32) {
1782 UseUpper32bit =
true;
1788 for (
unsigned i = 0; i < NumValidBits; ++i)
1789 Bits[i] = (*InBits)[i];
1791 return std::make_pair(Interesting, &Bits);
1797 std::tie(Interesting, LHSBits) = getValueBits(
V.getOperand(0),
1800 EVT FromType = cast<VTSDNode>(
V.getOperand(1))->getVT();
1801 const unsigned NumValidBits =
FromType.getSizeInBits();
1802 for (
unsigned i = 0; i < NumValidBits; ++i)
1803 Bits[i] = (*LHSBits)[i];
1807 for (
unsigned i = NumValidBits; i < NumBits; ++i)
1808 Bits[i] = (*LHSBits)[i].hasValue()
1809 ? ValueBit((*LHSBits)[i].getValue(),
1810 (*LHSBits)[i].getValueBitIndex(),
1811 ValueBit::VariableKnownToBeZero)
1812 : ValueBit(ValueBit::ConstZero);
1814 return std::make_pair(Interesting, &Bits);
1819 EVT VT =
LD->getMemoryVT();
1822 for (
unsigned i = 0; i < NumValidBits; ++i)
1823 Bits[i] = ValueBit(V, i);
1826 for (
unsigned i = NumValidBits; i < NumBits; ++i)
1827 Bits[i] = ValueBit(V, i, ValueBit::VariableKnownToBeZero);
1831 return std::make_pair(Interesting =
false, &Bits);
1836 for (
unsigned i = 0; i < NumBits; ++i)
1837 Bits[i] = ValueBit(V, i);
1839 return std::make_pair(Interesting =
false, &Bits);
1844 void computeRotationAmounts() {
1846 RLAmt.resize(
Bits.size());
1847 for (
unsigned i = 0; i <
Bits.size(); ++i)
1848 if (Bits[i].hasValue()) {
1849 unsigned VBI =
Bits[i].getValueBitIndex();
1853 RLAmt[i] =
Bits.size() - (VBI - i);
1854 }
else if (Bits[i].
isZero()) {
1856 RLAmt[i] = UINT32_MAX;
1865 void collectBitGroups(
bool LateMask) {
1868 unsigned LastRLAmt = RLAmt[0];
1870 unsigned LastGroupStartIdx = 0;
1871 bool IsGroupOfZeros = !
Bits[LastGroupStartIdx].hasValue();
1872 for (
unsigned i = 1; i <
Bits.size(); ++i) {
1873 unsigned ThisRLAmt = RLAmt[i];
1875 if (LateMask && !ThisValue) {
1876 ThisValue = LastValue;
1877 ThisRLAmt = LastRLAmt;
1880 if (BitGroups.empty())
1881 LastGroupStartIdx = 0;
1888 if (IsGroupOfZeros && Bits[i].
isZero())
1893 if (ThisRLAmt == LastRLAmt && ThisValue == LastValue)
1896 if (!(IsGroupOfZeros && ThisValue && !Bits[i].
isZero()))
1900 BitGroups.push_back(BitGroup(LastValue, LastRLAmt, LastGroupStartIdx,
1902 LastRLAmt = ThisRLAmt;
1903 LastValue = ThisValue;
1904 LastGroupStartIdx = i;
1905 IsGroupOfZeros = !
Bits[LastGroupStartIdx].hasValue();
1908 BitGroups.push_back(BitGroup(LastValue, LastRLAmt, LastGroupStartIdx,
1911 if (BitGroups.empty())
1915 if (BitGroups.size() > 1) {
1919 if (BitGroups[0].StartIdx == 0 &&
1920 BitGroups[BitGroups.size()-1].EndIdx ==
Bits.size()-1 &&
1921 BitGroups[0].V == BitGroups[BitGroups.size()-1].V &&
1922 BitGroups[0].RLAmt == BitGroups[BitGroups.size()-1].RLAmt) {
1923 LLVM_DEBUG(
dbgs() <<
"\tcombining final bit group with initial one\n");
1924 BitGroups[BitGroups.size()-1].EndIdx = BitGroups[0].EndIdx;
1925 BitGroups.erase(BitGroups.begin());
1935 void collectValueRotInfo() {
1938 for (
auto &BG : BitGroups) {
1939 unsigned RLAmtKey = BG.RLAmt + (BG.Repl32 ? 64 : 0);
1940 ValueRotInfo &VRI = ValueRots[std::make_pair(BG.V, RLAmtKey)];
1942 VRI.RLAmt = BG.RLAmt;
1943 VRI.Repl32 = BG.Repl32;
1945 VRI.FirstGroupStartIdx = std::min(VRI.FirstGroupStartIdx, BG.StartIdx);
1950 ValueRotsVec.clear();
1951 for (
auto &
I : ValueRots) {
1952 ValueRotsVec.push_back(
I.second);
1965 void assignRepl32BitGroups() {
1976 auto IsAllLow32 = [
this](BitGroup & BG) {
1977 if (BG.StartIdx <= BG.EndIdx) {
1978 for (
unsigned i = BG.StartIdx; i <= BG.EndIdx; ++i) {
1979 if (!Bits[i].hasValue())
1981 if (Bits[i].getValueBitIndex() >= 32)
1985 for (
unsigned i = BG.StartIdx; i <
Bits.size(); ++i) {
1986 if (!Bits[i].hasValue())
1988 if (Bits[i].getValueBitIndex() >= 32)
1991 for (
unsigned i = 0; i <= BG.EndIdx; ++i) {
1992 if (!Bits[i].hasValue())
1994 if (Bits[i].getValueBitIndex() >= 32)
2002 for (
auto &BG : BitGroups) {
2006 if (BG.RLAmt == 0) {
2007 auto PotentiallyMerged = [
this](BitGroup & BG) {
2008 for (
auto &BG2 : BitGroups)
2009 if (&BG != &BG2 && BG.V == BG2.V &&
2010 (BG2.RLAmt == 0 || BG2.RLAmt == 32))
2014 if (!PotentiallyMerged(BG))
2017 if (BG.StartIdx < 32 && BG.EndIdx < 32) {
2018 if (IsAllLow32(BG)) {
2019 if (BG.RLAmt >= 32) {
2027 << BG.V.getNode() <<
" RLAmt = " << BG.RLAmt <<
" ["
2028 << BG.StartIdx <<
", " << BG.EndIdx <<
"]\n");
2034 for (
auto I = BitGroups.begin();
I != BitGroups.end();) {
2037 auto IP = (
I == BitGroups.begin()) ?
2038 std::prev(BitGroups.end()) : std::prev(
I);
2039 if (
I->Repl32 && IP->Repl32 &&
I->V == IP->V &&
I->RLAmt == IP->RLAmt &&
2040 I->StartIdx == (IP->EndIdx + 1) % 64 &&
I != IP) {
2042 LLVM_DEBUG(
dbgs() <<
"\tcombining 32-bit replicated bit group for "
2043 <<
I->V.getNode() <<
" RLAmt = " <<
I->RLAmt <<
" ["
2044 <<
I->StartIdx <<
", " <<
I->EndIdx
2045 <<
"] with group with range [" << IP->StartIdx <<
", "
2046 << IP->EndIdx <<
"]\n");
2048 IP->EndIdx =
I->EndIdx;
2049 IP->Repl32CR = IP->Repl32CR ||
I->Repl32CR;
2050 IP->Repl32Coalesced =
true;
2051 I = BitGroups.erase(
I);
2060 if (
I->StartIdx == 32 &&
I->EndIdx == 63) {
2061 assert(std::next(
I) == BitGroups.end() &&
2062 "bit group ends at index 63 but there is another?");
2063 auto IN = BitGroups.begin();
2065 if (IP->Repl32 && IN->Repl32 &&
I->V == IP->V &&
I->V == IN->V &&
2066 (
I->RLAmt % 32) == IP->RLAmt && (
I->RLAmt % 32) == IN->RLAmt &&
2067 IP->EndIdx == 31 && IN->StartIdx == 0 &&
I != IP &&
2071 <<
" RLAmt = " <<
I->RLAmt <<
" [" <<
I->StartIdx
2072 <<
", " <<
I->EndIdx
2073 <<
"] with 32-bit replicated groups with ranges ["
2074 << IP->StartIdx <<
", " << IP->EndIdx <<
"] and ["
2075 << IN->StartIdx <<
", " << IN->EndIdx <<
"]\n");
2083 IP->Repl32CR = IP->Repl32CR ||
I->RLAmt >= 32;
2084 IP->Repl32Coalesced =
true;
2085 I = BitGroups.erase(
I);
2090 IP->EndIdx = IN->EndIdx;
2091 IP->Repl32CR = IP->Repl32CR || IN->Repl32CR ||
I->RLAmt >= 32;
2092 IP->Repl32Coalesced =
true;
2093 I = BitGroups.erase(
I);
2094 BitGroups.erase(BitGroups.begin());
2109 return CurDAG->getTargetConstant(Imm, dl, MVT::i32);
2114 for (
unsigned i = 0; i <
Bits.size(); ++i) {
2115 if (Bits[i].hasValue())
2117 Mask |= (UINT64_C(1) << i);
2128 if (
V.getValueSizeInBits() == 64)
2131 assert(
V.getValueSizeInBits() == 32);
2132 SDValue SubRegIdx = CurDAG->getTargetConstant(PPC::sub_32, dl, MVT::i32);
2133 SDValue ImDef =
SDValue(CurDAG->getMachineNode(PPC::IMPLICIT_DEF, dl,
2135 SDValue ExtVal =
SDValue(CurDAG->getMachineNode(PPC::INSERT_SUBREG, dl,
2142 if (
V.getValueSizeInBits() == 32)
2145 assert(
V.getValueSizeInBits() == 64);
2146 SDValue SubRegIdx = CurDAG->getTargetConstant(PPC::sub_32, dl, MVT::i32);
2147 SDValue SubVal =
SDValue(CurDAG->getMachineNode(PPC::EXTRACT_SUBREG, dl,
2148 MVT::i32, V, SubRegIdx), 0);
2155 void SelectAndParts32(
const SDLoc &dl,
SDValue &Res,
unsigned *InstCnt) {
2159 for (ValueRotInfo &VRI : ValueRotsVec) {
2161 for (
unsigned i = 0; i <
Bits.size(); ++i) {
2162 if (!Bits[i].hasValue() || Bits[i].getValue() != VRI.V)
2164 if (RLAmt[i] != VRI.RLAmt)
2170 unsigned ANDIMask = (
Mask & UINT16_MAX), ANDISMask = Mask >> 16;
2171 assert((ANDIMask != 0 || ANDISMask != 0) &&
2172 "No set bits in mask for value bit groups");
2173 bool NeedsRotate = VRI.RLAmt != 0;
2189 unsigned NumAndInsts = (
unsigned) NeedsRotate +
2190 (
unsigned) (ANDIMask != 0) +
2191 (
unsigned) (ANDISMask != 0) +
2192 (
unsigned) (ANDIMask != 0 && ANDISMask != 0) +
2193 (
unsigned) (
bool) Res;
2195 LLVM_DEBUG(
dbgs() <<
"\t\trotation groups for " << VRI.V.getNode()
2196 <<
" RL: " << VRI.RLAmt <<
":"
2197 <<
"\n\t\t\tisel using masking: " << NumAndInsts
2198 <<
" using rotates: " << VRI.NumGroups <<
"\n");
2200 if (NumAndInsts >= VRI.NumGroups)
2205 if (InstCnt) *InstCnt += NumAndInsts;
2210 { TruncateToInt32(VRI.V, dl), getI32Imm(VRI.RLAmt, dl),
2211 getI32Imm(0, dl), getI32Imm(31, dl) };
2212 VRot =
SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32,
2215 VRot = TruncateToInt32(VRI.V, dl);
2220 ANDIVal =
SDValue(CurDAG->getMachineNode(PPC::ANDI_rec, dl, MVT::i32,
2221 VRot, getI32Imm(ANDIMask, dl)),
2225 SDValue(CurDAG->getMachineNode(PPC::ANDIS_rec, dl, MVT::i32, VRot,
2226 getI32Imm(ANDISMask, dl)),
2231 TotalVal = ANDISVal;
2235 TotalVal =
SDValue(CurDAG->getMachineNode(PPC::OR, dl, MVT::i32,
2236 ANDIVal, ANDISVal), 0);
2241 Res =
SDValue(CurDAG->getMachineNode(PPC::OR, dl, MVT::i32,
2246 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
2247 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt;
2253 SDNode *Select32(
SDNode *
N,
bool LateMask,
unsigned *InstCnt) {
2257 if (InstCnt) *InstCnt = 0;
2260 SelectAndParts32(dl, Res, InstCnt);
2265 if ((!NeedMask || LateMask) && !Res) {
2266 ValueRotInfo &VRI = ValueRotsVec[0];
2268 if (InstCnt) *InstCnt += 1;
2270 { TruncateToInt32(VRI.V, dl), getI32Imm(VRI.RLAmt, dl),
2271 getI32Imm(0, dl), getI32Imm(31, dl) };
2272 Res =
SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32, Ops),
2275 Res = TruncateToInt32(VRI.V, dl);
2279 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
2280 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt;
2284 if (InstCnt) *InstCnt += BitGroups.size();
2287 for (
auto &BG : BitGroups) {
2290 { TruncateToInt32(BG.V, dl), getI32Imm(BG.RLAmt, dl),
2291 getI32Imm(
Bits.size() - BG.EndIdx - 1, dl),
2292 getI32Imm(
Bits.size() - BG.StartIdx - 1, dl) };
2293 Res =
SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32, Ops), 0);
2296 { Res, TruncateToInt32(BG.V, dl), getI32Imm(BG.RLAmt, dl),
2297 getI32Imm(
Bits.size() - BG.EndIdx - 1, dl),
2298 getI32Imm(
Bits.size() - BG.StartIdx - 1, dl) };
2299 Res =
SDValue(CurDAG->getMachineNode(PPC::RLWIMI, dl, MVT::i32, Ops), 0);
2306 unsigned ANDIMask = (
Mask & UINT16_MAX), ANDISMask = Mask >> 16;
2307 assert((ANDIMask != 0 || ANDISMask != 0) &&
2308 "No set bits in zeros mask?");
2310 if (InstCnt) *InstCnt += (
unsigned) (ANDIMask != 0) +
2312 (
unsigned) (ANDIMask != 0 && ANDISMask != 0);
2316 ANDIVal =
SDValue(CurDAG->getMachineNode(PPC::ANDI_rec, dl, MVT::i32,
2317 Res, getI32Imm(ANDIMask, dl)),
2321 SDValue(CurDAG->getMachineNode(PPC::ANDIS_rec, dl, MVT::i32, Res,
2322 getI32Imm(ANDISMask, dl)),
2330 Res =
SDValue(CurDAG->getMachineNode(PPC::OR, dl, MVT::i32,
2331 ANDIVal, ANDISVal), 0);
2337 unsigned SelectRotMask64Count(
unsigned RLAmt,
bool Repl32,
2338 unsigned MaskStart,
unsigned MaskEnd,
2342 unsigned InstMaskStart = 64 - MaskEnd - 1,
2343 InstMaskEnd = 64 - MaskStart - 1;
2348 if ((!IsIns && (InstMaskEnd == 63 || InstMaskStart == 0)) ||
2349 InstMaskEnd == 63 - RLAmt)
2358 bool Repl32,
unsigned MaskStart,
unsigned MaskEnd,
2359 unsigned *InstCnt =
nullptr) {
2362 unsigned InstMaskStart = 64 - MaskEnd - 1,
2363 InstMaskEnd = 64 - MaskStart - 1;
2365 if (InstCnt) *InstCnt += 1;
2371 assert(InstMaskStart >= 32 &&
"Mask cannot start out of range");
2372 assert(InstMaskEnd >= 32 &&
"Mask cannot end out of range");
2374 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2375 getI32Imm(InstMaskStart - 32, dl), getI32Imm(InstMaskEnd - 32, dl) };
2376 return SDValue(CurDAG->getMachineNode(PPC::RLWINM8, dl, MVT::i64,
2380 if (InstMaskEnd == 63) {
2382 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2383 getI32Imm(InstMaskStart, dl) };
2384 return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, Ops), 0);
2387 if (InstMaskStart == 0) {
2389 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2390 getI32Imm(InstMaskEnd, dl) };
2391 return SDValue(CurDAG->getMachineNode(PPC::RLDICR, dl, MVT::i64, Ops), 0);
2394 if (InstMaskEnd == 63 - RLAmt) {
2396 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2397 getI32Imm(InstMaskStart, dl) };
2398 return SDValue(CurDAG->getMachineNode(PPC::RLDIC, dl, MVT::i64, Ops), 0);
2407 if (InstCnt) *InstCnt += 1;
2410 unsigned RLAmt2 = MaskStart;
2413 unsigned RLAmt1 = (64 + RLAmt - RLAmt2) % 64;
2415 V = SelectRotMask64(V, dl, RLAmt1,
false, 0, 63);
2416 return SelectRotMask64(V, dl, RLAmt2,
false, MaskStart, MaskEnd);
2422 unsigned RLAmt,
bool Repl32,
unsigned MaskStart,
2423 unsigned MaskEnd,
unsigned *InstCnt =
nullptr) {
2426 unsigned InstMaskStart = 64 - MaskEnd - 1,
2427 InstMaskEnd = 64 - MaskStart - 1;
2429 if (InstCnt) *InstCnt += 1;
2435 assert(InstMaskStart >= 32 &&
"Mask cannot start out of range");
2436 assert(InstMaskEnd >= 32 &&
"Mask cannot end out of range");
2438 { ExtendToInt64(
Base, dl), ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2439 getI32Imm(InstMaskStart - 32, dl), getI32Imm(InstMaskEnd - 32, dl) };
2440 return SDValue(CurDAG->getMachineNode(PPC::RLWIMI8, dl, MVT::i64,
2444 if (InstMaskEnd == 63 - RLAmt) {
2446 { ExtendToInt64(
Base, dl), ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2447 getI32Imm(InstMaskStart, dl) };
2448 return SDValue(CurDAG->getMachineNode(PPC::RLDIMI, dl, MVT::i64, Ops), 0);
2457 if (InstCnt) *InstCnt += 1;
2460 unsigned RLAmt2 = MaskStart;
2463 unsigned RLAmt1 = (64 + RLAmt - RLAmt2) % 64;
2465 V = SelectRotMask64(V, dl, RLAmt1,
false, 0, 63);
2466 return SelectRotMaskIns64(
Base, V, dl, RLAmt2,
false, MaskStart, MaskEnd);
2469 void SelectAndParts64(
const SDLoc &dl,
SDValue &Res,
unsigned *InstCnt) {
2482 for (ValueRotInfo &VRI : ValueRotsVec) {
2490 auto MatchingBG = [VRI](
const BitGroup &BG) {
2494 unsigned EffRLAmt = BG.RLAmt;
2495 if (!VRI.Repl32 && BG.Repl32) {
2496 if (BG.StartIdx < 32 && BG.EndIdx < 32 && BG.StartIdx <= BG.EndIdx &&
2497 !BG.Repl32Coalesced) {
2503 }
else if (VRI.Repl32 != BG.Repl32) {
2507 return VRI.RLAmt == EffRLAmt;
2510 for (
auto &BG : BitGroups) {
2511 if (!MatchingBG(BG))
2514 if (BG.StartIdx <= BG.EndIdx) {
2515 for (
unsigned i = BG.StartIdx; i <= BG.EndIdx; ++i)
2516 Mask |= (UINT64_C(1) << i);
2518 for (
unsigned i = BG.StartIdx; i <
Bits.size(); ++i)
2519 Mask |= (UINT64_C(1) << i);
2520 for (
unsigned i = 0; i <= BG.EndIdx; ++i)
2521 Mask |= (UINT64_C(1) << i);
2528 bool Use32BitInsts = isUInt<32>(Mask);
2530 unsigned ANDIMask = (
Mask & UINT16_MAX),
2531 ANDISMask = (Mask >> 16) & UINT16_MAX;
2533 bool NeedsRotate = VRI.RLAmt || (VRI.Repl32 && !isUInt<32>(Mask));
2535 unsigned NumAndInsts = (
unsigned) NeedsRotate +
2536 (
unsigned) (
bool) Res;
2537 unsigned NumOfSelectInsts = 0;
2539 assert(NumOfSelectInsts > 0 &&
"Failed to select an i64 constant.");
2542 (
unsigned) (ANDIMask != 0 && ANDISMask != 0);
2544 NumAndInsts += NumOfSelectInsts + 1;
2546 unsigned NumRLInsts = 0;
2547 bool FirstBG =
true;
2548 bool MoreBG =
false;
2549 for (
auto &BG : BitGroups) {
2550 if (!MatchingBG(BG)) {
2555 SelectRotMask64Count(BG.RLAmt, BG.Repl32, BG.StartIdx, BG.EndIdx,
2560 LLVM_DEBUG(
dbgs() <<
"\t\trotation groups for " << VRI.V.getNode()
2561 <<
" RL: " << VRI.RLAmt << (VRI.Repl32 ?
" (32):" :
":")
2562 <<
"\n\t\t\tisel using masking: " << NumAndInsts
2563 <<
" using rotates: " << NumRLInsts <<
"\n");
2569 if (NumAndInsts > NumRLInsts)
2574 if ((Use32BitInsts || MoreBG) && NumAndInsts == NumRLInsts)
2579 if (InstCnt) *InstCnt += NumAndInsts;
2586 if (VRI.RLAmt || (VRI.Repl32 && !isUInt<32>(Mask)))
2587 VRot = SelectRotMask64(VRI.V, dl, VRI.RLAmt, VRI.Repl32,
2588 VRI.Repl32 ? 31 : 0, VRI.Repl32 ? 30 : 63);
2593 if (Use32BitInsts) {
2594 assert((ANDIMask != 0 || ANDISMask != 0) &&
2595 "No set bits in mask when using 32-bit ands for 64-bit value");
2599 ANDIVal =
SDValue(CurDAG->getMachineNode(PPC::ANDI8_rec, dl, MVT::i64,
2600 ExtendToInt64(VRot, dl),
2601 getI32Imm(ANDIMask, dl)),
2605 SDValue(CurDAG->getMachineNode(PPC::ANDIS8_rec, dl, MVT::i64,
2606 ExtendToInt64(VRot, dl),
2607 getI32Imm(ANDISMask, dl)),
2611 TotalVal = ANDISVal;
2615 TotalVal =
SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64,
2616 ExtendToInt64(ANDIVal, dl), ANDISVal), 0);
2620 SDValue(CurDAG->getMachineNode(PPC::AND8, dl, MVT::i64,
2621 ExtendToInt64(VRot, dl), TotalVal),
2628 Res =
SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64,
2629 ExtendToInt64(Res, dl), TotalVal),
2634 eraseMatchingBitGroups(MatchingBG);
2639 SDNode *Select64(
SDNode *
N,
bool LateMask,
unsigned *InstCnt) {
2643 if (InstCnt) *InstCnt = 0;
2646 SelectAndParts64(dl, Res, InstCnt);
2651 if ((!NeedMask || LateMask) && !Res) {
2655 unsigned MaxGroupsIdx = 0;
2656 if (!ValueRotsVec[0].Repl32) {
2657 for (
unsigned i = 0, ie = ValueRotsVec.size(); i < ie; ++i)
2658 if (ValueRotsVec[i].Repl32) {
2659 if (ValueRotsVec[i].NumGroups > ValueRotsVec[0].NumGroups)
2665 ValueRotInfo &VRI = ValueRotsVec[MaxGroupsIdx];
2666 bool NeedsRotate =
false;
2669 }
else if (VRI.Repl32) {
2670 for (
auto &BG : BitGroups) {
2671 if (BG.V != VRI.V || BG.RLAmt != VRI.RLAmt ||
2672 BG.Repl32 != VRI.Repl32)
2677 if (BG.StartIdx < 32 && BG.EndIdx < 32 && BG.StartIdx < BG.EndIdx)
2686 Res = SelectRotMask64(VRI.V, dl, VRI.RLAmt, VRI.Repl32,
2687 VRI.Repl32 ? 31 : 0, VRI.Repl32 ? 30 : 63,
2694 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
2695 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt &&
2696 BG.Repl32 == VRI.Repl32;
2703 for (
auto I = BitGroups.begin(), IE = BitGroups.end();
I != IE; ++
I) {
2704 if (SelectRotMask64Count(
I->RLAmt,
I->Repl32,
I->StartIdx,
I->EndIdx,
2706 SelectRotMask64Count(
I->RLAmt,
I->Repl32,
I->StartIdx,
I->EndIdx,
2708 if (
I != BitGroups.begin()) {
2711 BitGroups.insert(BitGroups.begin(), BG);
2719 for (
auto &BG : BitGroups) {
2721 Res = SelectRotMask64(BG.V, dl, BG.RLAmt, BG.Repl32, BG.StartIdx,
2722 BG.EndIdx, InstCnt);
2724 Res = SelectRotMaskIns64(Res, BG.V, dl, BG.RLAmt, BG.Repl32,
2725 BG.StartIdx, BG.EndIdx, InstCnt);
2734 bool Use32BitInsts = isUInt<32>(Mask);
2736 unsigned ANDIMask = (
Mask & UINT16_MAX),
2737 ANDISMask = (Mask >> 16) & UINT16_MAX;
2739 if (Use32BitInsts) {
2740 assert((ANDIMask != 0 || ANDISMask != 0) &&
2741 "No set bits in mask when using 32-bit ands for 64-bit value");
2743 if (InstCnt) *InstCnt += (
unsigned) (ANDIMask != 0) +
2745 (
unsigned) (ANDIMask != 0 && ANDISMask != 0);
2749 ANDIVal =
SDValue(CurDAG->getMachineNode(PPC::ANDI8_rec, dl, MVT::i64,
2750 ExtendToInt64(Res, dl),
2751 getI32Imm(ANDIMask, dl)),
2755 SDValue(CurDAG->getMachineNode(PPC::ANDIS8_rec, dl, MVT::i64,
2756 ExtendToInt64(Res, dl),
2757 getI32Imm(ANDISMask, dl)),
2765 Res =
SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64,
2766 ExtendToInt64(ANDIVal, dl), ANDISVal), 0);
2768 unsigned NumOfSelectInsts = 0;
2771 Res =
SDValue(CurDAG->getMachineNode(PPC::AND8, dl, MVT::i64,
2772 ExtendToInt64(Res, dl), MaskVal),
2775 *InstCnt += NumOfSelectInsts + 1;
2784 collectBitGroups(LateMask);
2785 if (BitGroups.empty())
2789 if (
Bits.size() == 64)
2790 assignRepl32BitGroups();
2793 collectValueRotInfo();
2795 if (
Bits.size() == 32) {
2796 return Select32(
N, LateMask, InstCnt);
2798 assert(
Bits.size() == 64 &&
"Not 64 bits here?");
2799 return Select64(
N, LateMask, InstCnt);
2805 void eraseMatchingBitGroups(
function_ref<
bool(
const BitGroup &)>
F) {
2811 bool NeedMask =
false;
2831 getValueBits(
SDValue(
N, 0),
N->getValueType(0).getSizeInBits());
2836 LLVM_DEBUG(
dbgs() <<
"Considering bit-permutation-based instruction"
2837 " selection for: ");
2841 computeRotationAmounts();
2854 unsigned InstCnt = 0, InstCntLateMask = 0;
2857 LLVM_DEBUG(
dbgs() <<
"\t\tisel would use " << InstCnt <<
" instructions\n");
2862 <<
" instructions\n");
2864 if (InstCnt <= InstCntLateMask) {
2874class IntegerCompareEliminator {
2879 enum ExtOrTruncConversion {
Ext, Trunc };
2887 enum SetccInGPROpts { ZExtOrig, ZExtInvert, SExtOrig, SExtInvert };
2897 enum ZeroCompare { GEZExt, GESExt, LEZExt, LESExt };
2904 SDValue addExtOrTrunc(
SDValue NatWidthRes, ExtOrTruncConversion Conv);
2908 int64_t RHSValue,
SDLoc dl);
2910 int64_t RHSValue,
SDLoc dl);
2912 int64_t RHSValue,
SDLoc dl);
2914 int64_t RHSValue,
SDLoc dl);
2919 PPCDAGToDAGISel *Sel) : CurDAG(DAG), S(Sel) {
2922 "Only expecting to use this on 64 bit targets.");
2927 switch (
N->getOpcode()) {
2938 return tryEXTEND(
N);
2942 return tryLogicOpOfCompares(
N);
2953 "Expecting a zero/sign extend node!");
2958 N->getOperand(0).getValueType() == MVT::i1 &&
2960 WideRes = computeLogicOpInGPR(
N->getOperand(0));
2961 else if (
N->getOperand(0).getOpcode() !=
ISD::SETCC)
2965 getSETCCInGPR(
N->getOperand(0),
2967 SetccInGPROpts::SExtOrig : SetccInGPROpts::ZExtOrig);
2974 bool Output32Bit =
N->getValueType(0) == MVT::i32;
2980 if (Input32Bit != Output32Bit)
2981 ConvOp = addExtOrTrunc(WideRes, Input32Bit ? ExtOrTruncConversion::Ext :
2982 ExtOrTruncConversion::Trunc);
2990SDNode *IntegerCompareEliminator::tryLogicOpOfCompares(
SDNode *
N) {
2991 if (
N->getValueType(0) != MVT::i1)
2994 "Expected a logic operation on setcc results.");
2996 if (!LoweredLogical)
3001 unsigned SubRegToExtract = IsBitwiseNegate ? PPC::sub_eq : PPC::sub_gt;
3010 if (IsBitwiseNegate &&
3013 else if (IsBitwiseNegate)
3015 OpToConvToRecForm = LoweredLogical.
getOperand(0);
3019 OpToConvToRecForm = LoweredLogical;
3029 if (NewOpc != -1 && IsBitwiseNegate) {
3032 "Expected a PPC::XORI8 only for bitwise negation.");
3034 std::vector<SDValue> Ops;
3035 for (
int i = 0, e = OpToConvToRecForm.
getNumOperands(); i < e; i++)
3036 Ops.push_back(OpToConvToRecForm.
getOperand(i));
3041 MVT::Glue, Ops), 0);
3043 assert((NewOpc != -1 || !IsBitwiseNegate) &&
3044 "No record form available for AND8/OR8/XOR8?");
3047 dl, MVT::i64, MVT::Glue, LHS, RHS),
3059 MVT::i1, CR0Reg, SRIdxVal,
3072SDValue IntegerCompareEliminator::computeLogicOpInGPR(
SDValue LogicOp) {
3074 "Can only handle logic operations here.");
3076 "Can only handle logic operations on i1 values here.");
3088 unsigned OperandOpcode = Operand.
getOpcode();
3090 return getSETCCInGPR(Operand, SetccInGPROpts::ZExtOrig);
3095 PPC::RLDICL, dl, InVT, InputOp,
3096 S->getI64Imm(0, dl),
3097 S->getI64Imm(63, dl)), 0);
3099 return computeLogicOpInGPR(Operand);
3108 if (!LHS || (!RHS && !IsBitwiseNegation))
3111 NumLogicOpsOnComparison++;
3114 if (
LHS.getValueType() == MVT::i32)
3115 LHS = addExtOrTrunc(LHS, ExtOrTruncConversion::Ext);
3116 if (!IsBitwiseNegation &&
RHS.getValueType() == MVT::i32)
3117 RHS = addExtOrTrunc(RHS, ExtOrTruncConversion::Ext);
3122 case ISD::AND: NewOpc = PPC::AND8;
break;
3123 case ISD::OR: NewOpc = PPC::OR8;
break;
3124 case ISD::XOR: NewOpc = PPC::XOR8;
break;
3127 if (IsBitwiseNegation) {
3128 RHS = S->getI64Imm(1, dl);
3129 NewOpc = PPC::XORI8;
3140SDValue IntegerCompareEliminator::signExtendInputIfNeeded(
SDValue Input) {
3142 "Can only sign-extend 32-bit values here.");
3150 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3152 LoadSDNode *InputLoad = dyn_cast<LoadSDNode>(Input);
3156 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3161 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3164 SignExtensionsAdded++;
3166 MVT::i64, Input), 0);
3173SDValue IntegerCompareEliminator::zeroExtendInputIfNeeded(
SDValue Input) {
3175 "Can only zero-extend 32-bit values here.");
3185 if (IsTruncateOfZExt)
3186 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3190 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3192 LoadSDNode *InputLoad = dyn_cast<LoadSDNode>(Input);
3195 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3199 ZeroExtensionsAdded++;
3201 S->getI64Imm(0, dl),
3202 S->getI64Imm(32, dl)), 0);
3209SDValue IntegerCompareEliminator::addExtOrTrunc(
SDValue NatWidthRes,
3210 ExtOrTruncConversion Conv) {
3211 SDLoc dl(NatWidthRes);
3215 if (Conv == ExtOrTruncConversion::Ext) {
3220 ImDef, NatWidthRes, SubRegIdx), 0);
3223 assert(Conv == ExtOrTruncConversion::Trunc &&
3224 "Unknown convertion between 32 and 64 bit values.");
3230 NatWidthRes, SubRegIdx), 0);
3236IntegerCompareEliminator::getCompoundZeroComparisonInGPR(
SDValue LHS,
SDLoc dl,
3237 ZeroCompare CmpTy) {
3238 EVT InVT =
LHS.getValueType();
3239 bool Is32Bit = InVT == MVT::i32;
3244 case ZeroCompare::GEZExt:
3245 case ZeroCompare::GESExt:
3247 dl, InVT, LHS, LHS), 0);
3249 case ZeroCompare::LEZExt:
3250 case ZeroCompare::LESExt: {
3253 LHS = signExtendInputIfNeeded(LHS);
3258 Neg, S->getI64Imm(1, dl),
3259 S->getI64Imm(63, dl)), 0);
3263 S->getI64Imm(~0ULL, dl)), 0);
3273 (CmpTy == ZeroCompare::GEZExt || CmpTy == ZeroCompare::LEZExt))
3275 ToExtend, S->getI64Imm(1, dl),
3276 S->getI64Imm(63, dl)), 0);
3278 (CmpTy == ZeroCompare::GESExt || CmpTy == ZeroCompare::LESExt))
3280 S->getI64Imm(63, dl)), 0);
3282 assert(Is32Bit &&
"Should have handled the 32-bit sequences above.");
3285 case ZeroCompare::GEZExt: {
3286 SDValue ShiftOps[] = { ToExtend, S->getI32Imm(1, dl), S->getI32Imm(31, dl),
3287 S->getI32Imm(31, dl) };
3291 case ZeroCompare::GESExt:
3293 S->getI32Imm(31, dl)), 0);
3294 case ZeroCompare::LEZExt:
3296 S->getI32Imm(1, dl)), 0);
3297 case ZeroCompare::LESExt:
3299 S->getI32Imm(-1, dl)), 0);
3310IntegerCompareEliminator::get32BitZExtCompare(
SDValue LHS,
SDValue RHS,
3312 int64_t RHSValue,
SDLoc dl) {
3316 bool IsRHSZero = RHSValue == 0;
3317 bool IsRHSOne = RHSValue == 1;
3318 bool IsRHSNegOne = RHSValue == -1LL;
3328 SDValue ShiftOps[] = { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl),
3329 S->getI32Imm(31, dl) };
3340 SDValue ShiftOps[] = { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl),
3341 S->getI32Imm(31, dl) };
3345 S->getI32Imm(1, dl)), 0);
3351 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt);
3357 IsRHSZero = RHSConst && RHSConst->
isZero();
3368 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LEZExt);
3372 LHS = signExtendInputIfNeeded(LHS);
3373 RHS = signExtendInputIfNeeded(RHS);
3378 S->getI64Imm(1, dl), S->getI64Imm(63, dl)),
3382 MVT::i64, Shift, S->getI32Imm(1, dl)), 0);
3390 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt);
3396 LHS = signExtendInputIfNeeded(LHS);
3397 RHS = signExtendInputIfNeeded(RHS);
3401 Neg, S->getI32Imm(1, dl), S->getI32Imm(63, dl)), 0);
3407 IsRHSZero = RHSConst && RHSConst->
isZero();
3419 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LEZExt);
3423 SDValue ShiftOps[] = {
LHS, S->getI32Imm(1, dl), S->getI32Imm(31, dl),
3424 S->getI32Imm(31, dl) };
3432 LHS = signExtendInputIfNeeded(LHS);
3433 RHS = signExtendInputIfNeeded(RHS);
3437 SUBFNode, S->getI64Imm(1, dl),
3438 S->getI64Imm(63, dl)), 0);
3449 LHS = zeroExtendInputIfNeeded(LHS);
3450 RHS = zeroExtendInputIfNeeded(RHS);
3455 Subtract, S->getI64Imm(1, dl),
3456 S->getI64Imm(63, dl)), 0);
3458 S->getI32Imm(1, dl)), 0);
3469 LHS = zeroExtendInputIfNeeded(LHS);
3470 RHS = zeroExtendInputIfNeeded(RHS);
3474 Subtract, S->getI64Imm(1, dl),
3475 S->getI64Imm(63, dl)), 0);
3483IntegerCompareEliminator::get32BitSExtCompare(
SDValue LHS,
SDValue RHS,
3485 int64_t RHSValue,
SDLoc dl) {
3489 bool IsRHSZero = RHSValue == 0;
3490 bool IsRHSOne = RHSValue == 1;
3491 bool IsRHSNegOne = RHSValue == -1LL;
3504 SDValue SHLOps[] = { Cntlzw, S->getI32Imm(27, dl),
3505 S->getI32Imm(5, dl), S->getI32Imm(31, dl) };
3523 { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl), S->getI32Imm(31, dl) };
3528 S->getI32Imm(1, dl)), 0);
3535 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt);
3541 IsRHSZero = RHSConst && RHSConst->
isZero();
3550 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LESExt);
3553 LHS = signExtendInputIfNeeded(LHS);
3554 RHS = signExtendInputIfNeeded(RHS);
3560 SUBFNode, S->getI64Imm(1, dl),
3561 S->getI64Imm(63, dl)), 0);
3563 S->getI32Imm(-1, dl)), 0);
3570 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt);
3575 LHS = signExtendInputIfNeeded(LHS);
3576 RHS = signExtendInputIfNeeded(RHS);
3580 S->getI64Imm(63, dl)), 0);
3586 IsRHSZero = RHSConst && RHSConst->
isZero();
3597 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LESExt);
3601 S->getI32Imm(31, dl)), 0);
3606 LHS = signExtendInputIfNeeded(LHS);
3607 RHS = signExtendInputIfNeeded(RHS);
3611 SUBFNode, S->getI64Imm(63, dl)), 0);
3622 LHS = zeroExtendInputIfNeeded(LHS);
3623 RHS = zeroExtendInputIfNeeded(RHS);
3628 S->getI32Imm(1, dl), S->getI32Imm(63,dl)),
3631 S->getI32Imm(-1, dl)), 0);
3642 LHS = zeroExtendInputIfNeeded(LHS);
3643 RHS = zeroExtendInputIfNeeded(RHS);
3647 Subtract, S->getI64Imm(63, dl)), 0);
3655IntegerCompareEliminator::get64BitZExtCompare(
SDValue LHS,
SDValue RHS,
3657 int64_t RHSValue,
SDLoc dl) {
3661 bool IsRHSZero = RHSValue == 0;
3662 bool IsRHSOne = RHSValue == 1;
3663 bool IsRHSNegOne = RHSValue == -1LL;
3674 S->getI64Imm(58, dl),
3675 S->getI64Imm(63, dl)), 0);
3686 Xor, S->getI32Imm(~0U, dl)), 0);
3696 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt);
3699 IsRHSZero = RHSConst && RHSConst->
isZero();
3708 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LEZExt);
3711 S->getI64Imm(1, dl),
3712 S->getI64Imm(63, dl)), 0);
3715 S->getI64Imm(63, dl)), 0);
3720 ShiftR, ShiftL, SubtractCarry), 0);
3728 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt);
3732 S->getI64Imm(~0ULL, dl)), 0);
3736 S->getI64Imm(1, dl),
3737 S->getI64Imm(63, dl)), 0);
3741 IsRHSZero = RHSConst && RHSConst->
isZero();
3751 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LEZExt);
3754 S->getI64Imm(1, dl),
3755 S->getI64Imm(63, dl)), 0);
3758 LHS, S->getI64Imm(63, dl)), 0);
3761 RHS, S->getI64Imm(1, dl),
3762 S->getI64Imm(63, dl)), 0);
3768 SRDINode, SRADINode, SUBFC8Carry), 0);
3770 ADDE8Node, S->getI64Imm(1, dl)), 0);
3785 LHS, LHS, SUBFC8Carry), 0);
3787 SUBFE8Node, S->getI64Imm(1, dl)), 0);
3802 LHS, LHS, SubtractCarry), 0);
3812IntegerCompareEliminator::get64BitSExtCompare(
SDValue LHS,
SDValue RHS,
3814 int64_t RHSValue,
SDLoc dl) {
3818 bool IsRHSZero = RHSValue == 0;
3819 bool IsRHSOne = RHSValue == 1;
3820 bool IsRHSNegOne = RHSValue == -1LL;
3832 AddInput, S->getI32Imm(~0U, dl)), 0);
3845 Xor, S->getI32Imm(0, dl)), 0);
3847 SC,
SC.getValue(1)), 0);
3855 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt);
3858 IsRHSZero = RHSConst && RHSConst->
isZero();
3867 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LESExt);
3870 S->getI64Imm(63, dl)), 0);
3873 S->getI64Imm(1, dl),
3874 S->getI64Imm(63, dl)), 0);
3880 ShiftR, ShiftL, SubtractCarry), 0);
3889 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt);
3893 S->getI64Imm(-1, dl)), 0);
3897 S->getI64Imm(63, dl)), 0);
3901 IsRHSZero = RHSConst && RHSConst->
isZero();
3911 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LESExt);
3914 S->getI64Imm(63, dl)), 0);
3918 LHS, S->getI64Imm(63, dl)), 0);
3921 RHS, S->getI64Imm(1, dl),
3922 S->getI64Imm(63, dl)), 0);
3928 SRDINode, SRADINode, SUBFC8Carry), 0);
3931 ADDE8Node, S->getI64Imm(1, dl)), 0);
3948 LHS, SubtractCarry), 0);
3950 ExtSub, ExtSub), 0);
3964 LHS, LHS, SubCarry), 0);
3975 "An ISD::SETCC node required here.");
3983 for (
auto *CompareUse :
Compare.getNode()->uses())
3988 OmittedForNonExtendUses++;
3998 SetccInGPROpts ConvOpts) {
4001 "An ISD::SETCC node required here.");
4014 cast<CondCodeSDNode>(
Compare.getOperand(CCOpNum))->get();
4015 EVT InputVT =
LHS.getValueType();
4016 if (InputVT != MVT::i32 && InputVT != MVT::i64)
4019 if (ConvOpts == SetccInGPROpts::ZExtInvert ||
4020 ConvOpts == SetccInGPROpts::SExtInvert)
4023 bool Inputs32Bit = InputVT == MVT::i32;
4028 bool IsSext = ConvOpts == SetccInGPROpts::SExtOrig ||
4029 ConvOpts == SetccInGPROpts::SExtInvert;
4031 if (IsSext && Inputs32Bit)
4032 return get32BitSExtCompare(LHS, RHS,
CC, RHSValue, dl);
4033 else if (Inputs32Bit)
4034 return get32BitZExtCompare(LHS, RHS,
CC, RHSValue, dl);
4036 return get64BitSExtCompare(LHS, RHS,
CC, RHSValue, dl);
4037 return get64BitZExtCompare(LHS, RHS,
CC, RHSValue, dl);
4042bool PPCDAGToDAGISel::tryIntCompareInGPR(
SDNode *
N) {
4043 if (
N->getValueType(0) != MVT::i32 &&
4044 N->getValueType(0) != MVT::i64)
4050 if (
TM.getOptLevel() == CodeGenOptLevel::None || !
TM.isPPC64())
4056 if (!(
CmpInGPR.getNumOccurrences() > 0) && Subtarget->isISA3_1())
4059 switch (
N->getOpcode()) {
4066 IntegerCompareEliminator ICmpElim(CurDAG,
this);
4067 if (
SDNode *New = ICmpElim.Select(
N)) {
4068 ReplaceNode(
N, New);
4076bool PPCDAGToDAGISel::tryBitPermutation(
SDNode *
N) {
4077 if (
N->getValueType(0) != MVT::i32 &&
4078 N->getValueType(0) != MVT::i64)
4084 switch (
N->getOpcode()) {
4089 if (Subtarget->isISA3_1() &&
N->getValueType(0) == MVT::i32 &&
4091 auto &OpRight =
N->getOperand(1);
4101 BitPermutationSelector BPS(CurDAG);
4102 if (
SDNode *New = BPS.Select(
N)) {
4103 ReplaceNode(
N, New);
4120 if (
LHS.getValueType() == MVT::i32) {
4125 if (isUInt<16>(Imm))
4127 getI32Imm(Imm & 0xFFFF, dl)),
4130 if (isInt<16>((
int)Imm))
4132 getI32Imm(Imm & 0xFFFF, dl)),
4145 getI32Imm(Imm >> 16, dl)), 0);
4147 getI32Imm(Imm & 0xFFFF, dl)), 0);
4153 getI32Imm(Imm & 0xFFFF, dl)), 0);
4159 getI32Imm((
int)SImm & 0xFFFF,
4164 }
else if (
LHS.getValueType() == MVT::i64) {
4169 if (isUInt<16>(Imm))
4171 getI32Imm(Imm & 0xFFFF, dl)),
4176 getI32Imm(Imm & 0xFFFF, dl)),
4188 if (isUInt<32>(Imm)) {
4190 getI64Imm(Imm >> 16, dl)), 0);
4192 getI64Imm(Imm & 0xFFFF, dl)),
4200 getI64Imm(Imm & 0xFFFF, dl)), 0);
4206 getI64Imm(SImm & 0xFFFF, dl)),
4210 }
else if (
LHS.getValueType() == MVT::f32) {
4211 if (Subtarget->hasSPE()) {
4216 Opc = PPC::EFSCMPEQ;
4224 Opc = PPC::EFSCMPLT;
4232 Opc = PPC::EFSCMPGT;
4237 }
else if (
LHS.getValueType() == MVT::f64) {
4238 if (Subtarget->hasSPE()) {
4243 Opc = PPC::EFDCMPEQ;
4251 Opc = PPC::EFDCMPLT;
4259 Opc = PPC::EFDCMPGT;
4263 Opc = Subtarget->hasVSX() ? PPC::XSCMPUDP : PPC::FCMPUD;
4265 assert(
LHS.getValueType() == MVT::f128 &&
"Unknown vt!");
4266 assert(Subtarget->hasP9Vector() &&
"XSCMPUQP requires Power9 Vector");
4267 Opc = PPC::XSCMPUQP;
4271 CurDAG->
getMachineNode(Opc, dl, MVT::i32, MVT::Other, LHS, RHS, Chain),
4335 case ISD::SETO: Invert =
true;
return 3;
4352 bool HasVSX,
bool &Swap,
bool &Negate) {
4379 if (VecVT == MVT::v4f32)
4380 return HasVSX ? PPC::XVCMPEQSP : PPC::VCMPEQFP;
4381 else if (VecVT == MVT::v2f64)
4382 return PPC::XVCMPEQDP;
4386 if (VecVT == MVT::v4f32)
4387 return HasVSX ? PPC::XVCMPGTSP : PPC::VCMPGTFP;
4388 else if (VecVT == MVT::v2f64)
4389 return PPC::XVCMPGTDP;
4393 if (VecVT == MVT::v4f32)
4394 return HasVSX ? PPC::XVCMPGESP : PPC::VCMPGEFP;
4395 else if (VecVT == MVT::v2f64)
4396 return PPC::XVCMPGEDP;
4423 if (VecVT == MVT::v16i8)
4424 return PPC::VCMPEQUB;
4425 else if (VecVT == MVT::v8i16)
4426 return PPC::VCMPEQUH;
4427 else if (VecVT == MVT::v4i32)
4428 return PPC::VCMPEQUW;
4429 else if (VecVT == MVT::v2i64)
4430 return PPC::VCMPEQUD;
4431 else if (VecVT == MVT::v1i128)
4432 return PPC::VCMPEQUQ;
4435 if (VecVT == MVT::v16i8)
4436 return PPC::VCMPGTSB;
4437 else if (VecVT == MVT::v8i16)
4438 return PPC::VCMPGTSH;
4439 else if (VecVT == MVT::v4i32)
4440 return PPC::VCMPGTSW;
4441 else if (VecVT == MVT::v2i64)
4442 return PPC::VCMPGTSD;
4443 else if (VecVT == MVT::v1i128)
4444 return PPC::VCMPGTSQ;
4447 if (VecVT == MVT::v16i8)
4448 return PPC::VCMPGTUB;
4449 else if (VecVT == MVT::v8i16)
4450 return PPC::VCMPGTUH;
4451 else if (VecVT == MVT::v4i32)
4452 return PPC::VCMPGTUW;
4453 else if (VecVT == MVT::v2i64)
4454 return PPC::VCMPGTUD;
4455 else if (VecVT == MVT::v1i128)
4456 return PPC::VCMPGTUQ;
4465bool PPCDAGToDAGISel::trySETCC(
SDNode *
N) {
4468 bool IsStrict =
N->isStrictFPOpcode();
4470 cast<CondCodeSDNode>(
N->getOperand(IsStrict ? 3 : 2))->get();
4473 bool isPPC64 = (PtrVT == MVT::i64);
4489 SDValue Ops[] = {
Op, getI32Imm(27, dl), getI32Imm(5, dl),
4490 getI32Imm(31, dl) };
4498 Op, getI32Imm(~0U, dl)), 0);
4503 SDValue Ops[] = {
Op, getI32Imm(1, dl), getI32Imm(31, dl),
4504 getI32Imm(31, dl) };
4512 SDValue Ops[] = {
T, getI32Imm(1, dl), getI32Imm(31, dl),
4513 getI32Imm(31, dl) };
4518 }
else if (Imm == ~0U) {
4525 Op, getI32Imm(1, dl)), 0);
4530 0),
Op.getValue(1));
4536 Op, getI32Imm(~0U, dl));
4543 getI32Imm(1, dl)), 0);
4546 SDValue Ops[] = { AN, getI32Imm(1, dl), getI32Imm(31, dl),
4547 getI32Imm(31, dl) };
4552 SDValue Ops[] = {
Op, getI32Imm(1, dl), getI32Imm(31, dl),
4553 getI32Imm(31, dl) };
4564 if (!IsStrict &&
LHS.getValueType().isVector()) {
4565 if (Subtarget->hasSPE())
4568 EVT VecVT =
LHS.getValueType();
4570 unsigned int VCmpInst =
4578 CurDAG->
SelectNodeTo(
N, Subtarget->hasVSX() ? PPC::XXLNOR : PPC::VNOR,
4587 if (Subtarget->useCRBits())
4592 SDValue CCReg = SelectCC(LHS, RHS,
CC, dl, Chain);
4599 if (Subtarget->hasSPE() &&
LHS.getValueType().isFloatingPoint()) {
4613 SDValue Ops[] = { IntCR, getI32Imm((32 - (3 -
Idx)) & 31, dl),
4614 getI32Imm(31, dl), getI32Imm(31, dl) };
4623 CurDAG->
SelectNodeTo(
N, PPC::XORI, MVT::i32, Tmp, getI32Imm(1, dl));
4629bool PPCDAGToDAGISel::isOffsetMultipleOf(
SDNode *
N,
unsigned Val)
const {
4635 AddrOp =
N->getOperand(1);
4650 if ((SlotAlign % Val) != 0)
4665void PPCDAGToDAGISel::transferMemOperands(
SDNode *
N,
SDNode *Result) {
4672 bool &NeedSwapOps,
bool &IsUnCmp) {
4678 SDValue TrueRes =
N->getOperand(2);
4679 SDValue FalseRes =
N->getOperand(3);
4681 if (!TrueConst || (
N->getSimpleValueType(0) != MVT::i64 &&
4682 N->getSimpleValueType(0) != MVT::i32))
4691 if ((TrueResVal < -1 || TrueResVal > 1) ||
4720 cast<CondCodeSDNode>(SetOrSelCC.
getOperand(InnerIsSel ? 4 : 2))->get();
4725 dyn_cast<ConstantSDNode>(SetOrSelCC.
getOperand(2));
4727 dyn_cast<ConstantSDNode>(SetOrSelCC.
getOperand(3));
4728 if (!SelCCTrueConst || !SelCCFalseConst)
4733 if (SelCCTVal == -1 && SelCCFVal == 1) {
4735 }
else if (SelCCTVal != 1 || SelCCFVal != -1)
4745 bool InnerSwapped =
false;
4746 if (
LHS == InnerRHS &&
RHS == InnerLHS)
4747 InnerSwapped =
true;
4748 else if (
LHS != InnerLHS ||
RHS != InnerRHS)
4759 NeedSwapOps = (InnerCC ==
ISD::SETGT) ? InnerSwapped : !InnerSwapped;
4776 NeedSwapOps = (TrueResVal == 1);
4795 NeedSwapOps = (TrueResVal == -1);
4804 LLVM_DEBUG(
dbgs() <<
"Found a node that can be lowered to a SETB: ");
4814 if (
N.getNumOperands() < 1 || !isa<ConstantSDNode>(
N.getOperand(0)) ||
4817 switch (
N.getConstantOperandVal(0)) {
4818 case Intrinsic::ppc_vsx_xvtdivdp:
4819 case Intrinsic::ppc_vsx_xvtdivsp:
4820 case Intrinsic::ppc_vsx_xvtsqrtdp:
4821 case Intrinsic::ppc_vsx_xvtsqrtsp:
4827bool PPCDAGToDAGISel::tryFoldSWTestBRCC(
SDNode *
N) {
4885bool PPCDAGToDAGISel::trySelectLoopCountIntrinsic(
SDNode *
N) {
4892 if (
LHS.getOpcode() !=
ISD::AND || !isa<ConstantSDNode>(
LHS.getOperand(1)) ||
4897 LHS.getOperand(0).getConstantOperandVal(1) != Intrinsic::loop_decrement)
4900 if (!isa<ConstantSDNode>(RHS))
4904 "Counter decrement comparison is not EQ or NE");
4907 assert(OldDecrement.
hasOneUse() &&
"loop decrement has more than one use!");
4909 SDLoc DecrementLoc(OldDecrement);
4911 SDValue DecrementOps[] = {Subtarget->
isPPC64() ? getI64Imm(1, DecrementLoc)
4912 : getI32Imm(1, DecrementLoc)};
4913 unsigned DecrementOpcode =
4914 Subtarget->
isPPC64() ? PPC::DecreaseCTR8loop : PPC::DecreaseCTRloop;
4916 MVT::i1, DecrementOps);
4918 unsigned Val =
RHS->getAsZExtVal();
4920 unsigned Opcode = IsBranchOnTrue ? PPC::BC : PPC::BCn;
4922 ReplaceUses(
LHS.getValue(0),
LHS.getOperand(1));
4926 ReplaceUses(OldDecrement.
getValue(1), ChainInput);
4930 ChainInput,
N->getOperand(0));
4933 N->getOperand(4), Chain);
4937bool PPCDAGToDAGISel::tryAsSingleRLWINM(
SDNode *
N) {
4945 unsigned SH, MB, ME;
4948 if (isRotateAndMask(Val.
getNode(), Imm,
false, SH, MB, ME)) {
4950 SDValue Ops[] = {Val, getI32Imm(SH, dl), getI32Imm(MB, dl),
4959 SDValue Ops[] = {Val, getI32Imm(0, dl), getI32Imm(MB, dl),
4967 ReplaceUses(
SDValue(
N, 0),
N->getOperand(1));
4974bool PPCDAGToDAGISel::tryAsSingleRLWINM8(
SDNode *
N) {
4991 SDValue Ops[] = {
N->getOperand(0), getI64Imm(0, dl), getI64Imm(MB - 32, dl),
4992 getI64Imm(ME - 32, dl)};
5000bool PPCDAGToDAGISel::tryAsPairOfRLDICL(
SDNode *
N) {
5008 if (isUInt<16>(Imm64))
5020 if (NumOfLeadingZeros != 0)
5021 Imm64 |= maskLeadingOnes<uint64_t>(NumOfLeadingZeros);
5033 unsigned OnesOnLeft = ME + 1;
5034 unsigned ZerosInBetween = (MB - ME + 63) & 63;
5038 getI64Imm(OnesOnLeft, Loc),
5039 getI64Imm(ZerosInBetween, Loc)),
5048 SDValue Ops[] = {Val, getI64Imm(64 - OnesOnLeft, Loc),
5049 getI64Imm(NumOfLeadingZeros, Loc)};
5054bool PPCDAGToDAGISel::tryAsSingleRLWIMI(
SDNode *
N) {
5081 if (
isRunOfOnes(~(Imm ^ Imm2), MB, ME) && !(~Imm & Imm2)) {
5084 getI32Imm(MB, dl), getI32Imm(ME, dl)};
5085 ReplaceNode(
N, CurDAG->
getMachineNode(PPC::RLWIMI, dl, MVT::i32, Ops));
5092bool PPCDAGToDAGISel::tryAsSingleRLDCL(
SDNode *
N) {
5121bool PPCDAGToDAGISel::tryAsSingleRLDICL(
SDNode *
N) {
5140 auto ImDef = CurDAG->
getMachineNode(PPC::IMPLICIT_DEF, dl, ResultType);
5158 assert(Imm < 64 &&
"Illegal shift amount");
5163 SDValue Ops[] = {Val, getI32Imm(SH, dl), getI32Imm(MB, dl)};
5168bool PPCDAGToDAGISel::tryAsSingleRLDICR(
SDNode *
N) {
5181 SDValue Ops[] = {
N->getOperand(0), getI32Imm(SH, dl), getI32Imm(MB, dl)};
5186bool PPCDAGToDAGISel::tryAsSingleRLDIMI(
SDNode *
N) {
5200 unsigned SH = 63 - ME;
5206 getI32Imm(SH, Dl), getI32Imm(MB, Dl)};
5213void PPCDAGToDAGISel::Select(
SDNode *
N) {
5215 if (
N->isMachineOpcode()) {
5228 if (tryBitPermutation(
N))
5232 if (tryIntCompareInGPR(
N))
5235 switch (
N->getOpcode()) {
5239 if (
N->getValueType(0) == MVT::i64) {
5246 auto IntrinsicID =
N->getConstantOperandVal(1);
5247 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
5248 IntrinsicID != Intrinsic::ppc_trapd &&
5249 IntrinsicID != Intrinsic::ppc_trap)
5251 unsigned Opcode = (IntrinsicID == Intrinsic::ppc_tdw ||
5252 IntrinsicID == Intrinsic::ppc_trapd)
5257 if (IntrinsicID == Intrinsic::ppc_tdw ||
5258 IntrinsicID == Intrinsic::ppc_tw) {
5259 SDValue Ops[] = {
N->getOperand(4),
N->getOperand(2),
N->getOperand(3)};
5260 int16_t SImmOperand2;
5261 int16_t SImmOperand3;
5262 int16_t SImmOperand4;
5263 bool isOperand2IntS16Immediate =
5265 bool isOperand3IntS16Immediate =
5270 if (isOperand2IntS16Immediate == isOperand3IntS16Immediate)
5271 Opcode = IntrinsicID == Intrinsic::ppc_tdw ? PPC::TD : PPC::TW;
5272 else if (isOperand3IntS16Immediate)
5274 Ops[2] = getI32Imm(
int(SImmOperand3) & 0xFFFF, dl);
5277 bool isOperand4IntS16Immediate =
5279 (void)isOperand4IntS16Immediate;
5280 assert(isOperand4IntS16Immediate &&
5281 "The 4th operand is not an Immediate");
5283 int16_t TO = int(SImmOperand4) & 0x1F;
5285 if ((TO & 0x1) != ((TO & 0x2) >> 1))
5286 TO = (TO & 0x1) ? TO + 1 : TO - 1;
5288 if ((TO & 0x8) != ((TO & 0x10) >> 1))
5289 TO = (TO & 0x8) ? TO + 8 : TO - 8;
5290 Ops[0] = getI32Imm(TO, dl);
5291 Ops[1] =
N->getOperand(3);
5292 Ops[2] = getI32Imm(
int(SImmOperand2) & 0xFFFF, dl);
5294 OpsWithMD = {Ops[0], Ops[1], Ops[2]};
5297 OpsWithMD = {getI32Imm(24, dl),
N->getOperand(2), getI32Imm(0, dl)};
5301 if (
N->getNumOperands() > MDIndex) {
5302 SDValue MDV =
N->getOperand(MDIndex);
5303 const MDNode *MD = cast<MDNodeSDNode>(MDV)->getMD();
5306 MD->
getOperand(0))->getString().equals(
"ppc-trap-reason"))
5307 &&
"Unsupported annotation data type!");
5310 "Invalid data type for annotation ppc-trap-reason!");
5312 getI32Imm(std::stoi(cast<MDString>(
5313 MD->
getOperand(i))->getString().str()), dl));
5328 auto IntID =
N->getConstantOperandVal(0);
5329 if (IntID == Intrinsic::ppc_fsels) {
5330 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2),
N->getOperand(3)};
5335 if (IntID == Intrinsic::ppc_bcdadd_p || IntID == Intrinsic::ppc_bcdsub_p) {
5336 auto Pred =
N->getConstantOperandVal(1);
5338 IntID == Intrinsic::ppc_bcdadd_p ? PPC::BCDADD_rec : PPC::BCDSUB_rec;
5340 unsigned ShiftVal = 0;
5379 EVT VTs[] = {MVT::v16i8, MVT::Glue};
5380 SDValue Ops[] = {
N->getOperand(2),
N->getOperand(3),
5386 if (Subtarget->isISA3_1()) {
5389 CurDAG->
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
5390 CR6Reg, SubRegIdx, BCDOp.
getValue(1)),
5399 SDValue Ops[] = {Move, getI32Imm((32 - (4 + ShiftVal)) & 31, dl),
5400 getI32Imm(31, dl), getI32Imm(31, dl)};
5406 CurDAG->
SelectNodeTo(
N, PPC::XORI, MVT::i32, Shift, getI32Imm(1, dl));
5412 if (!Subtarget->isISA3_1())
5414 unsigned Opcode = 0;
5418 case Intrinsic::ppc_altivec_vstribr_p:
5419 Opcode = PPC::VSTRIBR_rec;
5421 case Intrinsic::ppc_altivec_vstribl_p:
5422 Opcode = PPC::VSTRIBL_rec;
5424 case Intrinsic::ppc_altivec_vstrihr_p:
5425 Opcode = PPC::VSTRIHR_rec;
5427 case Intrinsic::ppc_altivec_vstrihl_p:
5428 Opcode = PPC::VSTRIHL_rec;
5435 EVT VTs[] = {MVT::v16i8, MVT::Glue};
5443 CurDAG->
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
5444 CR6Reg, SubRegIdx, VecStrOp.
getValue(1)),
5461 if (PPCLowering->getPointerTy(CurDAG->
getDataLayout()) != MVT::i32 ||
5462 !Subtarget->isSecurePlt() || !Subtarget->
isTargetELF() ||
5470 if (PPCLowering->getPointerTy(CurDAG->
getDataLayout()) != MVT::i32 ||
5471 !
TM.isPositionIndependent() || !Subtarget->isSecurePlt() ||
5489 ReplaceNode(
N, getGlobalBaseReg());
5493 selectFrameIndex(
N,
N);
5499 N->getOperand(0), InGlue));
5504 ReplaceNode(
N, CurDAG->
getMachineNode(PPC::ReadTB, dl, MVT::i32, MVT::i32,
5505 MVT::Other,
N->getOperand(0)));
5512 getConstantIntValue(), dl,
5513 N->getValueType(0));
5514 if (
N->getValueType(0) == MVT::i64) {
5522 assert(
N->getValueType(0) == MVT::i32 &&
5523 "Expecting i64 or i32 in PPCISD::SRA_ADDZE");
5539 if (tryTLSXFormStore(ST))
5546 EVT LoadedVT =
LD->getMemoryVT();
5553 if (tryTLSXFormLoad(LD))
5564 if (
LD->getValueType(0) != MVT::i64) {
5566 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5569 case MVT::f64: Opcode = PPC::LFDU;
break;
5570 case MVT::f32: Opcode = PPC::LFSU;
break;
5571 case MVT::i32: Opcode = PPC::LWZU;
break;
5572 case MVT::i16: Opcode = isSExt ? PPC::LHAU : PPC::LHZU;
break;
5574 case MVT::i8: Opcode = PPC::LBZU;
break;
5577 assert(
LD->getValueType(0) == MVT::i64 &&
"Unknown load result type!");
5578 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5581 case MVT::i64: Opcode = PPC::LDU;
break;
5582 case MVT::i32: Opcode = PPC::LWZU8;
break;
5583 case MVT::i16: Opcode = isSExt ? PPC::LHAU8 : PPC::LHZU8;
break;
5585 case MVT::i8: Opcode = PPC::LBZU8;
break;
5593 Opcode, dl,
LD->getValueType(0),
5594 PPCLowering->getPointerTy(CurDAG->
getDataLayout()), MVT::Other, Ops);
5595 transferMemOperands(
N, MN);
5601 if (
LD->getValueType(0) != MVT::i64) {
5603 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5606 case MVT::f64: Opcode = PPC::LFDUX;
break;
5607 case MVT::f32: Opcode = PPC::LFSUX;
break;
5608 case MVT::i32: Opcode = PPC::LWZUX;
break;
5609 case MVT::i16: Opcode = isSExt ? PPC::LHAUX : PPC::LHZUX;
break;
5611 case MVT::i8: Opcode = PPC::LBZUX;
break;
5614 assert(
LD->getValueType(0) == MVT::i64 &&
"Unknown load result type!");
5615 assert((!isSExt || LoadedVT == MVT::i16 || LoadedVT == MVT::i32) &&
5616 "Invalid sext update load");
5619 case MVT::i64: Opcode = PPC::LDUX;
break;
5620 case MVT::i32: Opcode = isSExt ? PPC::LWAUX : PPC::LWZUX8;
break;
5621 case MVT::i16: Opcode = isSExt ? PPC::LHAUX8 : PPC::LHZUX8;
break;
5623 case MVT::i8: Opcode = PPC::LBZUX8;
break;
5631 Opcode, dl,
LD->getValueType(0),
5632 PPCLowering->getPointerTy(CurDAG->
getDataLayout()), MVT::Other, Ops);
5633 transferMemOperands(
N, MN);
5641 if (tryAsSingleRLWINM(
N) || tryAsSingleRLWIMI(
N) || tryAsSingleRLDCL(
N) ||
5642 tryAsSingleRLDICL(
N) || tryAsSingleRLDICR(
N) || tryAsSingleRLWINM8(
N) ||
5643 tryAsPairOfRLDICL(
N))
5649 if (
N->getValueType(0) == MVT::i32)
5650 if (tryBitfieldInsert(
N))
5661 selectFrameIndex(
N,
N->getOperand(0).getNode(), (int64_t)Imm);
5668 if (tryAsSingleRLDIMI(
N))
5674 bool IsPPC64 = Subtarget->
isPPC64();
5676 (Imm64 & ~0xFFFFFFFFuLL) == 0) {
5680 if (ImmHi != 0 && ImmLo != 0) {
5683 getI16Imm(ImmLo, dl));
5697 bool IsPPC64 = Subtarget->
isPPC64();
5699 (Imm64 & ~0xFFFFFFFFuLL) == 0) {
5703 if (ImmHi != 0 && ImmLo != 0) {
5706 getI16Imm(ImmLo, dl));
5719 selectFrameIndex(
N,
N->getOperand(0).getNode(), (int64_t)Imm);
5726 unsigned Imm, SH, MB, ME;
5728 isRotateAndMask(
N, Imm,
true, SH, MB, ME)) {
5729 SDValue Ops[] = {
N->getOperand(0).getOperand(0),
5730 getI32Imm(SH, dl), getI32Imm(MB, dl),
5731 getI32Imm(ME, dl) };
5740 unsigned Imm, SH, MB, ME;
5742 isRotateAndMask(
N, Imm,
true, SH, MB, ME)) {
5743 SDValue Ops[] = {
N->getOperand(0).getOperand(0),
5744 getI32Imm(SH, dl), getI32Imm(MB, dl),
5745 getI32Imm(ME, dl) };
5761 unsigned Shift = llvm::countr_zero<uint64_t>(Imm);
5762 if (isInt<16>(Imm) || !Shift)
5769 if (!isInt<16>(ImmSh))
5776 N->getOperand(0), SDImm);
5779 getI32Imm(63 - Shift, dl)};
5785 N->getOperand(0), SDImm);
5788 getI32Imm(0, dl), getI32Imm(31 - Shift, dl)};
5800 EVT InVT =
N->getOperand(0).getValueType();
5801 assert((InVT == MVT::i64 || InVT == MVT::i32) &&
5802 "Invalid input type for ANDI_rec_1_EQ_BIT");
5804 unsigned Opcode = (InVT == MVT::i64) ? PPC::ANDI8_rec : PPC::ANDI_rec;
5814 CurDAG->
SelectNodeTo(
N, TargetOpcode::EXTRACT_SUBREG, MVT::i1, CR0Reg,
5815 SRIdxVal,
SDValue(AndI.getNode(), 1) );
5822 bool isPPC64 = (PtrVT == MVT::i64);
5825 if (Subtarget->useCRBits() &&
N->getOperand(0).getValueType() == MVT::i1)
5828 if (Subtarget->isISA3_0() && Subtarget->
isPPC64()) {
5829 bool NeedSwapOps =
false;
5830 bool IsUnCmp =
false;
5846 N,
N->getSimpleValueType(0) == MVT::i64 ? PPC::SETB8 : PPC::SETB,
5847 N->getValueType(0), GenCC);
5858 N->getValueType(0) == MVT::i32) {
5861 N->getOperand(0), getI32Imm(~0U, dl));
5863 N->getOperand(0),
SDValue(Tmp, 1));
5867 SDValue CCReg = SelectCC(
N->getOperand(0),
N->getOperand(1),
CC, dl);
5869 if (
N->getValueType(0) == MVT::i1) {
5877 case 0: SRI = PPC::sub_lt;
break;
5878 case 1: SRI = PPC::sub_gt;
break;
5879 case 2: SRI = PPC::sub_eq;
break;
5880 case 3: SRI = PPC::sub_un;
break;
5887 SDValue C = Inv ? NotCCBit : CCBit,
5888 NotC = Inv ? CCBit : NotCCBit;
5891 C,
N->getOperand(2)), 0);
5893 NotC,
N->getOperand(3)), 0);
5895 CurDAG->
SelectNodeTo(
N, PPC::CROR, MVT::i1, CAndT, NotCAndF);
5902 unsigned SelectCCOp;
5903 if (
N->getValueType(0) == MVT::i32)
5904 SelectCCOp = PPC::SELECT_CC_I4;
5905 else if (
N->getValueType(0) == MVT::i64)
5906 SelectCCOp = PPC::SELECT_CC_I8;
5907 else if (
N->getValueType(0) == MVT::f32) {
5908 if (Subtarget->hasP8Vector())
5909 SelectCCOp = PPC::SELECT_CC_VSSRC;
5910 else if (Subtarget->hasSPE())
5911 SelectCCOp = PPC::SELECT_CC_SPE4;
5913 SelectCCOp = PPC::SELECT_CC_F4;
5914 }
else if (
N->getValueType(0) == MVT::f64) {
5915 if (Subtarget->hasVSX())
5916 SelectCCOp = PPC::SELECT_CC_VSFRC;
5917 else if (Subtarget->hasSPE())
5918 SelectCCOp = PPC::SELECT_CC_SPE;
5920 SelectCCOp = PPC::SELECT_CC_F8;
5921 }
else if (
N->getValueType(0) == MVT::f128)
5922 SelectCCOp = PPC::SELECT_CC_F16;
5923 else if (Subtarget->hasSPE())
5924 SelectCCOp = PPC::SELECT_CC_SPE;
5925 else if (
N->getValueType(0) == MVT::v2f64 ||
5926 N->getValueType(0) == MVT::v2i64)
5927 SelectCCOp = PPC::SELECT_CC_VSRC;
5929 SelectCCOp = PPC::SELECT_CC_VRRC;
5931 SDValue Ops[] = { CCReg,
N->getOperand(2),
N->getOperand(3),
5932 getI32Imm(BROpc, dl) };
5937 if (Subtarget->hasVSX() && (
N->getValueType(0) == MVT::v2f64 ||
5938 N->getValueType(0) == MVT::v2i64)) {
5942 Op2 =
N->getOperand(SVN->
getMaskElt(1) < 2 ? 0 : 1);
5945 for (
int i = 0; i < 2; ++i)
5951 if (Op1 == Op2 &&
DM[0] == 0 &&
DM[1] == 0 &&
5957 if (
LD->isUnindexed() &&
LD->hasOneUse() && Op1.
hasOneUse() &&
5958 (
LD->getMemoryVT() == MVT::f64 ||
5959 LD->getMemoryVT() == MVT::i64) &&
5965 N->getValueType(0), Ops);
5975 unsigned tmp =
DM[0];
5982 SDValue Ops[] = { Op1, Op2, DMV };
5990 bool IsPPC64 = Subtarget->
isPPC64();
5991 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(0) };
5993 ? (IsPPC64 ? PPC::BDNZ8 : PPC::BDNZ)
5994 : (IsPPC64 ? PPC::BDZ8 : PPC::BDZ),
6005 unsigned PCC =
N->getConstantOperandVal(1);
6009 SDValue Pred = getI32Imm(PCC, dl);
6010 SDValue Ops[] = { Pred,
N->getOperand(2),
N->getOperand(3),
6011 N->getOperand(0),
N->getOperand(4) };
6016 if (tryFoldSWTestBRCC(
N))
6018 if (trySelectLoopCountIntrinsic(
N))
6024 if (
N->getOperand(2).getValueType() == MVT::i1) {
6029 case PPC::PRED_LT: Opc = PPC::CRANDC; Swap =
true;
break;
6030 case PPC::PRED_LE: Opc = PPC::CRORC; Swap =
true;
break;
6031 case PPC::PRED_EQ: Opc = PPC::CREQV; Swap =
false;
break;
6032 case PPC::PRED_GE: Opc = PPC::CRORC; Swap =
false;
break;
6033 case PPC::PRED_GT: Opc = PPC::CRANDC; Swap =
false;
break;
6034 case PPC::PRED_NE: Opc = PPC::CRXOR; Swap =
false;
break;
6047 N->getOperand(Swap ? 3 : 2),
6048 N->getOperand(Swap ? 2 : 3)), 0);
6049 CurDAG->
SelectNodeTo(
N, PPC::BC, MVT::Other, BitComp,
N->getOperand(4),
6059 N->getOperand(4),
N->getOperand(0) };
6067 unsigned Opc =
Target.getValueType() == MVT::i32 ? PPC::MTCTR : PPC::MTCTR8;
6068 unsigned Reg =
Target.getValueType() == MVT::i32 ? PPC::BCTR : PPC::BCTR8;
6075 const bool isPPC64 = Subtarget->
isPPC64();
6076 const bool isELFABI = Subtarget->
isSVR4ABI();
6077 const bool isAIXABI = Subtarget->
isAIXABI();
6083 "PowerPC doesn't support tiny or kernel code models.");
6094 auto replaceWith = [
this, &dl](
unsigned OpCode,
SDNode *TocEntry,
6099 transferMemOperands(TocEntry, MN);
6100 ReplaceNode(TocEntry, MN);
6108 assert(
TM.isPositionIndependent() &&
6109 "32-bit ELF can only have TOC entries in position independent"
6112 replaceWith(PPC::LWZtoc,
N, MVT::i32);
6116 assert(isAIXABI &&
"ELF ABI already handled");
6120 replaceWith(PPC::ADDItoc,
N, MVT::i32);
6124 replaceWith(PPC::LWZtoc,
N, MVT::i32);
6129 assert(isAIXABI &&
"ELF ABI handled in common SelectCode");
6133 replaceWith(PPC::ADDItoc8,
N, MVT::i64);
6143 assert((isPPC64 || (isAIXABI && !isPPC64)) &&
"We are dealing with 64-bit"
6144 " ELF/AIX or 32-bit AIX in the following.");
6158 SDValue TOCbase =
N->getOperand(1);
6160 EVT VT = isPPC64 ? MVT::i64 : MVT::i32;
6162 isPPC64 ? PPC::ADDIStocHA8 : PPC::ADDIStocHA, dl, VT, TOCbase, GA);
6164 if (PPCLowering->isAccessedAsGotIndirect(GA)) {
6168 isPPC64 ? PPC::LDtocL : PPC::LWZtocL, dl, VT, GA,
SDValue(Tmp, 0));
6170 transferMemOperands(
N, MN);
6183 "PPCISD::PPC32_PICGOT is only supported for 32-bit SVR4");
6192 assert(isa<ConstantSDNode>(
N->getOperand(0)) &&
6193 isa<ConstantSDNode>(
N->getOperand(1)) &&
6194 "Invalid operand on VADD_SPLAT!");
6196 int Elt =
N->getConstantOperandVal(0);
6197 int EltSize =
N->getConstantOperandVal(1);
6198 unsigned Opc1, Opc2, Opc3;
6202 Opc1 = PPC::VSPLTISB;
6203 Opc2 = PPC::VADDUBM;
6204 Opc3 = PPC::VSUBUBM;
6206 }
else if (EltSize == 2) {
6207 Opc1 = PPC::VSPLTISH;
6208 Opc2 = PPC::VADDUHM;
6209 Opc3 = PPC::VSUBUHM;
6212 assert(EltSize == 4 &&
"Invalid element size on VADD_SPLAT!");
6213 Opc1 = PPC::VSPLTISW;
6214 Opc2 = PPC::VADDUWM;
6215 Opc3 = PPC::VSUBUWM;
6219 if ((Elt & 1) == 0) {
6226 SDValue EltVal = getI32Imm(Elt >> 1, dl);
6231 }
else if (Elt > 0) {
6238 SDValue EltVal = getI32Imm(Elt - 16, dl);
6240 EltVal = getI32Imm(-16, dl);
6252 SDValue EltVal = getI32Imm(Elt + 16, dl);
6254 EltVal = getI32Imm(-16, dl);
6265 if (!Subtarget->hasAltivec() || Subtarget->hasDirectMove())
6269 if (
Type != MVT::v16i8 &&
Type != MVT::v8i16)
6278 isOffsetMultipleOf(
N, 16))
6283 Subtarget->
isPPC64() ? MVT::i64 : MVT::i32);
6284 unsigned LIOpcode = Subtarget->
isPPC64() ? PPC::LI8 : PPC::LI;
6299 unsigned SplatOp = (
Type == MVT::v16i8) ? PPC::VSPLTB : PPC::VSPLTH;
6300 unsigned SplatElemIndex =
6309 {ZeroReg,
N->getOperand(1),
N->getOperand(0)});
6311 SDNode *LoadHigh = LoadLow;
6312 if (
Type == MVT::v8i16) {
6314 PPC::LVX, dl, MVT::v16i8, MVT::Other,
6316 LIOpcode, dl, MVT::i32,
6319 N->getOperand(1),
SDValue(LoadLow, 1)});
6323 transferMemOperands(
N, LoadHigh);
6348 "Only OR nodes are supported for CMPB");
6351 if (!Subtarget->hasCMPB())
6354 if (
N->getValueType(0) != MVT::i32 &&
6355 N->getValueType(0) != MVT::i64)
6358 EVT VT =
N->getValueType(0);
6361 bool BytesFound[8] = {
false,
false,
false,
false,
false,
false,
false,
false};
6364 auto IsByteSelectCC = [
this](
SDValue O,
unsigned &
b,
6371 if (!isa<ConstantSDNode>(
O.getOperand(2)) ||
6372 !isa<ConstantSDNode>(
O.getOperand(3)))
6375 uint64_t PM =
O.getConstantOperandVal(2);
6376 uint64_t PAlt =
O.getConstantOperandVal(3);
6377 for (b = 0;
b < 8; ++
b) {
6379 if (PM && (PM & Mask) == PM && (PAlt &
Mask) == PAlt)
6388 if (!isa<ConstantSDNode>(
O.getOperand(1)) ||
6389 O.getConstantOperandVal(1) != 0) {
6390 SDValue Op0 =
O.getOperand(0), Op1 =
O.getOperand(1);
6420 isa<ConstantSDNode>(
O.getOperand(1))) {
6422 uint64_t ULim =
O.getConstantOperandVal(1);
6423 if (ULim != (UINT64_C(1) << b*8))
6446 if (!isa<ConstantSDNode>(
Op.getOperand(1)))
6448 if (
Op.getConstantOperandVal(1) != (UINT64_C(0xFF) << (8*
b)))
6453 XOR =
XOR.getOperand(0);
6461 if (!isa<ConstantSDNode>(
Op.getOperand(1)))
6463 unsigned Bits =
Op.getValueSizeInBits();
6466 if (
Op.getConstantOperandVal(1) !=
Bits-8)
6471 XOR =
XOR.getOperand(0);
6484 while (!
Queue.empty()) {
6487 for (
const SDValue &O :
V.getNode()->ops()) {
6493 }
else if (IsByteSelectCC(O, b, M,
A, OLHS, ORHS)) {
6497 BytesFound[
b] =
true;
6500 }
else if ((LHS == ORHS && RHS == OLHS) ||
6501 (RHS == ORHS && LHS == OLHS)) {
6502 BytesFound[
b] =
true;
6514 unsigned LastB = 0, BCnt = 0;
6515 for (
unsigned i = 0; i < 8; ++i)
6516 if (BytesFound[LastB]) {
6521 if (!LastB || BCnt < 2)
6526 if (
LHS.getValueType() != VT) {
6533 bool NonTrivialMask = ((int64_t) Mask) != INT64_C(-1);
6534 if (NonTrivialMask && !Alt) {
6562 if (!Subtarget->useCRBits())
6570 if (
N->getOperand(0).getValueType() != MVT::i1)
6573 if (!
N->hasOneUse())
6577 EVT VT =
N->getValueType(0);
6594 User->getValueType(0), {O0, O1});
6599 SDValue TrueRes = TryFold(ConstTrue);
6600 if (!TrueRes || TrueRes.
isUndef())
6602 SDValue FalseRes = TryFold(ConstFalse);
6603 if (!FalseRes || FalseRes.
isUndef())
6609 if (!isInt<16>(True) || !isInt<16>(False))
6616 ConstTrue = TrueRes;
6617 ConstFalse = FalseRes;
6618 }
while (
N->hasOneUse());
6621void PPCDAGToDAGISel::PreprocessISelDAG() {
6624 bool MadeChange =
false;
6631 switch (
N->getOpcode()) {
6634 Res = combineToCMPB(
N);
6639 foldBoolExts(Res,
N);
6659void PPCDAGToDAGISel::PostprocessISelDAG() {
6661 if (
TM.getOptLevel() == CodeGenOptLevel::None)
6666 PeepholePPC64ZExt();
6674bool PPCDAGToDAGISel::AllUsersSelectZero(
SDNode *
N) {
6676 if (!
User->isMachineOpcode())
6678 if (
User->getMachineOpcode() != PPC::SELECT_I4 &&
6679 User->getMachineOpcode() != PPC::SELECT_I8)
6703void PPCDAGToDAGISel::SwapAllSelectUsers(
SDNode *
N) {
6706 assert((
User->getMachineOpcode() == PPC::SELECT_I4 ||
6707 User->getMachineOpcode() == PPC::SELECT_I8) &&
6708 "Must have all select users");
6725 ReplaceUses(
User, ResNode);
6729void PPCDAGToDAGISel::PeepholeCROps() {
6735 if (!MachineNode || MachineNode->
use_empty())
6737 SDNode *ResNode = MachineNode;
6739 bool Op1Set =
false, Op1Unset =
false,
6741 Op2Set =
false, Op2Unset =
false,
6756 if (
Op.isMachineOpcode()) {
6757 if (
Op.getMachineOpcode() == PPC::CRSET)
6759 else if (
Op.getMachineOpcode() == PPC::CRUNSET)
6761 else if ((
Op.getMachineOpcode() == PPC::CRNOR &&
6762 Op.getOperand(0) ==
Op.getOperand(1)) ||
6763 Op.getMachineOpcode() == PPC::CRNOT)
6770 case PPC::SELECT_I4:
6771 case PPC::SELECT_I8:
6772 case PPC::SELECT_F4:
6773 case PPC::SELECT_F8:
6774 case PPC::SELECT_SPE:
6775 case PPC::SELECT_SPE4:
6776 case PPC::SELECT_VRRC:
6777 case PPC::SELECT_VSFRC:
6778 case PPC::SELECT_VSSRC:
6779 case PPC::SELECT_VSRC: {
6781 if (
Op.isMachineOpcode()) {
6782 if (
Op.getMachineOpcode() == PPC::CRSET)
6784 else if (
Op.getMachineOpcode() == PPC::CRUNSET)
6786 else if ((
Op.getMachineOpcode() == PPC::CRNOR &&
6787 Op.getOperand(0) ==
Op.getOperand(1)) ||
6788 Op.getMachineOpcode() == PPC::CRNOT)
6795 bool SelectSwap =
false;
6808 else if (Op1Unset || Op2Unset)
6824 else if (AllUsersSelectZero(MachineNode)) {
6847 else if (Op1Unset || Op2Unset)
6863 else if (AllUsersSelectZero(MachineNode)) {
6874 else if (Op1Set || Op2Set)
6896 else if (AllUsersSelectZero(MachineNode)) {
6936 else if (AllUsersSelectZero(MachineNode)) {
6944 if (Op1Set || Op2Set)
6970 else if (AllUsersSelectZero(MachineNode)) {
7010 else if (AllUsersSelectZero(MachineNode)) {
7027 else if (Op1Unset || Op2Set)
7046 else if (AllUsersSelectZero(MachineNode)) {
7058 else if (Op1Set || Op2Unset)
7082 else if (AllUsersSelectZero(MachineNode)) {
7089 case PPC::SELECT_I4:
7090 case PPC::SELECT_I8:
7091 case PPC::SELECT_F4:
7092 case PPC::SELECT_F8:
7093 case PPC::SELECT_SPE:
7094 case PPC::SELECT_SPE4:
7095 case PPC::SELECT_VRRC:
7096 case PPC::SELECT_VSFRC:
7097 case PPC::SELECT_VSSRC:
7098 case PPC::SELECT_VSRC:
7130 SwapAllSelectUsers(MachineNode);
7132 if (ResNode != MachineNode) {
7139 ReplaceUses(MachineNode, ResNode);
7145 }
while (IsModified);
7256 if (!Op0OK && !Op1OK)
7279 if (!Op0OK && !Op1OK)
7293void PPCDAGToDAGISel::PeepholePPC64ZExt() {
7308 bool MadeChange =
false;
7312 if (
N->use_empty() || !
N->isMachineOpcode())
7315 if (
N->getMachineOpcode() != PPC::RLDICL)
7318 if (
N->getConstantOperandVal(1) != 0 ||
7319 N->getConstantOperandVal(2) != 32)
7354 bool OutsideUse =
false;
7355 for (
SDNode *PN : ToPromote) {
7357 if (!ToPromote.count(UN) && UN != ISR.
getNode()) {
7375 for (
SDNode *PN : ToPromote) {
7377 switch (PN->getMachineOpcode()) {
7380 case PPC::RLWINM: NewOpcode = PPC::RLWINM8;
break;
7381 case PPC::RLWNM: NewOpcode = PPC::RLWNM8;
break;
7382 case PPC::SLW: NewOpcode = PPC::SLW8;
break;
7383 case PPC::SRW: NewOpcode = PPC::SRW8;
break;
7384 case PPC::LI: NewOpcode = PPC::LI8;
break;
7385 case PPC::LIS: NewOpcode = PPC::LIS8;
break;
7386 case PPC::LHBRX: NewOpcode = PPC::LHBRX8;
break;
7387 case PPC::LWBRX: NewOpcode = PPC::LWBRX8;
break;
7388 case PPC::CNTLZW: NewOpcode = PPC::CNTLZW8;
break;
7389 case PPC::CNTTZW: NewOpcode = PPC::CNTTZW8;
break;
7390 case PPC::RLWIMI: NewOpcode = PPC::RLWIMI8;
break;
7391 case PPC::OR: NewOpcode = PPC::OR8;
break;
7392 case PPC::SELECT_I4: NewOpcode = PPC::SELECT_I8;
break;
7393 case PPC::ORI: NewOpcode = PPC::ORI8;
break;
7394 case PPC::ORIS: NewOpcode = PPC::ORIS8;
break;
7395 case PPC::AND: NewOpcode = PPC::AND8;
break;
7397 NewOpcode = PPC::ANDI8_rec;
7399 case PPC::ANDIS_rec:
7400 NewOpcode = PPC::ANDIS8_rec;
7411 if (!ToPromote.count(
V.getNode()) &&
V.getValueType() == MVT::i32 &&
7412 !isa<ConstantSDNode>(V)) {
7429 for (
unsigned i = 0, ie = VTs.
NumVTs; i != ie; ++i)
7430 if (VTs.
VTs[i] == MVT::i32)
7463 if (!
N->isMachineOpcode())
7465 unsigned Opc =
N->getMachineOpcode();
7469 if (Opc == PPC::XXPERMDIs) {
7470 return isa<ConstantSDNode>(
N->getOperand(1)) &&
7471 N->getConstantOperandVal(1) == 2;
7472 }
else if (Opc == PPC::XXPERMDI || Opc == PPC::XXSLDWI) {
7473 return N->getOperand(0) ==
N->getOperand(1) &&
7474 isa<ConstantSDNode>(
N->getOperand(2)) &&
7475 N->getConstantOperandVal(2) == 2;
7483 if (!
N->isMachineOpcode())
7485 unsigned Opc =
N->getMachineOpcode();
7534 auto SkipRCCopy = [](
SDValue V) {
7535 while (V->isMachineOpcode() &&
7536 V->getMachineOpcode() == TargetOpcode::COPY_TO_REGCLASS) {
7538 if (V->use_empty() || !V->use_begin()->isOnlyUserOf(V.getNode()))
7540 V = V->getOperand(0);
7542 return V.hasOneUse() ? V :
SDValue();
7545 SDValue VecOp = SkipRCCopy(
N->getOperand(0));
7606 if (
N->getMachineOpcode() != PPC::ADDI8)
7611 SDValue InitialADDI =
N->getOperand(0);
7624 "Expecting the first operand to be a thread pointer for folding addi "
7625 "in local-exec accesses!");
7632 assert(GA &&
"Expecting a valid GlobalAddressSDNode when folding addi into "
7633 "local-exec accesses!");
7641 int Offset =
N->getConstantOperandVal(1);
7650void PPCDAGToDAGISel::PeepholePPC64() {
7652 bool HasAIXSmallLocalExecTLS = Subtarget->hasAIXSmallLocalExecTLS();
7657 if (
N->use_empty() || !
N->isMachineOpcode())
7664 if (HasAIXSmallLocalExecTLS)
7668 unsigned StorageOpcode =
N->getMachineOpcode();
7669 bool RequiresMod4Offset =
false;
7671 switch (StorageOpcode) {
7676 case PPC::DFLOADf64:
7677 case PPC::DFLOADf32:
7678 RequiresMod4Offset =
true;
7694 case PPC::DFSTOREf64:
7695 case PPC::DFSTOREf32:
7696 RequiresMod4Offset =
true;
7714 if (!isa<ConstantSDNode>(
N->getOperand(FirstOp)))
7718 if (!
Base.isMachineOpcode())
7722 bool ReplaceFlags =
true;
7734 switch (
Base.getMachineOpcode()) {
7742 ReplaceFlags =
false;
7744 case PPC::ADDIdtprelL:
7747 case PPC::ADDItlsldL:
7750 case PPC::ADDItocL8:
7761 int MaxDisplacement = 7;
7765 MaxDisplacement = std::min((
int)Alignment.
value() - 1, MaxDisplacement);
7768 bool UpdateHBase =
false;
7771 int Offset =
N->getConstantOperandVal(FirstOp);
7773 if (Offset < 0 || Offset > MaxDisplacement) {
7777 if (
Base.getMachineOpcode() != PPC::ADDItocL8)
7788 if (HImmOpnd != ImmOpnd)
7796 if (RequiresMod4Offset) {
7798 dyn_cast<GlobalAddressSDNode>(ImmOpnd)) {
7811 if (
auto *
C = dyn_cast<ConstantSDNode>(ImmOpnd)) {
7814 if (RequiresMod4Offset && (
Offset % 4) != 0)
7822 }
else if (
Offset != 0) {
7824 if (HasAIXSmallLocalExecTLS &&
7829 assert(GA &&
"Expecting a valid GlobalAddressSDNode when folding "
7830 "addi into local-exec accesses!");
7843 LLVM_DEBUG(
dbgs() <<
"Folding add-immediate into mem-op:\nBase: ");
7858 if (Alignment < 4 && (RequiresMod4Offset || (
Offset % 4) != 0)) {
7859 LLVM_DEBUG(
dbgs() <<
"Rejected this candidate for alignment.\n\n");
7864 dyn_cast<ConstantPoolSDNode>(ImmOpnd)) {
7873 Base.getOperand(0),
N->getOperand(3));
7883 if (
Base.getNode()->use_empty())
7893 return new PPCDAGToDAGISel(
TM, OptLevel);
MachineBasicBlock MachineBasicBlock::iterator MBBI
amdgpu 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 GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
std::optional< std::vector< StOtherPiece > > Other
const HexagonInstrInfo * TII
static MaybeAlign getAlign(Value *Ptr)
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
unsigned const TargetRegisterInfo * TRI
Module.h This file contains the declarations for the Module class.
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 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 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 isEligibleToFoldADDIForLocalExecAccesses(SelectionDAG *DAG, SDValue ADDIToFold)
static bool isInt64Immediate(SDNode *N, uint64_t &Imm)
isInt64Immediate - This method tests to see if the node is a 64-bit constant operand.
static void foldADDIForLocalExecAccesses(SDNode *N, SelectionDAG *DAG)
static bool isInt32Immediate(SDNode *N, unsigned &Imm)
isInt32Immediate - This method tests to see if the node is a 32-bit constant operand.
static int findContiguousZerosAtLeast(uint64_t Imm, unsigned Num)
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 bool hasTocDataAttr(SDValue Val, unsigned PointerSize)
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 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)
const char LLVMTargetMachineRef TM
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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)
support::ulittle16_t & Lo
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
APInt rotr(unsigned rotateAmt) const
Rotate right by rotateAmt.
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...
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
This is an important base class in LLVM.
This class represents an Operation in the Expression.
unsigned getPointerSize(unsigned AS=0) const
Layout pointer size in bytes, rounded up to a whole number of bytes.
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)
unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
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.
StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
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.
A description of a memory reference used in the backend.
An SDNode that represents everything that will be needed to construct a MachineInstr.
This SDNode is used for target intrinsics that touch memory and need an associated MachineMemOperand.
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.
PICLevel::Level getPICLevel() const
Returns the PIC level (small or large model)
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
void setROPProtectionHashSaveIndex(int Idx)
static int getRecordFormOpcode(unsigned Opcode)
bool is32BitELFABI() const
bool isPPC64() const
isPPC64 - Return true if we are generating code for 64-bit pointer mode.
const PPCTargetLowering * getTargetLowering() const override
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.
const PPCRegisterInfo * getRegisterInfo() const override
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...
This class provides iterator support for SDUse operands that use a specific SDNode.
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.
void dump() const
Dump this node, for debugging.
bool hasOneUse() const
Return true if there is exactly one use of this node.
iterator_range< use_iterator > uses()
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.
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 SelectInlineAsmMemoryOperand(const SDValue &Op, InlineAsm::ConstraintCode ConstraintID, std::vector< SDValue > &OutOps)
SelectInlineAsmMemoryOperand - Select the specified address as a target addressing mode,...
virtual void PostprocessISelDAG()
PostprocessISelDAG() - This hook allows the target to hack on the graph right after selection.
virtual void PreprocessISelDAG()
PreprocessISelDAG - This hook allows targets to hack on the graph before instruction selection starts...
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
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 getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS)
Helper function to make it easier to build Select's if you just have operands and don't want to check...
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
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),...
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,...
const TargetLowering & getTargetLoweringInfo() const
allnodes_const_iterator allnodes_begin() const
allnodes_const_iterator allnodes_end() const
void setNodeMemRefs(MachineSDNode *N, ArrayRef< MachineMemOperand * > NewMemRefs)
Mutate the specified machine node's memory references to the provided list.
const DataLayout & getDataLayout() const
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getRegister(unsigned Reg, EVT VT)
void RemoveDeadNodes()
This method deletes all unreachable nodes in the SelectionDAG.
void RemoveDeadNode(SDNode *N)
Remove the specified node from the system.
SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
const TargetMachine & getTarget() const
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...
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
iterator_range< allnodes_iterator > allnodes()
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)
void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDValue > Ops)
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.
bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
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
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
int getMaskElt(unsigned Idx) const
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
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 is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
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.
unsigned getID() const
Return the register class ID number.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Target - Wrapper for Target specific information.
The instances of the Type class are immutable: once they are created, they are never changed.
A Use represents the edge between a Value definition and its users.
unsigned getOperandNo() const
Return the operand # of this use in its User.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
StringRef getName() const
Return a constant reference to the value's name.
void dump() const
Support for debugging, callable in GDB: V->dump()
An efficient, type-erasing, non-owning reference to a callable.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ 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.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ BR_CC
BR_CC - Conditional branch.
@ BRIND
BRIND - Indirect branch.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ TargetConstant
TargetConstant* - Like Constant*, but the DAG does not do any folding, simplification,...
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
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_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...
@ ADDI_TLSGD_L_ADDR
G8RC = ADDI_TLSGD_L_ADDR G8RReg, Symbol, Symbol - Op that combines ADDI_TLSGD_L and GET_TLS_ADDR unti...
@ COND_BRANCH
CHAIN = COND_BRANCH CHAIN, CRRC, OPC, DESTBB [, INFLAG] - This corresponds to the COND_BRANCH pseudo ...
@ BDNZ
CHAIN = BDNZ CHAIN, DESTBB - These are used to create counter-based loops.
@ SRL
These nodes represent PPC shifts.
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
@ 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...
@ ADDI_TLSLD_L_ADDR
G8RC = ADDI_TLSLD_L_ADDR G8RReg, Symbol, Symbol - Op that combines ADDI_TLSLD_L and GET_TLSLD_ADDR un...
@ MAT_PCREL_ADDR
MAT_PCREL_ADDR = Materialize a PC Relative address.
@ MFOCRF
R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
@ TOC_ENTRY
GPRC = TOC_ENTRY GA, TOC Loads the entry for GA from the TOC, where the TOC base is given by the last...
@ ADD_TLS
G8RC = ADD_TLS G8RReg, Symbol - Can be used by the initial-exec and local-exec TLS models,...
@ 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.
@ CALL
CALL - A direct function call.
@ LD_SPLAT
VSRC, CHAIN = LD_SPLAT, CHAIN, Ptr - a splatting load memory instructions such as LXVDSX,...
@ TLS_LOCAL_EXEC_MAT_ADDR
TLS_LOCAL_EXEC_MAT_ADDR = Materialize an address for TLS global address when using local exec access ...
@ FTSQRT
Test instruction for software square root.
@ CMPB
The CMPB instruction (takes two operands of i32 or i64).
@ SRA_ADDZE
The combination of sra[wd]i and addze used to implemented signed integer division by a power of 2.
@ GET_TPOINTER
x3 = GET_TPOINTER - Used for the local- and initial-exec TLS model on 32-bit AIX, produces a call to ...
@ LD_GOT_TPREL_L
G8RC = LD_GOT_TPREL_L Symbol, G8RReg - Used by the initial-exec TLS model, produces a LD instruction ...
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
@ Define
Register definition.
Reg
All possible values of the reg field in the ModR/M byte.
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)
This is an optimization pass for GlobalISel generic memory operations.
bool operator<(int64_t V1, const APSInt &V2)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
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,...
static bool isRunOfOnes64(uint64_t Val, unsigned &MB, unsigned &ME)
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
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.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
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...
CodeGenOptLevel
Code generation optimization level.
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
FunctionPass * createPPCISelDag(PPCTargetMachine &TM, CodeGenOptLevel OL)
createPPCISelDag - This pass converts a legalized DAG into a PowerPC-specific DAG,...
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Xor
Bitwise or logical XOR of integers.
DWARFExpression::Operation Op
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.
This struct is a compact representation of a valid (non-zero power of two) alignment.
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.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.