49#include "llvm/IR/IntrinsicsPowerPC.h"
72#define DEBUG_TYPE "ppc-isel"
73#define PASS_NAME "PowerPC DAG->DAG Pattern Instruction Selection"
76 "Number of (sext(setcc)) nodes expanded into GPR sequence.");
78 "Number of (zext(setcc)) nodes expanded into GPR sequence.");
80 "Number of sign extensions for compare inputs added.");
82 "Number of zero extensions for compare inputs added.");
84 "Number of logical ops on i1 values calculated in GPR.");
86 "Number of compares not eliminated as they have non-extending uses.");
88 "Number of compares lowered to setb.");
96 cl::desc(
"use aggressive ppc isel for bit permutations"),
99 "ppc-bit-perm-rewriter-stress-rotates",
100 cl::desc(
"stress rotate selection in aggressive ppc isel for "
105 "ppc-use-branch-hint",
cl::init(
true),
106 cl::desc(
"Enable static hinting of branches on ppc"),
111 cl::desc(
"Enable tls optimization peephole"),
120 cl::desc(
"Specify the types of comparisons to emit GPR-only code for."),
126 "Only comparisons where inputs don't need [sz]ext."),
129 "Only i32 comparisons with zext result."),
131 "Only i64 comparisons with zext result."),
134 "Only i32 comparisons with sext result."),
136 "Only i64 comparisons with sext result.")));
147 unsigned GlobalBaseReg = 0;
150 PPCDAGToDAGISel() =
delete;
160 if (Subtarget->hasROPProtect()) {
179 inline SDValue getI16Imm(
unsigned Imm,
const SDLoc &dl) {
180 return CurDAG->getTargetConstant(Imm, dl, MVT::i16);
185 inline SDValue getI32Imm(
unsigned Imm,
const SDLoc &dl) {
186 return CurDAG->getTargetConstant(Imm, dl, MVT::i32);
192 return CurDAG->getTargetConstant(Imm, dl, MVT::i64);
196 inline SDValue getSmallIPtrImm(int64_t Imm,
const SDLoc &dl) {
197 return CurDAG->getSignedTargetConstant(
198 Imm, dl, PPCLowering->getPointerTy(CurDAG->getDataLayout()));
203 static bool isRotateAndMask(
SDNode *
N,
unsigned Mask,
bool isShiftMask,
204 unsigned &SH,
unsigned &MB,
unsigned &ME);
208 SDNode *getGlobalBaseReg();
216 bool tryBitfieldInsert(
SDNode *
N);
217 bool tryBitPermutation(
SDNode *
N);
218 bool tryIntCompareInGPR(
SDNode *
N);
250 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
258 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
266 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
274 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
281 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
289 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
297 return PPCLowering->SelectForceXFormMode(
N, Disp,
Base, *CurDAG) ==
308 return PPCLowering->SelectAddressRegReg(
N,
Base, Index, *CurDAG,
319 return PPCLowering->SelectAddressRegReg(
N,
Base, Index, *CurDAG,
330 return PPCLowering->SelectAddressRegReg(
N,
Base, Index, *CurDAG,
337 return PPCLowering->SelectAddressRegRegOnly(
N,
Base, Index, *CurDAG);
346 return PPCLowering->SelectAddressRegImm(
N, Disp,
Base, *CurDAG,
354 return PPCLowering->SelectAddressRegImm(
N, Disp,
Base, *CurDAG,
Align(4));
361 return PPCLowering->SelectAddressRegImm(
N, Disp,
Base, *CurDAG,
369 return PPCLowering->SelectAddressRegImm34(
N, Disp,
Base, *CurDAG);
379 return PPCLowering->SelectAddressPCRel(
N,
Base);
389 std::vector<SDValue> &OutOps)
override {
390 switch(ConstraintID) {
392 errs() <<
"ConstraintID: "
406 SDValue RC = CurDAG->getTargetConstant(TRC->
getID(), dl, MVT::i32);
408 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
409 dl,
Op.getValueType(),
412 OutOps.push_back(NewOp);
419#include "PPCGenDAGISel.inc"
423 bool tryFoldSWTestBRCC(
SDNode *
N);
424 bool trySelectLoopCountIntrinsic(
SDNode *
N);
425 bool tryAsSingleRLDICL(
SDNode *
N);
426 bool tryAsSingleRLDCL(
SDNode *
N);
427 bool tryAsSingleRLDICR(
SDNode *
N);
428 bool tryAsSingleRLWINM(
SDNode *
N);
429 bool tryAsSingleRLWINM8(
SDNode *
N);
430 bool tryAsSingleRLWIMI(
SDNode *
N);
431 bool tryAsPairOfRLDICL(
SDNode *
N);
432 bool tryAsSingleRLDIMI(
SDNode *
N);
434 void PeepholePPC64();
435 void PeepholePPC64ZExt();
436 void PeepholeCROps();
441 bool AllUsersSelectZero(
SDNode *
N);
442 void SwapAllSelectUsers(
SDNode *
N);
444 bool isOffsetMultipleOf(
SDNode *
N,
unsigned Val)
const;
454 ID,
std::make_unique<PPCDAGToDAGISel>(tm, OptLevel)) {}
458char PPCDAGToDAGISelLegacy::ID = 0;
465SDNode *PPCDAGToDAGISel::getGlobalBaseReg() {
466 if (!GlobalBaseReg) {
474 if (PPCLowering->getPointerTy(CurDAG->getDataLayout()) == MVT::i32) {
477 if (!Subtarget->isSecurePlt() &&
487 TII.get(PPC::UpdateGBR), GlobalBaseReg)
493 RegInfo->createVirtualRegister(&PPC::GPRC_and_GPRC_NOR0RegClass);
513 return CurDAG->getRegister(GlobalBaseReg,
514 PPCLowering->getPointerTy(CurDAG->getDataLayout()))
554 if (
N->getOpcode() ==
ISD::Constant &&
N->getValueType(0) == MVT::i32) {
555 Imm =
N->getAsZExtVal();
564 if (
N->getOpcode() ==
ISD::Constant &&
N->getValueType(0) == MVT::i64) {
565 Imm =
N->getAsZExtVal();
586 assert(isa<BasicBlockSDNode>(DestMBB));
616 if (std::max(TProb, FProb) / Threshold < std::min(TProb, FProb))
620 <<
"::" << BB->
getName() <<
"'\n"
621 <<
" -> " <<
TBB->
getName() <<
": " << TProb <<
"\n"
622 <<
" -> " << FBB->
getName() <<
": " << FProb <<
"\n");
638 return N->getOpcode() == Opc
644 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
645 SDValue TFI = CurDAG->getTargetFrameIndex(FI,
N->getValueType(0));
646 unsigned Opc =
N->getValueType(0) == MVT::i32 ? PPC::ADDI : PPC::ADDI8;
648 CurDAG->SelectNodeTo(SN, Opc,
N->getValueType(0), TFI,
649 getSmallIPtrImm(
Offset, dl));
651 ReplaceNode(SN, CurDAG->getMachineNode(Opc, dl,
N->getValueType(0), TFI,
652 getSmallIPtrImm(
Offset, dl)));
655bool PPCDAGToDAGISel::isRotateAndMask(
SDNode *
N,
unsigned Mask,
656 bool isShiftMask,
unsigned &SH,
657 unsigned &MB,
unsigned &ME) {
660 if (
N->getValueType(0) != MVT::i32)
664 unsigned Indeterminant = ~0;
665 unsigned Opcode =
N->getOpcode();
666 if (
N->getNumOperands() != 2 ||
672 if (isShiftMask)
Mask =
Mask << Shift;
674 Indeterminant = ~(0xFFFFFFFFu << Shift);
677 if (isShiftMask)
Mask =
Mask >> Shift;
679 Indeterminant = ~(0xFFFFFFFFu >> Shift);
689 if (Mask && !(Mask & Indeterminant)) {
702 "Only expecting the ADD_TLS instruction to acquire the thread pointer!");
706 unsigned ADDTLSOp1Opcode = ADDTLSOp1.getOpcode();
719 LoadSDNode *LD = dyn_cast<LoadSDNode>(ADDTLSOp1);
731 dyn_cast_or_null<RegisterSDNode>(ADDTLSOp1.getNode());
753 for (
auto *ADDTLSUse :
Base.getNode()->users()) {
757 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(ADDTLSUse)) {
758 if (LD->getSrcValueOffset() != 0 || !LD->getOffset().isUndef())
760 }
else if (
StoreSDNode *ST = dyn_cast<StoreSDNode>(ADDTLSUse)) {
761 if (ST->getSrcValueOffset() != 0 || !ST->getOffset().isUndef())
776bool PPCDAGToDAGISel::tryTLSXFormStore(
StoreSDNode *ST) {
782 EVT MemVT =
ST->getMemoryVT();
783 EVT RegVT =
ST->getValue().getValueType();
790 Opcode = (RegVT == MVT::i32) ? PPC::STBXTLS_32 : PPC::STBXTLS;
794 Opcode = (RegVT == MVT::i32) ? PPC::STHXTLS_32 : PPC::STHXTLS;
798 Opcode = (RegVT == MVT::i32) ? PPC::STWXTLS_32 : PPC::STWXTLS;
802 Opcode = PPC::STDXTLS;
806 Opcode = PPC::STFSXTLS;
810 Opcode = PPC::STFDXTLS;
818 SDNode *MN = CurDAG->getMachineNode(Opcode, dl, VTs, Ops);
819 transferMemOperands(ST, MN);
824bool PPCDAGToDAGISel::tryTLSXFormLoad(
LoadSDNode *LD) {
830 EVT MemVT =
LD->getMemoryVT();
831 EVT RegVT =
LD->getValueType(0);
838 Opcode = (RegVT == MVT::i32) ? PPC::LBZXTLS_32 : PPC::LBZXTLS;
842 if (RegVT == MVT::i32)
843 Opcode = isSExt ? PPC::LHAXTLS_32 : PPC::LHZXTLS_32;
845 Opcode = isSExt ? PPC::LHAXTLS : PPC::LHZXTLS;
849 if (RegVT == MVT::i32)
850 Opcode = isSExt ? PPC::LWAXTLS_32 : PPC::LWZXTLS_32;
852 Opcode = isSExt ? PPC::LWAXTLS : PPC::LWZXTLS;
856 Opcode = PPC::LDXTLS;
860 Opcode = PPC::LFSXTLS;
864 Opcode = PPC::LFDXTLS;
871 SDNode *MN = CurDAG->getMachineNode(Opcode, dl, VTs, Ops);
872 transferMemOperands(LD, MN);
879bool PPCDAGToDAGISel::tryBitfieldInsert(
SDNode *
N) {
884 KnownBits LKnown = CurDAG->computeKnownBits(Op0);
885 KnownBits RKnown = CurDAG->computeKnownBits(Op1);
890 if ((TargetMask | InsertMask) == 0xFFFFFFFF) {
893 unsigned Value, SH = 0;
894 TargetMask = ~TargetMask;
895 InsertMask = ~InsertMask;
943 SDValue Ops[] = { Op0, Op1, getI32Imm(SH, dl), getI32Imm(MB, dl),
945 ReplaceNode(
N, CurDAG->getMachineNode(PPC::RLWIMI, dl, MVT::i32, Ops));
953 unsigned MaxTruncation = 0;
960 User->isMachineOpcode() ?
User->getMachineOpcode() :
User->getOpcode();
964 if (
User->isMachineOpcode())
966 MaxTruncation = std::max(MaxTruncation,
967 (
unsigned)
User->getValueType(0).getSizeInBits());
970 if (
User->isMachineOpcode())
976 MaxTruncation = std::max(MaxTruncation, MemVTSize);
985 MaxTruncation = std::max(MaxTruncation, 32u);
993 MaxTruncation = std::max(MaxTruncation, 16u);
1001 MaxTruncation = std::max(MaxTruncation, 8u);
1005 return MaxTruncation;
1011 unsigned HiTZ = llvm::countr_zero<uint32_t>(
Hi_32(Imm));
1012 unsigned LoLZ = llvm::countl_zero<uint32_t>(
Lo_32(Imm));
1013 if ((HiTZ + LoLZ) >= Num)
1021 unsigned TZ = llvm::countr_zero<uint64_t>(Imm);
1022 unsigned LZ = llvm::countl_zero<uint64_t>(Imm);
1023 unsigned TO = llvm::countr_one<uint64_t>(Imm);
1024 unsigned LO = llvm::countl_one<uint64_t>(Imm);
1025 unsigned Hi32 =
Hi_32(Imm);
1026 unsigned Lo32 =
Lo_32(Imm);
1027 SDNode *Result =
nullptr;
1030 auto getI32Imm = [CurDAG, dl](
unsigned Imm) {
1038 if (isInt<16>(Imm)) {
1044 if (TZ > 15 && (LZ > 32 || LO > 32))
1046 getI32Imm((Imm >> 16) & 0xffff));
1050 assert(LZ < 64 &&
"Unexpected leading zeros here.");
1052 unsigned FO = llvm::countl_one<uint64_t>(Imm << LZ);
1055 if (isInt<32>(Imm)) {
1056 uint64_t ImmHi16 = (Imm >> 16) & 0xffff;
1057 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
1058 Result = CurDAG->
getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
1060 getI32Imm(Imm & 0xffff));
1068 if ((LZ + FO + TZ) > 48) {
1070 getI32Imm((Imm >> TZ) & 0xffff));
1072 getI32Imm(TZ), getI32Imm(LZ));
1089 if ((LZ + TO) > 48) {
1093 assert(LZ <= 32 &&
"Unexpected shift value.");
1095 getI32Imm((Imm >> (48 - LZ) & 0xffff)));
1097 getI32Imm(48 - LZ), getI32Imm(LZ));
1115 if ((LZ + FO + TO) > 48) {
1117 getI32Imm((Imm >> TO) & 0xffff));
1119 getI32Imm(TO), getI32Imm(LZ));
1125 if (LZ == 32 && ((Lo32 & 0x8000) == 0)) {
1127 getI32Imm(Lo32 & 0xffff));
1129 getI32Imm(Lo32 >> 16));
1153 getI32Imm(RotImm & 0xffff));
1155 getI32Imm(Shift), getI32Imm(0));
1162 uint64_t ImmHi16 = (Lo32 >> 16) & 0xffff;
1164 if (isInt<16>(Lo32))
1166 CurDAG->
getMachineNode(PPC::LI8, dl, MVT::i64, getI32Imm(ImmLo16));
1169 CurDAG->
getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(ImmHi16));
1173 CurDAG->
getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(ImmHi16));
1175 SDValue(Result, 0), getI32Imm(ImmLo16));
1192 if ((LZ + FO + TZ) > 32) {
1193 uint64_t ImmHi16 = (Imm >> (TZ + 16)) & 0xffff;
1194 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
1195 Result = CurDAG->
getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
1197 getI32Imm((Imm >> TZ) & 0xffff));
1199 getI32Imm(TZ), getI32Imm(LZ));
1206 if ((LZ + TO) > 32) {
1210 assert(LZ <= 32 &&
"Unexpected shift value.");
1212 getI32Imm((Imm >> (48 - LZ)) & 0xffff));
1214 getI32Imm((Imm >> (32 - LZ)) & 0xffff));
1216 getI32Imm(32 - LZ), getI32Imm(LZ));
1224 if ((LZ + FO + TO) > 32) {
1226 getI32Imm((Imm >> (TO + 16)) & 0xffff));
1228 getI32Imm((Imm >> TO) & 0xffff));
1230 getI32Imm(TO), getI32Imm(LZ));
1242 uint64_t ImmHi16 = (RotImm >> 16) & 0xffff;
1243 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
1244 Result = CurDAG->
getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
1246 getI32Imm(RotImm & 0xffff));
1248 getI32Imm(Shift), getI32Imm(0));
1262 unsigned TZ = llvm::countr_zero<uint64_t>(Imm);
1263 unsigned LZ = llvm::countl_zero<uint64_t>(Imm);
1264 unsigned TO = llvm::countr_one<uint64_t>(Imm);
1265 unsigned FO = llvm::countl_one<uint64_t>(LZ == 64 ? 0 : (Imm << LZ));
1266 unsigned Hi32 =
Hi_32(Imm);
1267 unsigned Lo32 =
Lo_32(Imm);
1269 auto getI32Imm = [CurDAG, dl](
unsigned Imm) {
1273 auto getI64Imm = [CurDAG, dl](
uint64_t Imm) {
1288 SDNode *Result =
nullptr;
1295 if ((LZ + FO + TZ) > 30) {
1296 APInt SignedInt34 =
APInt(34, (Imm >> TZ) & 0x3ffffffff);
1299 getI64Imm(Extended.getZExtValue()));
1301 getI32Imm(TZ), getI32Imm(LZ));
1317 if ((LZ + TO) > 30) {
1318 APInt SignedInt34 =
APInt(34, (Imm >> (30 - LZ)) & 0x3ffffffff);
1321 getI64Imm(Extended.getZExtValue()));
1323 getI32Imm(30 - LZ), getI32Imm(LZ));
1330 if ((LZ + FO + TO) > 30) {
1331 APInt SignedInt34 =
APInt(34, (Imm >> TO) & 0x3ffffffff);
1334 getI64Imm(Extended.getZExtValue()));
1336 getI32Imm(TO), getI32Imm(LZ));
1348 for (
unsigned Shift = 0; Shift < 63; ++Shift) {
1350 if (isInt<34>(RotImm)) {
1352 CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(RotImm));
1354 SDValue(Result, 0), getI32Imm(Shift),
1362 Result = CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(Hi32));
1372 CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(Hi32));
1374 CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(Lo32));
1381 unsigned *InstCnt =
nullptr) {
1382 unsigned InstCntDirect = 0;
1393 if (Subtarget.hasPrefixInstrs() && InstCntDirect != 1) {
1394 unsigned InstCntDirectP = 0;
1401 if (ResultP && (!Result || InstCntDirectP < InstCntDirect)) {
1403 *InstCnt = InstCntDirectP;
1410 *InstCnt = InstCntDirect;
1413 auto getI32Imm = [CurDAG, dl](
unsigned Imm) {
1422 if (Hi16OfLo32 && Lo16OfLo32) {
1425 bool IsSelected =
false;
1429 CurDAG->
getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(Hi16));
1431 SDValue(Result, 0), getI32Imm(Lo16));
1437 if (Hi16OfHi32 == Lo16OfHi32 && Lo16OfHi32 == Lo16OfLo32) {
1439 Result = getSplat(Hi16OfLo32, Lo16OfLo32);
1444 }
else if (Hi16OfHi32 == Hi16OfLo32 && Hi16OfLo32 == Lo16OfLo32) {
1446 Result = getSplat(Hi16OfHi32, Lo16OfHi32);
1449 getI32Imm(16), getI32Imm(31)};
1450 Result = CurDAG->
getMachineNode(PPC::RLWIMI8, dl, MVT::i64, Ops);
1451 }
else if (Lo16OfHi32 == Lo16OfLo32 && Hi16OfLo32 == Lo16OfLo32) {
1453 Result = getSplat(Hi16OfHi32, Lo16OfHi32);
1456 getI32Imm(0), getI32Imm(15)};
1457 Result = CurDAG->
getMachineNode(PPC::RLWIMI8, dl, MVT::i64, Ops);
1459 if (IsSelected ==
true) {
1472 SDValue(Result, 0), getI32Imm(Hi16OfLo32));
1477 getI32Imm(Lo16OfLo32));
1481 *InstCnt = InstCntDirect;
1490 int64_t Imm =
N->getAsZExtVal();
1494 if (isInt<16>(SextImm))
1502class BitPermutationSelector {
1517 VariableKnownToBeZero
1520 ValueBit(
SDValue V,
unsigned I, Kind K = Variable)
1522 ValueBit(Kind K = Variable) :
Idx(UINT32_MAX),
K(
K) {}
1525 return K == ConstZero ||
K == VariableKnownToBeZero;
1528 bool hasValue()
const {
1529 return K == Variable ||
K == VariableKnownToBeZero;
1533 assert(hasValue() &&
"Cannot get the value of a constant bit");
1537 unsigned getValueBitIndex()
const {
1538 assert(hasValue() &&
"Cannot get the value bit index of a constant bit");
1547 unsigned StartIdx, EndIdx;
1557 bool Repl32Coalesced;
1559 BitGroup(
SDValue V,
unsigned R,
unsigned S,
unsigned E)
1560 :
V(
V), RLAmt(
R), StartIdx(S), EndIdx(E), Repl32(
false), Repl32CR(
false),
1561 Repl32Coalesced(
false) {
1562 LLVM_DEBUG(
dbgs() <<
"\tbit group for " <<
V.getNode() <<
" RLAmt = " << R
1563 <<
" [" << S <<
", " << E <<
"]\n");
1569 struct ValueRotInfo {
1571 unsigned RLAmt = std::numeric_limits<unsigned>::max();
1572 unsigned NumGroups = 0;
1573 unsigned FirstGroupStartIdx = std::numeric_limits<unsigned>::max();
1574 bool Repl32 =
false;
1576 ValueRotInfo() =
default;
1584 if (Repl32 <
Other.Repl32)
1586 else if (Repl32 >
Other.Repl32)
1588 else if (NumGroups >
Other.NumGroups)
1590 else if (NumGroups <
Other.NumGroups)
1592 else if (RLAmt == 0 &&
Other.RLAmt != 0)
1594 else if (RLAmt != 0 &&
Other.RLAmt == 0)
1596 else if (FirstGroupStartIdx <
Other.FirstGroupStartIdx)
1602 using ValueBitsMemoizedValue = std::pair<bool, SmallVector<ValueBit, 64>>;
1603 using ValueBitsMemoizer =
1605 ValueBitsMemoizer Memoizer;
1611 std::pair<bool, SmallVector<ValueBit, 64> *> getValueBits(
SDValue V,
1613 auto &ValueEntry = Memoizer[
V];
1615 return std::make_pair(ValueEntry->first, &ValueEntry->second);
1616 ValueEntry.reset(
new ValueBitsMemoizedValue());
1617 bool &Interesting = ValueEntry->first;
1619 Bits.resize(NumBits);
1621 switch (
V.getOpcode()) {
1624 if (isa<ConstantSDNode>(
V.getOperand(1))) {
1626 unsigned RotAmt =
V.getConstantOperandVal(1) & (NumBits - 1);
1628 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1630 for (
unsigned i = 0; i < NumBits; ++i)
1631 Bits[i] = LHSBits[i < RotAmt ? i + (NumBits - RotAmt) : i - RotAmt];
1633 return std::make_pair(Interesting =
true, &Bits);
1638 if (isa<ConstantSDNode>(
V.getOperand(1))) {
1640 unsigned ShiftAmt =
V.getConstantOperandVal(1) & ((NumBits << 1) - 1);
1642 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1644 if (ShiftAmt >= NumBits) {
1645 for (
unsigned i = 0; i < NumBits; ++i)
1646 Bits[i] = ValueBit(ValueBit::ConstZero);
1648 for (
unsigned i = ShiftAmt; i < NumBits; ++i)
1649 Bits[i] = LHSBits[i - ShiftAmt];
1650 for (
unsigned i = 0; i < ShiftAmt; ++i)
1651 Bits[i] = ValueBit(ValueBit::ConstZero);
1654 return std::make_pair(Interesting =
true, &Bits);
1659 if (isa<ConstantSDNode>(
V.getOperand(1))) {
1661 unsigned ShiftAmt =
V.getConstantOperandVal(1) & ((NumBits << 1) - 1);
1663 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1665 if (ShiftAmt >= NumBits) {
1666 for (
unsigned i = 0; i < NumBits; ++i)
1667 Bits[i] = ValueBit(ValueBit::ConstZero);
1669 for (
unsigned i = 0; i < NumBits - ShiftAmt; ++i)
1670 Bits[i] = LHSBits[i + ShiftAmt];
1671 for (
unsigned i = NumBits - ShiftAmt; i < NumBits; ++i)
1672 Bits[i] = ValueBit(ValueBit::ConstZero);
1675 return std::make_pair(Interesting =
true, &Bits);
1679 if (isa<ConstantSDNode>(
V.getOperand(1))) {
1687 std::tie(Interesting, LHSBits) = getValueBits(
V.getOperand(0), NumBits);
1689 for (
unsigned i = 0; i < NumBits; ++i)
1690 if (((Mask >> i) & 1) == 1)
1691 Bits[i] = (*LHSBits)[i];
1695 if ((*LHSBits)[i].
isZero())
1696 Bits[i] = (*LHSBits)[i];
1698 Bits[i] = ValueBit(ValueBit::ConstZero);
1701 return std::make_pair(Interesting, &Bits);
1705 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1706 const auto &RHSBits = *getValueBits(
V.getOperand(1), NumBits).second;
1708 bool AllDisjoint =
true;
1710 unsigned LastIdx = 0;
1711 for (
unsigned i = 0; i < NumBits; ++i) {
1719 if (LHSBits[i].hasValue() && LHSBits[i].getValue() == LastVal &&
1720 LHSBits[i].getValueBitIndex() == LastIdx + 1)
1721 Bits[i] = LHSBits[i];
1722 else if (RHSBits[i].hasValue() && RHSBits[i].getValue() == LastVal &&
1723 RHSBits[i].getValueBitIndex() == LastIdx + 1)
1724 Bits[i] = RHSBits[i];
1726 Bits[i] = ValueBit(ValueBit::ConstZero);
1728 else if (LHSBits[i].
isZero())
1729 Bits[i] = RHSBits[i];
1730 else if (RHSBits[i].
isZero())
1731 Bits[i] = LHSBits[i];
1733 AllDisjoint =
false;
1737 if (Bits[i].hasValue()) {
1738 LastVal =
Bits[i].getValue();
1739 LastIdx =
Bits[i].getValueBitIndex();
1742 if (LastVal) LastVal =
SDValue();
1750 return std::make_pair(Interesting =
true, &Bits);
1754 if (
V.getValueType() != MVT::i64 ||
1755 V.getOperand(0).getValueType() != MVT::i32)
1759 const unsigned NumOperandBits = 32;
1760 std::tie(Interesting, LHSBits) = getValueBits(
V.getOperand(0),
1763 for (
unsigned i = 0; i < NumOperandBits; ++i)
1764 Bits[i] = (*LHSBits)[i];
1766 for (
unsigned i = NumOperandBits; i < NumBits; ++i)
1767 Bits[i] = ValueBit(ValueBit::ConstZero);
1769 return std::make_pair(Interesting, &Bits);
1773 EVT ToType =
V.getValueType();
1775 if (FromType != MVT::i64 || ToType != MVT::i32)
1777 const unsigned NumAllBits =
FromType.getSizeInBits();
1779 std::tie(Interesting, InBits) = getValueBits(
V.getOperand(0),
1785 bool UseUpper32bit =
false;
1786 for (
unsigned i = 0; i < NumValidBits; ++i)
1787 if ((*InBits)[i].hasValue() && (*InBits)[i].getValueBitIndex() >= 32) {
1788 UseUpper32bit =
true;
1794 for (
unsigned i = 0; i < NumValidBits; ++i)
1795 Bits[i] = (*InBits)[i];
1797 return std::make_pair(Interesting, &Bits);
1803 std::tie(Interesting, LHSBits) = getValueBits(
V.getOperand(0),
1806 EVT FromType = cast<VTSDNode>(
V.getOperand(1))->getVT();
1807 const unsigned NumValidBits =
FromType.getSizeInBits();
1808 for (
unsigned i = 0; i < NumValidBits; ++i)
1809 Bits[i] = (*LHSBits)[i];
1813 for (
unsigned i = NumValidBits; i < NumBits; ++i)
1814 Bits[i] = (*LHSBits)[i].hasValue()
1815 ? ValueBit((*LHSBits)[i].getValue(),
1816 (*LHSBits)[i].getValueBitIndex(),
1817 ValueBit::VariableKnownToBeZero)
1818 : ValueBit(ValueBit::ConstZero);
1820 return std::make_pair(Interesting, &Bits);
1825 EVT VT =
LD->getMemoryVT();
1828 for (
unsigned i = 0; i < NumValidBits; ++i)
1829 Bits[i] = ValueBit(V, i);
1832 for (
unsigned i = NumValidBits; i < NumBits; ++i)
1833 Bits[i] = ValueBit(V, i, ValueBit::VariableKnownToBeZero);
1837 return std::make_pair(Interesting =
false, &Bits);
1842 for (
unsigned i = 0; i < NumBits; ++i)
1843 Bits[i] = ValueBit(V, i);
1845 return std::make_pair(Interesting =
false, &Bits);
1850 void computeRotationAmounts() {
1852 RLAmt.resize(
Bits.size());
1853 for (
unsigned i = 0; i <
Bits.size(); ++i)
1854 if (Bits[i].hasValue()) {
1855 unsigned VBI =
Bits[i].getValueBitIndex();
1859 RLAmt[i] =
Bits.size() - (VBI - i);
1860 }
else if (Bits[i].
isZero()) {
1862 RLAmt[i] = UINT32_MAX;
1871 void collectBitGroups(
bool LateMask) {
1874 unsigned LastRLAmt = RLAmt[0];
1876 unsigned LastGroupStartIdx = 0;
1877 bool IsGroupOfZeros = !
Bits[LastGroupStartIdx].hasValue();
1878 for (
unsigned i = 1; i <
Bits.size(); ++i) {
1879 unsigned ThisRLAmt = RLAmt[i];
1881 if (LateMask && !ThisValue) {
1882 ThisValue = LastValue;
1883 ThisRLAmt = LastRLAmt;
1886 if (BitGroups.empty())
1887 LastGroupStartIdx = 0;
1894 if (IsGroupOfZeros && Bits[i].
isZero())
1899 if (ThisRLAmt == LastRLAmt && ThisValue == LastValue)
1902 if (!(IsGroupOfZeros && ThisValue && !Bits[i].
isZero()))
1906 BitGroups.push_back(BitGroup(LastValue, LastRLAmt, LastGroupStartIdx,
1908 LastRLAmt = ThisRLAmt;
1909 LastValue = ThisValue;
1910 LastGroupStartIdx = i;
1911 IsGroupOfZeros = !
Bits[LastGroupStartIdx].hasValue();
1914 BitGroups.push_back(BitGroup(LastValue, LastRLAmt, LastGroupStartIdx,
1917 if (BitGroups.empty())
1921 if (BitGroups.size() > 1) {
1925 if (BitGroups[0].StartIdx == 0 &&
1926 BitGroups[BitGroups.size()-1].EndIdx ==
Bits.size()-1 &&
1927 BitGroups[0].V == BitGroups[BitGroups.size()-1].V &&
1928 BitGroups[0].RLAmt == BitGroups[BitGroups.size()-1].RLAmt) {
1929 LLVM_DEBUG(
dbgs() <<
"\tcombining final bit group with initial one\n");
1930 BitGroups[BitGroups.size()-1].EndIdx = BitGroups[0].EndIdx;
1931 BitGroups.erase(BitGroups.begin());
1941 void collectValueRotInfo() {
1944 for (
auto &BG : BitGroups) {
1945 unsigned RLAmtKey = BG.RLAmt + (BG.Repl32 ? 64 : 0);
1946 ValueRotInfo &VRI = ValueRots[std::make_pair(BG.V, RLAmtKey)];
1948 VRI.RLAmt = BG.RLAmt;
1949 VRI.Repl32 = BG.Repl32;
1951 VRI.FirstGroupStartIdx = std::min(VRI.FirstGroupStartIdx, BG.StartIdx);
1956 ValueRotsVec.clear();
1957 for (
auto &
I : ValueRots) {
1958 ValueRotsVec.push_back(
I.second);
1971 void assignRepl32BitGroups() {
1982 auto IsAllLow32 = [
this](BitGroup & BG) {
1983 if (BG.StartIdx <= BG.EndIdx) {
1984 for (
unsigned i = BG.StartIdx; i <= BG.EndIdx; ++i) {
1985 if (!Bits[i].hasValue())
1987 if (Bits[i].getValueBitIndex() >= 32)
1991 for (
unsigned i = BG.StartIdx; i <
Bits.size(); ++i) {
1992 if (!Bits[i].hasValue())
1994 if (Bits[i].getValueBitIndex() >= 32)
1997 for (
unsigned i = 0; i <= BG.EndIdx; ++i) {
1998 if (!Bits[i].hasValue())
2000 if (Bits[i].getValueBitIndex() >= 32)
2008 for (
auto &BG : BitGroups) {
2012 if (BG.RLAmt == 0) {
2013 auto PotentiallyMerged = [
this](BitGroup & BG) {
2014 for (
auto &BG2 : BitGroups)
2015 if (&BG != &BG2 && BG.V == BG2.V &&
2016 (BG2.RLAmt == 0 || BG2.RLAmt == 32))
2020 if (!PotentiallyMerged(BG))
2023 if (BG.StartIdx < 32 && BG.EndIdx < 32) {
2024 if (IsAllLow32(BG)) {
2025 if (BG.RLAmt >= 32) {
2033 << BG.V.getNode() <<
" RLAmt = " << BG.RLAmt <<
" ["
2034 << BG.StartIdx <<
", " << BG.EndIdx <<
"]\n");
2040 for (
auto I = BitGroups.begin();
I != BitGroups.end();) {
2043 auto IP = (
I == BitGroups.begin()) ?
2044 std::prev(BitGroups.end()) : std::prev(
I);
2045 if (
I->Repl32 && IP->Repl32 &&
I->V == IP->V &&
I->RLAmt == IP->RLAmt &&
2046 I->StartIdx == (IP->EndIdx + 1) % 64 &&
I != IP) {
2048 LLVM_DEBUG(
dbgs() <<
"\tcombining 32-bit replicated bit group for "
2049 <<
I->V.getNode() <<
" RLAmt = " <<
I->RLAmt <<
" ["
2050 <<
I->StartIdx <<
", " <<
I->EndIdx
2051 <<
"] with group with range [" << IP->StartIdx <<
", "
2052 << IP->EndIdx <<
"]\n");
2054 IP->EndIdx =
I->EndIdx;
2055 IP->Repl32CR = IP->Repl32CR ||
I->Repl32CR;
2056 IP->Repl32Coalesced =
true;
2057 I = BitGroups.erase(
I);
2066 if (
I->StartIdx == 32 &&
I->EndIdx == 63) {
2067 assert(std::next(
I) == BitGroups.end() &&
2068 "bit group ends at index 63 but there is another?");
2069 auto IN = BitGroups.begin();
2071 if (IP->Repl32 && IN->Repl32 &&
I->V == IP->V &&
I->V == IN->V &&
2072 (
I->RLAmt % 32) == IP->RLAmt && (
I->RLAmt % 32) == IN->RLAmt &&
2073 IP->EndIdx == 31 && IN->StartIdx == 0 &&
I != IP &&
2077 <<
" RLAmt = " <<
I->RLAmt <<
" [" <<
I->StartIdx
2078 <<
", " <<
I->EndIdx
2079 <<
"] with 32-bit replicated groups with ranges ["
2080 << IP->StartIdx <<
", " << IP->EndIdx <<
"] and ["
2081 << IN->StartIdx <<
", " << IN->EndIdx <<
"]\n");
2089 IP->Repl32CR = IP->Repl32CR ||
I->RLAmt >= 32;
2090 IP->Repl32Coalesced =
true;
2091 I = BitGroups.erase(
I);
2096 IP->EndIdx = IN->EndIdx;
2097 IP->Repl32CR = IP->Repl32CR || IN->Repl32CR ||
I->RLAmt >= 32;
2098 IP->Repl32Coalesced =
true;
2099 I = BitGroups.erase(
I);
2100 BitGroups.erase(BitGroups.begin());
2115 return CurDAG->getTargetConstant(Imm, dl, MVT::i32);
2120 for (
unsigned i = 0; i <
Bits.size(); ++i) {
2121 if (Bits[i].hasValue())
2123 Mask |= (UINT64_C(1) << i);
2134 if (
V.getValueSizeInBits() == 64)
2137 assert(
V.getValueSizeInBits() == 32);
2138 SDValue SubRegIdx = CurDAG->getTargetConstant(PPC::sub_32, dl, MVT::i32);
2139 SDValue ImDef =
SDValue(CurDAG->getMachineNode(PPC::IMPLICIT_DEF, dl,
2141 SDValue ExtVal =
SDValue(CurDAG->getMachineNode(PPC::INSERT_SUBREG, dl,
2148 if (
V.getValueSizeInBits() == 32)
2151 assert(
V.getValueSizeInBits() == 64);
2152 SDValue SubRegIdx = CurDAG->getTargetConstant(PPC::sub_32, dl, MVT::i32);
2153 SDValue SubVal =
SDValue(CurDAG->getMachineNode(PPC::EXTRACT_SUBREG, dl,
2154 MVT::i32, V, SubRegIdx), 0);
2161 void SelectAndParts32(
const SDLoc &dl,
SDValue &Res,
unsigned *InstCnt) {
2165 for (ValueRotInfo &VRI : ValueRotsVec) {
2167 for (
unsigned i = 0; i <
Bits.size(); ++i) {
2168 if (!Bits[i].hasValue() || Bits[i].getValue() != VRI.V)
2170 if (RLAmt[i] != VRI.RLAmt)
2176 unsigned ANDIMask = (
Mask & UINT16_MAX), ANDISMask = Mask >> 16;
2177 assert((ANDIMask != 0 || ANDISMask != 0) &&
2178 "No set bits in mask for value bit groups");
2179 bool NeedsRotate = VRI.RLAmt != 0;
2195 unsigned NumAndInsts = (
unsigned) NeedsRotate +
2196 (
unsigned) (ANDIMask != 0) +
2197 (
unsigned) (ANDISMask != 0) +
2198 (
unsigned) (ANDIMask != 0 && ANDISMask != 0) +
2199 (
unsigned) (
bool) Res;
2201 LLVM_DEBUG(
dbgs() <<
"\t\trotation groups for " << VRI.V.getNode()
2202 <<
" RL: " << VRI.RLAmt <<
":"
2203 <<
"\n\t\t\tisel using masking: " << NumAndInsts
2204 <<
" using rotates: " << VRI.NumGroups <<
"\n");
2206 if (NumAndInsts >= VRI.NumGroups)
2211 if (InstCnt) *InstCnt += NumAndInsts;
2216 { TruncateToInt32(VRI.V, dl), getI32Imm(VRI.RLAmt, dl),
2217 getI32Imm(0, dl), getI32Imm(31, dl) };
2218 VRot =
SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32,
2221 VRot = TruncateToInt32(VRI.V, dl);
2226 ANDIVal =
SDValue(CurDAG->getMachineNode(PPC::ANDI_rec, dl, MVT::i32,
2227 VRot, getI32Imm(ANDIMask, dl)),
2231 SDValue(CurDAG->getMachineNode(PPC::ANDIS_rec, dl, MVT::i32, VRot,
2232 getI32Imm(ANDISMask, dl)),
2237 TotalVal = ANDISVal;
2241 TotalVal =
SDValue(CurDAG->getMachineNode(PPC::OR, dl, MVT::i32,
2242 ANDIVal, ANDISVal), 0);
2247 Res =
SDValue(CurDAG->getMachineNode(PPC::OR, dl, MVT::i32,
2252 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
2253 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt;
2259 SDNode *Select32(
SDNode *
N,
bool LateMask,
unsigned *InstCnt) {
2263 if (InstCnt) *InstCnt = 0;
2266 SelectAndParts32(dl, Res, InstCnt);
2271 if ((!NeedMask || LateMask) && !Res) {
2272 ValueRotInfo &VRI = ValueRotsVec[0];
2274 if (InstCnt) *InstCnt += 1;
2276 { TruncateToInt32(VRI.V, dl), getI32Imm(VRI.RLAmt, dl),
2277 getI32Imm(0, dl), getI32Imm(31, dl) };
2278 Res =
SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32, Ops),
2281 Res = TruncateToInt32(VRI.V, dl);
2285 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
2286 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt;
2290 if (InstCnt) *InstCnt += BitGroups.size();
2293 for (
auto &BG : BitGroups) {
2296 { 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::RLWINM, dl, MVT::i32, Ops), 0);
2302 { Res, TruncateToInt32(BG.V, dl), getI32Imm(BG.RLAmt, dl),
2303 getI32Imm(
Bits.size() - BG.EndIdx - 1, dl),
2304 getI32Imm(
Bits.size() - BG.StartIdx - 1, dl) };
2305 Res =
SDValue(CurDAG->getMachineNode(PPC::RLWIMI, dl, MVT::i32, Ops), 0);
2312 unsigned ANDIMask = (
Mask & UINT16_MAX), ANDISMask = Mask >> 16;
2313 assert((ANDIMask != 0 || ANDISMask != 0) &&
2314 "No set bits in zeros mask?");
2316 if (InstCnt) *InstCnt += (
unsigned) (ANDIMask != 0) +
2318 (
unsigned) (ANDIMask != 0 && ANDISMask != 0);
2322 ANDIVal =
SDValue(CurDAG->getMachineNode(PPC::ANDI_rec, dl, MVT::i32,
2323 Res, getI32Imm(ANDIMask, dl)),
2327 SDValue(CurDAG->getMachineNode(PPC::ANDIS_rec, dl, MVT::i32, Res,
2328 getI32Imm(ANDISMask, dl)),
2336 Res =
SDValue(CurDAG->getMachineNode(PPC::OR, dl, MVT::i32,
2337 ANDIVal, ANDISVal), 0);
2343 unsigned SelectRotMask64Count(
unsigned RLAmt,
bool Repl32,
2344 unsigned MaskStart,
unsigned MaskEnd,
2348 unsigned InstMaskStart = 64 - MaskEnd - 1,
2349 InstMaskEnd = 64 - MaskStart - 1;
2354 if ((!IsIns && (InstMaskEnd == 63 || InstMaskStart == 0)) ||
2355 InstMaskEnd == 63 - RLAmt)
2364 bool Repl32,
unsigned MaskStart,
unsigned MaskEnd,
2365 unsigned *InstCnt =
nullptr) {
2368 unsigned InstMaskStart = 64 - MaskEnd - 1,
2369 InstMaskEnd = 64 - MaskStart - 1;
2371 if (InstCnt) *InstCnt += 1;
2377 assert(InstMaskStart >= 32 &&
"Mask cannot start out of range");
2378 assert(InstMaskEnd >= 32 &&
"Mask cannot end out of range");
2380 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2381 getI32Imm(InstMaskStart - 32, dl), getI32Imm(InstMaskEnd - 32, dl) };
2382 return SDValue(CurDAG->getMachineNode(PPC::RLWINM8, dl, MVT::i64,
2386 if (InstMaskEnd == 63) {
2388 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2389 getI32Imm(InstMaskStart, dl) };
2390 return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64, Ops), 0);
2393 if (InstMaskStart == 0) {
2395 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2396 getI32Imm(InstMaskEnd, dl) };
2397 return SDValue(CurDAG->getMachineNode(PPC::RLDICR, dl, MVT::i64, Ops), 0);
2400 if (InstMaskEnd == 63 - RLAmt) {
2402 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2403 getI32Imm(InstMaskStart, dl) };
2404 return SDValue(CurDAG->getMachineNode(PPC::RLDIC, dl, MVT::i64, Ops), 0);
2413 if (InstCnt) *InstCnt += 1;
2416 unsigned RLAmt2 = MaskStart;
2419 unsigned RLAmt1 = (64 + RLAmt - RLAmt2) % 64;
2421 V = SelectRotMask64(V, dl, RLAmt1,
false, 0, 63);
2422 return SelectRotMask64(V, dl, RLAmt2,
false, MaskStart, MaskEnd);
2428 unsigned RLAmt,
bool Repl32,
unsigned MaskStart,
2429 unsigned MaskEnd,
unsigned *InstCnt =
nullptr) {
2432 unsigned InstMaskStart = 64 - MaskEnd - 1,
2433 InstMaskEnd = 64 - MaskStart - 1;
2435 if (InstCnt) *InstCnt += 1;
2441 assert(InstMaskStart >= 32 &&
"Mask cannot start out of range");
2442 assert(InstMaskEnd >= 32 &&
"Mask cannot end out of range");
2444 { ExtendToInt64(
Base, dl), ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2445 getI32Imm(InstMaskStart - 32, dl), getI32Imm(InstMaskEnd - 32, dl) };
2446 return SDValue(CurDAG->getMachineNode(PPC::RLWIMI8, dl, MVT::i64,
2450 if (InstMaskEnd == 63 - RLAmt) {
2452 { ExtendToInt64(
Base, dl), ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2453 getI32Imm(InstMaskStart, dl) };
2454 return SDValue(CurDAG->getMachineNode(PPC::RLDIMI, dl, MVT::i64, Ops), 0);
2463 if (InstCnt) *InstCnt += 1;
2466 unsigned RLAmt2 = MaskStart;
2469 unsigned RLAmt1 = (64 + RLAmt - RLAmt2) % 64;
2471 V = SelectRotMask64(V, dl, RLAmt1,
false, 0, 63);
2472 return SelectRotMaskIns64(
Base, V, dl, RLAmt2,
false, MaskStart, MaskEnd);
2475 void SelectAndParts64(
const SDLoc &dl,
SDValue &Res,
unsigned *InstCnt) {
2488 for (ValueRotInfo &VRI : ValueRotsVec) {
2496 auto MatchingBG = [VRI](
const BitGroup &BG) {
2500 unsigned EffRLAmt = BG.RLAmt;
2501 if (!VRI.Repl32 && BG.Repl32) {
2502 if (BG.StartIdx < 32 && BG.EndIdx < 32 && BG.StartIdx <= BG.EndIdx &&
2503 !BG.Repl32Coalesced) {
2509 }
else if (VRI.Repl32 != BG.Repl32) {
2513 return VRI.RLAmt == EffRLAmt;
2516 for (
auto &BG : BitGroups) {
2517 if (!MatchingBG(BG))
2520 if (BG.StartIdx <= BG.EndIdx) {
2521 for (
unsigned i = BG.StartIdx; i <= BG.EndIdx; ++i)
2522 Mask |= (UINT64_C(1) << i);
2524 for (
unsigned i = BG.StartIdx; i <
Bits.size(); ++i)
2525 Mask |= (UINT64_C(1) << i);
2526 for (
unsigned i = 0; i <= BG.EndIdx; ++i)
2527 Mask |= (UINT64_C(1) << i);
2534 bool Use32BitInsts = isUInt<32>(Mask);
2536 unsigned ANDIMask = (
Mask & UINT16_MAX),
2537 ANDISMask = (Mask >> 16) & UINT16_MAX;
2539 bool NeedsRotate = VRI.RLAmt || (VRI.Repl32 && !isUInt<32>(Mask));
2541 unsigned NumAndInsts = (
unsigned) NeedsRotate +
2542 (
unsigned) (
bool) Res;
2543 unsigned NumOfSelectInsts = 0;
2545 assert(NumOfSelectInsts > 0 &&
"Failed to select an i64 constant.");
2548 (
unsigned) (ANDIMask != 0 && ANDISMask != 0);
2550 NumAndInsts += NumOfSelectInsts + 1;
2552 unsigned NumRLInsts = 0;
2553 bool FirstBG =
true;
2554 bool MoreBG =
false;
2555 for (
auto &BG : BitGroups) {
2556 if (!MatchingBG(BG)) {
2561 SelectRotMask64Count(BG.RLAmt, BG.Repl32, BG.StartIdx, BG.EndIdx,
2566 LLVM_DEBUG(
dbgs() <<
"\t\trotation groups for " << VRI.V.getNode()
2567 <<
" RL: " << VRI.RLAmt << (VRI.Repl32 ?
" (32):" :
":")
2568 <<
"\n\t\t\tisel using masking: " << NumAndInsts
2569 <<
" using rotates: " << NumRLInsts <<
"\n");
2575 if (NumAndInsts > NumRLInsts)
2580 if ((Use32BitInsts || MoreBG) && NumAndInsts == NumRLInsts)
2585 if (InstCnt) *InstCnt += NumAndInsts;
2592 if (VRI.RLAmt || (VRI.Repl32 && !isUInt<32>(Mask)))
2593 VRot = SelectRotMask64(VRI.V, dl, VRI.RLAmt, VRI.Repl32,
2594 VRI.Repl32 ? 31 : 0, VRI.Repl32 ? 30 : 63);
2599 if (Use32BitInsts) {
2600 assert((ANDIMask != 0 || ANDISMask != 0) &&
2601 "No set bits in mask when using 32-bit ands for 64-bit value");
2605 ANDIVal =
SDValue(CurDAG->getMachineNode(PPC::ANDI8_rec, dl, MVT::i64,
2606 ExtendToInt64(VRot, dl),
2607 getI32Imm(ANDIMask, dl)),
2611 SDValue(CurDAG->getMachineNode(PPC::ANDIS8_rec, dl, MVT::i64,
2612 ExtendToInt64(VRot, dl),
2613 getI32Imm(ANDISMask, dl)),
2617 TotalVal = ANDISVal;
2621 TotalVal =
SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64,
2622 ExtendToInt64(ANDIVal, dl), ANDISVal), 0);
2626 SDValue(CurDAG->getMachineNode(PPC::AND8, dl, MVT::i64,
2627 ExtendToInt64(VRot, dl), TotalVal),
2634 Res =
SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64,
2635 ExtendToInt64(Res, dl), TotalVal),
2640 eraseMatchingBitGroups(MatchingBG);
2645 SDNode *Select64(
SDNode *
N,
bool LateMask,
unsigned *InstCnt) {
2649 if (InstCnt) *InstCnt = 0;
2652 SelectAndParts64(dl, Res, InstCnt);
2657 if ((!NeedMask || LateMask) && !Res) {
2661 unsigned MaxGroupsIdx = 0;
2662 if (!ValueRotsVec[0].Repl32) {
2663 for (
unsigned i = 0, ie = ValueRotsVec.size(); i < ie; ++i)
2664 if (ValueRotsVec[i].Repl32) {
2665 if (ValueRotsVec[i].NumGroups > ValueRotsVec[0].NumGroups)
2671 ValueRotInfo &VRI = ValueRotsVec[MaxGroupsIdx];
2672 bool NeedsRotate =
false;
2675 }
else if (VRI.Repl32) {
2676 for (
auto &BG : BitGroups) {
2677 if (BG.V != VRI.V || BG.RLAmt != VRI.RLAmt ||
2678 BG.Repl32 != VRI.Repl32)
2683 if (BG.StartIdx < 32 && BG.EndIdx < 32 && BG.StartIdx < BG.EndIdx)
2692 Res = SelectRotMask64(VRI.V, dl, VRI.RLAmt, VRI.Repl32,
2693 VRI.Repl32 ? 31 : 0, VRI.Repl32 ? 30 : 63,
2700 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
2701 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt &&
2702 BG.Repl32 == VRI.Repl32;
2709 for (
auto I = BitGroups.begin(), IE = BitGroups.end();
I != IE; ++
I) {
2710 if (SelectRotMask64Count(
I->RLAmt,
I->Repl32,
I->StartIdx,
I->EndIdx,
2712 SelectRotMask64Count(
I->RLAmt,
I->Repl32,
I->StartIdx,
I->EndIdx,
2714 if (
I != BitGroups.begin()) {
2717 BitGroups.insert(BitGroups.begin(), BG);
2725 for (
auto &BG : BitGroups) {
2727 Res = SelectRotMask64(BG.V, dl, BG.RLAmt, BG.Repl32, BG.StartIdx,
2728 BG.EndIdx, InstCnt);
2730 Res = SelectRotMaskIns64(Res, BG.V, dl, BG.RLAmt, BG.Repl32,
2731 BG.StartIdx, BG.EndIdx, InstCnt);
2740 bool Use32BitInsts = isUInt<32>(Mask);
2742 unsigned ANDIMask = (
Mask & UINT16_MAX),
2743 ANDISMask = (Mask >> 16) & UINT16_MAX;
2745 if (Use32BitInsts) {
2746 assert((ANDIMask != 0 || ANDISMask != 0) &&
2747 "No set bits in mask when using 32-bit ands for 64-bit value");
2749 if (InstCnt) *InstCnt += (
unsigned) (ANDIMask != 0) +
2751 (
unsigned) (ANDIMask != 0 && ANDISMask != 0);
2755 ANDIVal =
SDValue(CurDAG->getMachineNode(PPC::ANDI8_rec, dl, MVT::i64,
2756 ExtendToInt64(Res, dl),
2757 getI32Imm(ANDIMask, dl)),
2761 SDValue(CurDAG->getMachineNode(PPC::ANDIS8_rec, dl, MVT::i64,
2762 ExtendToInt64(Res, dl),
2763 getI32Imm(ANDISMask, dl)),
2771 Res =
SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64,
2772 ExtendToInt64(ANDIVal, dl), ANDISVal), 0);
2774 unsigned NumOfSelectInsts = 0;
2777 Res =
SDValue(CurDAG->getMachineNode(PPC::AND8, dl, MVT::i64,
2778 ExtendToInt64(Res, dl), MaskVal),
2781 *InstCnt += NumOfSelectInsts + 1;
2790 collectBitGroups(LateMask);
2791 if (BitGroups.empty())
2795 if (
Bits.size() == 64)
2796 assignRepl32BitGroups();
2799 collectValueRotInfo();
2801 if (
Bits.size() == 32) {
2802 return Select32(
N, LateMask, InstCnt);
2804 assert(
Bits.size() == 64 &&
"Not 64 bits here?");
2805 return Select64(
N, LateMask, InstCnt);
2811 void eraseMatchingBitGroups(
function_ref<
bool(
const BitGroup &)>
F) {
2817 bool NeedMask =
false;
2837 getValueBits(
SDValue(
N, 0),
N->getValueType(0).getSizeInBits());
2842 LLVM_DEBUG(
dbgs() <<
"Considering bit-permutation-based instruction"
2843 " selection for: ");
2847 computeRotationAmounts();
2860 unsigned InstCnt = 0, InstCntLateMask = 0;
2863 LLVM_DEBUG(
dbgs() <<
"\t\tisel would use " << InstCnt <<
" instructions\n");
2868 <<
" instructions\n");
2870 if (InstCnt <= InstCntLateMask) {
2880class IntegerCompareEliminator {
2885 enum ExtOrTruncConversion {
Ext, Trunc };
2893 enum SetccInGPROpts { ZExtOrig, ZExtInvert, SExtOrig, SExtInvert };
2903 enum ZeroCompare { GEZExt, GESExt, LEZExt, LESExt };
2910 SDValue addExtOrTrunc(
SDValue NatWidthRes, ExtOrTruncConversion Conv);
2914 int64_t RHSValue,
SDLoc dl);
2916 int64_t RHSValue,
SDLoc dl);
2918 int64_t RHSValue,
SDLoc dl);
2920 int64_t RHSValue,
SDLoc dl);
2925 PPCDAGToDAGISel *Sel) : CurDAG(DAG), S(Sel) {
2928 "Only expecting to use this on 64 bit targets.");
2933 switch (
N->getOpcode()) {
2944 return tryEXTEND(
N);
2948 return tryLogicOpOfCompares(
N);
2959 "Expecting a zero/sign extend node!");
2964 N->getOperand(0).getValueType() == MVT::i1 &&
2966 WideRes = computeLogicOpInGPR(
N->getOperand(0));
2967 else if (
N->getOperand(0).getOpcode() !=
ISD::SETCC)
2971 getSETCCInGPR(
N->getOperand(0),
2973 SetccInGPROpts::SExtOrig : SetccInGPROpts::ZExtOrig);
2980 bool Output32Bit =
N->getValueType(0) == MVT::i32;
2986 if (Input32Bit != Output32Bit)
2987 ConvOp = addExtOrTrunc(WideRes, Input32Bit ? ExtOrTruncConversion::Ext :
2988 ExtOrTruncConversion::Trunc);
2996SDNode *IntegerCompareEliminator::tryLogicOpOfCompares(
SDNode *
N) {
2997 if (
N->getValueType(0) != MVT::i1)
3000 "Expected a logic operation on setcc results.");
3002 if (!LoweredLogical)
3007 unsigned SubRegToExtract = IsBitwiseNegate ? PPC::sub_eq : PPC::sub_gt;
3016 if (IsBitwiseNegate &&
3019 else if (IsBitwiseNegate)
3021 OpToConvToRecForm = LoweredLogical.
getOperand(0);
3025 OpToConvToRecForm = LoweredLogical;
3035 if (NewOpc != -1 && IsBitwiseNegate) {
3038 "Expected a PPC::XORI8 only for bitwise negation.");
3040 std::vector<SDValue> Ops;
3041 for (
int i = 0, e = OpToConvToRecForm.
getNumOperands(); i < e; i++)
3042 Ops.push_back(OpToConvToRecForm.
getOperand(i));
3047 MVT::Glue, Ops), 0);
3049 assert((NewOpc != -1 || !IsBitwiseNegate) &&
3050 "No record form available for AND8/OR8/XOR8?");
3053 dl, MVT::i64, MVT::Glue, LHS, RHS),
3065 MVT::i1, CR0Reg, SRIdxVal,
3078SDValue IntegerCompareEliminator::computeLogicOpInGPR(
SDValue LogicOp) {
3080 "Can only handle logic operations here.");
3082 "Can only handle logic operations on i1 values here.");
3094 unsigned OperandOpcode = Operand.
getOpcode();
3096 return getSETCCInGPR(Operand, SetccInGPROpts::ZExtOrig);
3101 PPC::RLDICL, dl, InVT, InputOp,
3102 S->getI64Imm(0, dl),
3103 S->getI64Imm(63, dl)), 0);
3105 return computeLogicOpInGPR(Operand);
3114 if (!LHS || (!RHS && !IsBitwiseNegation))
3117 NumLogicOpsOnComparison++;
3120 if (
LHS.getValueType() == MVT::i32)
3121 LHS = addExtOrTrunc(LHS, ExtOrTruncConversion::Ext);
3122 if (!IsBitwiseNegation &&
RHS.getValueType() == MVT::i32)
3123 RHS = addExtOrTrunc(RHS, ExtOrTruncConversion::Ext);
3128 case ISD::AND: NewOpc = PPC::AND8;
break;
3129 case ISD::OR: NewOpc = PPC::OR8;
break;
3130 case ISD::XOR: NewOpc = PPC::XOR8;
break;
3133 if (IsBitwiseNegation) {
3134 RHS = S->getI64Imm(1, dl);
3135 NewOpc = PPC::XORI8;
3146SDValue IntegerCompareEliminator::signExtendInputIfNeeded(
SDValue Input) {
3148 "Can only sign-extend 32-bit values here.");
3156 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3158 LoadSDNode *InputLoad = dyn_cast<LoadSDNode>(Input);
3162 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3167 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3170 SignExtensionsAdded++;
3172 MVT::i64, Input), 0);
3179SDValue IntegerCompareEliminator::zeroExtendInputIfNeeded(
SDValue Input) {
3181 "Can only zero-extend 32-bit values here.");
3191 if (IsTruncateOfZExt)
3192 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3196 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3198 LoadSDNode *InputLoad = dyn_cast<LoadSDNode>(Input);
3201 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3205 ZeroExtensionsAdded++;
3207 S->getI64Imm(0, dl),
3208 S->getI64Imm(32, dl)), 0);
3215SDValue IntegerCompareEliminator::addExtOrTrunc(
SDValue NatWidthRes,
3216 ExtOrTruncConversion Conv) {
3217 SDLoc dl(NatWidthRes);
3221 if (Conv == ExtOrTruncConversion::Ext) {
3226 ImDef, NatWidthRes, SubRegIdx), 0);
3229 assert(Conv == ExtOrTruncConversion::Trunc &&
3230 "Unknown convertion between 32 and 64 bit values.");
3236 NatWidthRes, SubRegIdx), 0);
3242IntegerCompareEliminator::getCompoundZeroComparisonInGPR(
SDValue LHS,
SDLoc dl,
3243 ZeroCompare CmpTy) {
3244 EVT InVT =
LHS.getValueType();
3245 bool Is32Bit = InVT == MVT::i32;
3250 case ZeroCompare::GEZExt:
3251 case ZeroCompare::GESExt:
3253 dl, InVT, LHS, LHS), 0);
3255 case ZeroCompare::LEZExt:
3256 case ZeroCompare::LESExt: {
3259 LHS = signExtendInputIfNeeded(LHS);
3264 Neg, S->getI64Imm(1, dl),
3265 S->getI64Imm(63, dl)), 0);
3269 S->getI64Imm(~0ULL, dl)), 0);
3279 (CmpTy == ZeroCompare::GEZExt || CmpTy == ZeroCompare::LEZExt))
3281 ToExtend, S->getI64Imm(1, dl),
3282 S->getI64Imm(63, dl)), 0);
3284 (CmpTy == ZeroCompare::GESExt || CmpTy == ZeroCompare::LESExt))
3286 S->getI64Imm(63, dl)), 0);
3288 assert(Is32Bit &&
"Should have handled the 32-bit sequences above.");
3291 case ZeroCompare::GEZExt: {
3292 SDValue ShiftOps[] = { ToExtend, S->getI32Imm(1, dl), S->getI32Imm(31, dl),
3293 S->getI32Imm(31, dl) };
3297 case ZeroCompare::GESExt:
3299 S->getI32Imm(31, dl)), 0);
3300 case ZeroCompare::LEZExt:
3302 S->getI32Imm(1, dl)), 0);
3303 case ZeroCompare::LESExt:
3305 S->getI32Imm(-1, dl)), 0);
3316IntegerCompareEliminator::get32BitZExtCompare(
SDValue LHS,
SDValue RHS,
3318 int64_t RHSValue,
SDLoc dl) {
3322 bool IsRHSZero = RHSValue == 0;
3323 bool IsRHSOne = RHSValue == 1;
3324 bool IsRHSNegOne = RHSValue == -1LL;
3334 SDValue ShiftOps[] = { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl),
3335 S->getI32Imm(31, dl) };
3346 SDValue ShiftOps[] = { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl),
3347 S->getI32Imm(31, dl) };
3351 S->getI32Imm(1, dl)), 0);
3357 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt);
3363 IsRHSZero = RHSConst && RHSConst->
isZero();
3374 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LEZExt);
3378 LHS = signExtendInputIfNeeded(LHS);
3379 RHS = signExtendInputIfNeeded(RHS);
3384 S->getI64Imm(1, dl), S->getI64Imm(63, dl)),
3388 MVT::i64, Shift, S->getI32Imm(1, dl)), 0);
3396 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt);
3402 LHS = signExtendInputIfNeeded(LHS);
3403 RHS = signExtendInputIfNeeded(RHS);
3407 Neg, S->getI32Imm(1, dl), S->getI32Imm(63, dl)), 0);
3413 IsRHSZero = RHSConst && RHSConst->
isZero();
3425 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LEZExt);
3429 SDValue ShiftOps[] = {
LHS, S->getI32Imm(1, dl), S->getI32Imm(31, dl),
3430 S->getI32Imm(31, dl) };
3438 LHS = signExtendInputIfNeeded(LHS);
3439 RHS = signExtendInputIfNeeded(RHS);
3443 SUBFNode, S->getI64Imm(1, dl),
3444 S->getI64Imm(63, dl)), 0);
3455 LHS = zeroExtendInputIfNeeded(LHS);
3456 RHS = zeroExtendInputIfNeeded(RHS);
3461 Subtract, S->getI64Imm(1, dl),
3462 S->getI64Imm(63, dl)), 0);
3464 S->getI32Imm(1, dl)), 0);
3475 LHS = zeroExtendInputIfNeeded(LHS);
3476 RHS = zeroExtendInputIfNeeded(RHS);
3480 Subtract, S->getI64Imm(1, dl),
3481 S->getI64Imm(63, dl)), 0);
3489IntegerCompareEliminator::get32BitSExtCompare(
SDValue LHS,
SDValue RHS,
3491 int64_t RHSValue,
SDLoc dl) {
3495 bool IsRHSZero = RHSValue == 0;
3496 bool IsRHSOne = RHSValue == 1;
3497 bool IsRHSNegOne = RHSValue == -1LL;
3510 SDValue SHLOps[] = { Cntlzw, S->getI32Imm(27, dl),
3511 S->getI32Imm(5, dl), S->getI32Imm(31, dl) };
3529 { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl), S->getI32Imm(31, dl) };
3534 S->getI32Imm(1, dl)), 0);
3541 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt);
3547 IsRHSZero = RHSConst && RHSConst->
isZero();
3556 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LESExt);
3559 LHS = signExtendInputIfNeeded(LHS);
3560 RHS = signExtendInputIfNeeded(RHS);
3566 SUBFNode, S->getI64Imm(1, dl),
3567 S->getI64Imm(63, dl)), 0);
3569 S->getI32Imm(-1, dl)), 0);
3576 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt);
3581 LHS = signExtendInputIfNeeded(LHS);
3582 RHS = signExtendInputIfNeeded(RHS);
3586 S->getI64Imm(63, dl)), 0);
3592 IsRHSZero = RHSConst && RHSConst->
isZero();
3603 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LESExt);
3607 S->getI32Imm(31, dl)), 0);
3612 LHS = signExtendInputIfNeeded(LHS);
3613 RHS = signExtendInputIfNeeded(RHS);
3617 SUBFNode, S->getI64Imm(63, dl)), 0);
3628 LHS = zeroExtendInputIfNeeded(LHS);
3629 RHS = zeroExtendInputIfNeeded(RHS);
3634 S->getI32Imm(1, dl), S->getI32Imm(63,dl)),
3637 S->getI32Imm(-1, dl)), 0);
3648 LHS = zeroExtendInputIfNeeded(LHS);
3649 RHS = zeroExtendInputIfNeeded(RHS);
3653 Subtract, S->getI64Imm(63, dl)), 0);
3661IntegerCompareEliminator::get64BitZExtCompare(
SDValue LHS,
SDValue RHS,
3663 int64_t RHSValue,
SDLoc dl) {
3667 bool IsRHSZero = RHSValue == 0;
3668 bool IsRHSOne = RHSValue == 1;
3669 bool IsRHSNegOne = RHSValue == -1LL;
3680 S->getI64Imm(58, dl),
3681 S->getI64Imm(63, dl)), 0);
3692 Xor, S->getI32Imm(~0U, dl)), 0);
3702 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt);
3705 IsRHSZero = RHSConst && RHSConst->
isZero();
3714 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LEZExt);
3717 S->getI64Imm(1, dl),
3718 S->getI64Imm(63, dl)), 0);
3721 S->getI64Imm(63, dl)), 0);
3726 ShiftR, ShiftL, SubtractCarry), 0);
3734 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt);
3738 S->getI64Imm(~0ULL, dl)), 0);
3742 S->getI64Imm(1, dl),
3743 S->getI64Imm(63, dl)), 0);
3747 IsRHSZero = RHSConst && RHSConst->
isZero();
3757 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LEZExt);
3760 S->getI64Imm(1, dl),
3761 S->getI64Imm(63, dl)), 0);
3764 LHS, S->getI64Imm(63, dl)), 0);
3767 RHS, S->getI64Imm(1, dl),
3768 S->getI64Imm(63, dl)), 0);
3774 SRDINode, SRADINode, SUBFC8Carry), 0);
3776 ADDE8Node, S->getI64Imm(1, dl)), 0);
3791 LHS, LHS, SUBFC8Carry), 0);
3793 SUBFE8Node, S->getI64Imm(1, dl)), 0);
3808 LHS, LHS, SubtractCarry), 0);
3818IntegerCompareEliminator::get64BitSExtCompare(
SDValue LHS,
SDValue RHS,
3820 int64_t RHSValue,
SDLoc dl) {
3824 bool IsRHSZero = RHSValue == 0;
3825 bool IsRHSOne = RHSValue == 1;
3826 bool IsRHSNegOne = RHSValue == -1LL;
3838 AddInput, S->getI32Imm(~0U, dl)), 0);
3851 Xor, S->getI32Imm(0, dl)), 0);
3853 SC,
SC.getValue(1)), 0);
3861 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt);
3864 IsRHSZero = RHSConst && RHSConst->
isZero();
3873 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LESExt);
3876 S->getI64Imm(63, dl)), 0);
3879 S->getI64Imm(1, dl),
3880 S->getI64Imm(63, dl)), 0);
3886 ShiftR, ShiftL, SubtractCarry), 0);
3895 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt);
3899 S->getI64Imm(-1, dl)), 0);
3903 S->getI64Imm(63, dl)), 0);
3907 IsRHSZero = RHSConst && RHSConst->
isZero();
3917 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LESExt);
3920 S->getI64Imm(63, dl)), 0);
3924 LHS, S->getI64Imm(63, dl)), 0);
3927 RHS, S->getI64Imm(1, dl),
3928 S->getI64Imm(63, dl)), 0);
3934 SRDINode, SRADINode, SUBFC8Carry), 0);
3937 ADDE8Node, S->getI64Imm(1, dl)), 0);
3954 LHS, SubtractCarry), 0);
3956 ExtSub, ExtSub), 0);
3970 LHS, LHS, SubCarry), 0);
3981 "An ISD::SETCC node required here.");
3989 for (
auto *CompareUse :
Compare.getNode()->users())
3994 OmittedForNonExtendUses++;
4004 SetccInGPROpts ConvOpts) {
4007 "An ISD::SETCC node required here.");
4020 cast<CondCodeSDNode>(
Compare.getOperand(CCOpNum))->get();
4021 EVT InputVT =
LHS.getValueType();
4022 if (InputVT != MVT::i32 && InputVT != MVT::i64)
4025 if (ConvOpts == SetccInGPROpts::ZExtInvert ||
4026 ConvOpts == SetccInGPROpts::SExtInvert)
4029 bool Inputs32Bit = InputVT == MVT::i32;
4034 bool IsSext = ConvOpts == SetccInGPROpts::SExtOrig ||
4035 ConvOpts == SetccInGPROpts::SExtInvert;
4037 if (IsSext && Inputs32Bit)
4038 return get32BitSExtCompare(LHS, RHS,
CC, RHSValue, dl);
4039 else if (Inputs32Bit)
4040 return get32BitZExtCompare(LHS, RHS,
CC, RHSValue, dl);
4042 return get64BitSExtCompare(LHS, RHS,
CC, RHSValue, dl);
4043 return get64BitZExtCompare(LHS, RHS,
CC, RHSValue, dl);
4048bool PPCDAGToDAGISel::tryIntCompareInGPR(
SDNode *
N) {
4049 if (
N->getValueType(0) != MVT::i32 &&
4050 N->getValueType(0) != MVT::i64)
4056 if (
TM.getOptLevel() == CodeGenOptLevel::None || !
TM.isPPC64())
4062 if (!(
CmpInGPR.getNumOccurrences() > 0) && Subtarget->isISA3_1())
4065 switch (
N->getOpcode()) {
4072 IntegerCompareEliminator ICmpElim(CurDAG,
this);
4073 if (
SDNode *New = ICmpElim.Select(
N)) {
4074 ReplaceNode(
N, New);
4082bool PPCDAGToDAGISel::tryBitPermutation(
SDNode *
N) {
4083 if (
N->getValueType(0) != MVT::i32 &&
4084 N->getValueType(0) != MVT::i64)
4090 switch (
N->getOpcode()) {
4095 if (Subtarget->isISA3_1() &&
N->getValueType(0) == MVT::i32 &&
4097 auto &OpRight =
N->getOperand(1);
4107 BitPermutationSelector BPS(CurDAG);
4108 if (
SDNode *New = BPS.Select(
N)) {
4109 ReplaceNode(
N, New);
4126 if (
LHS.getValueType() == MVT::i32) {
4131 if (isUInt<16>(Imm))
4133 getI32Imm(Imm & 0xFFFF, dl)),
4136 if (isInt<16>((
int)Imm))
4138 getI32Imm(Imm & 0xFFFF, dl)),
4151 getI32Imm(Imm >> 16, dl)), 0);
4153 getI32Imm(Imm & 0xFFFF, dl)), 0);
4159 getI32Imm(Imm & 0xFFFF, dl)), 0);
4165 getI32Imm((
int)SImm & 0xFFFF,
4170 }
else if (
LHS.getValueType() == MVT::i64) {
4175 if (isUInt<16>(Imm))
4177 getI32Imm(Imm & 0xFFFF, dl)),
4182 getI32Imm(Imm & 0xFFFF, dl)),
4194 if (isUInt<32>(Imm)) {
4196 getI64Imm(Imm >> 16, dl)), 0);
4198 getI64Imm(Imm & 0xFFFF, dl)),
4206 getI64Imm(Imm & 0xFFFF, dl)), 0);
4212 getI64Imm(SImm & 0xFFFF, dl)),
4216 }
else if (
LHS.getValueType() == MVT::f32) {
4217 if (Subtarget->hasSPE()) {
4222 Opc = PPC::EFSCMPEQ;
4230 Opc = PPC::EFSCMPLT;
4238 Opc = PPC::EFSCMPGT;
4243 }
else if (
LHS.getValueType() == MVT::f64) {
4244 if (Subtarget->hasSPE()) {
4249 Opc = PPC::EFDCMPEQ;
4257 Opc = PPC::EFDCMPLT;
4265 Opc = PPC::EFDCMPGT;
4269 Opc = Subtarget->hasVSX() ? PPC::XSCMPUDP : PPC::FCMPUD;
4271 assert(
LHS.getValueType() == MVT::f128 &&
"Unknown vt!");
4272 assert(Subtarget->hasP9Vector() &&
"XSCMPUQP requires Power9 Vector");
4273 Opc = PPC::XSCMPUQP;
4277 CurDAG->
getMachineNode(Opc, dl, MVT::i32, MVT::Other, LHS, RHS, Chain),
4341 case ISD::SETO: Invert =
true;
return 3;
4358 bool HasVSX,
bool &Swap,
bool &Negate) {
4385 if (VecVT == MVT::v4f32)
4386 return HasVSX ? PPC::XVCMPEQSP : PPC::VCMPEQFP;
4387 else if (VecVT == MVT::v2f64)
4388 return PPC::XVCMPEQDP;
4392 if (VecVT == MVT::v4f32)
4393 return HasVSX ? PPC::XVCMPGTSP : PPC::VCMPGTFP;
4394 else if (VecVT == MVT::v2f64)
4395 return PPC::XVCMPGTDP;
4399 if (VecVT == MVT::v4f32)
4400 return HasVSX ? PPC::XVCMPGESP : PPC::VCMPGEFP;
4401 else if (VecVT == MVT::v2f64)
4402 return PPC::XVCMPGEDP;
4429 if (VecVT == MVT::v16i8)
4430 return PPC::VCMPEQUB;
4431 else if (VecVT == MVT::v8i16)
4432 return PPC::VCMPEQUH;
4433 else if (VecVT == MVT::v4i32)
4434 return PPC::VCMPEQUW;
4435 else if (VecVT == MVT::v2i64)
4436 return PPC::VCMPEQUD;
4437 else if (VecVT == MVT::v1i128)
4438 return PPC::VCMPEQUQ;
4441 if (VecVT == MVT::v16i8)
4442 return PPC::VCMPGTSB;
4443 else if (VecVT == MVT::v8i16)
4444 return PPC::VCMPGTSH;
4445 else if (VecVT == MVT::v4i32)
4446 return PPC::VCMPGTSW;
4447 else if (VecVT == MVT::v2i64)
4448 return PPC::VCMPGTSD;
4449 else if (VecVT == MVT::v1i128)
4450 return PPC::VCMPGTSQ;
4453 if (VecVT == MVT::v16i8)
4454 return PPC::VCMPGTUB;
4455 else if (VecVT == MVT::v8i16)
4456 return PPC::VCMPGTUH;
4457 else if (VecVT == MVT::v4i32)
4458 return PPC::VCMPGTUW;
4459 else if (VecVT == MVT::v2i64)
4460 return PPC::VCMPGTUD;
4461 else if (VecVT == MVT::v1i128)
4462 return PPC::VCMPGTUQ;
4471bool PPCDAGToDAGISel::trySETCC(
SDNode *
N) {
4474 bool IsStrict =
N->isStrictFPOpcode();
4476 cast<CondCodeSDNode>(
N->getOperand(IsStrict ? 3 : 2))->get();
4479 bool isPPC64 = (PtrVT == MVT::i64);
4495 SDValue Ops[] = {
Op, getI32Imm(27, dl), getI32Imm(5, dl),
4496 getI32Imm(31, dl) };
4504 Op, getI32Imm(~0U, dl)), 0);
4509 SDValue Ops[] = {
Op, getI32Imm(1, dl), getI32Imm(31, dl),
4510 getI32Imm(31, dl) };
4518 SDValue Ops[] = {
T, getI32Imm(1, dl), getI32Imm(31, dl),
4519 getI32Imm(31, dl) };
4524 }
else if (Imm == ~0U) {
4531 Op, getI32Imm(1, dl)), 0);
4536 0),
Op.getValue(1));
4542 Op, getI32Imm(~0U, dl));
4549 getI32Imm(1, dl)), 0);
4552 SDValue Ops[] = { AN, getI32Imm(1, dl), getI32Imm(31, dl),
4553 getI32Imm(31, dl) };
4558 SDValue Ops[] = {
Op, getI32Imm(1, dl), getI32Imm(31, dl),
4559 getI32Imm(31, dl) };
4570 if (!IsStrict &&
LHS.getValueType().isVector()) {
4571 if (Subtarget->hasSPE())
4574 EVT VecVT =
LHS.getValueType();
4576 unsigned int VCmpInst =
4584 CurDAG->
SelectNodeTo(
N, Subtarget->hasVSX() ? PPC::XXLNOR : PPC::VNOR,
4593 if (Subtarget->useCRBits())
4598 SDValue CCReg = SelectCC(LHS, RHS,
CC, dl, Chain);
4605 if (Subtarget->hasSPE() &&
LHS.getValueType().isFloatingPoint()) {
4619 SDValue Ops[] = { IntCR, getI32Imm((32 - (3 -
Idx)) & 31, dl),
4620 getI32Imm(31, dl), getI32Imm(31, dl) };
4629 CurDAG->
SelectNodeTo(
N, PPC::XORI, MVT::i32, Tmp, getI32Imm(1, dl));
4635bool PPCDAGToDAGISel::isOffsetMultipleOf(
SDNode *
N,
unsigned Val)
const {
4641 AddrOp =
N->getOperand(1);
4656 if ((SlotAlign % Val) != 0)
4671void PPCDAGToDAGISel::transferMemOperands(
SDNode *
N,
SDNode *Result) {
4678 bool &NeedSwapOps,
bool &IsUnCmp) {
4684 SDValue TrueRes =
N->getOperand(2);
4685 SDValue FalseRes =
N->getOperand(3);
4687 if (!TrueConst || (
N->getSimpleValueType(0) != MVT::i64 &&
4688 N->getSimpleValueType(0) != MVT::i32))
4697 if ((TrueResVal < -1 || TrueResVal > 1) ||
4726 cast<CondCodeSDNode>(SetOrSelCC.
getOperand(InnerIsSel ? 4 : 2))->get();
4731 dyn_cast<ConstantSDNode>(SetOrSelCC.
getOperand(2));
4733 dyn_cast<ConstantSDNode>(SetOrSelCC.
getOperand(3));
4734 if (!SelCCTrueConst || !SelCCFalseConst)
4739 if (SelCCTVal == -1 && SelCCFVal == 1) {
4741 }
else if (SelCCTVal != 1 || SelCCFVal != -1)
4751 bool InnerSwapped =
false;
4752 if (
LHS == InnerRHS &&
RHS == InnerLHS)
4753 InnerSwapped =
true;
4754 else if (
LHS != InnerLHS ||
RHS != InnerRHS)
4765 NeedSwapOps = (InnerCC ==
ISD::SETGT) ? InnerSwapped : !InnerSwapped;
4782 NeedSwapOps = (TrueResVal == 1);
4801 NeedSwapOps = (TrueResVal == -1);
4810 LLVM_DEBUG(
dbgs() <<
"Found a node that can be lowered to a SETB: ");
4820 if (
N.getNumOperands() < 1 || !isa<ConstantSDNode>(
N.getOperand(0)) ||
4823 switch (
N.getConstantOperandVal(0)) {
4824 case Intrinsic::ppc_vsx_xvtdivdp:
4825 case Intrinsic::ppc_vsx_xvtdivsp:
4826 case Intrinsic::ppc_vsx_xvtsqrtdp:
4827 case Intrinsic::ppc_vsx_xvtsqrtsp:
4833bool PPCDAGToDAGISel::tryFoldSWTestBRCC(
SDNode *
N) {
4891bool PPCDAGToDAGISel::trySelectLoopCountIntrinsic(
SDNode *
N) {
4898 if (
LHS.getOpcode() !=
ISD::AND || !isa<ConstantSDNode>(
LHS.getOperand(1)) ||
4903 LHS.getOperand(0).getConstantOperandVal(1) != Intrinsic::loop_decrement)
4906 if (!isa<ConstantSDNode>(RHS))
4910 "Counter decrement comparison is not EQ or NE");
4913 assert(OldDecrement.
hasOneUse() &&
"loop decrement has more than one use!");
4915 SDLoc DecrementLoc(OldDecrement);
4917 SDValue DecrementOps[] = {Subtarget->
isPPC64() ? getI64Imm(1, DecrementLoc)
4918 : getI32Imm(1, DecrementLoc)};
4919 unsigned DecrementOpcode =
4920 Subtarget->
isPPC64() ? PPC::DecreaseCTR8loop : PPC::DecreaseCTRloop;
4922 MVT::i1, DecrementOps);
4924 unsigned Val =
RHS->getAsZExtVal();
4926 unsigned Opcode = IsBranchOnTrue ? PPC::BC : PPC::BCn;
4928 ReplaceUses(
LHS.getValue(0),
LHS.getOperand(1));
4932 ReplaceUses(OldDecrement.
getValue(1), ChainInput);
4936 ChainInput,
N->getOperand(0));
4939 N->getOperand(4), Chain);
4943bool PPCDAGToDAGISel::tryAsSingleRLWINM(
SDNode *
N) {
4951 unsigned SH, MB, ME;
4954 if (isRotateAndMask(Val.
getNode(), Imm,
false, SH, MB, ME)) {
4956 SDValue Ops[] = {Val, getI32Imm(SH, dl), getI32Imm(MB, dl),
4965 SDValue Ops[] = {Val, getI32Imm(0, dl), getI32Imm(MB, dl),
4973 ReplaceUses(
SDValue(
N, 0),
N->getOperand(1));
4980bool PPCDAGToDAGISel::tryAsSingleRLWINM8(
SDNode *
N) {
4997 SDValue Ops[] = {
N->getOperand(0), getI64Imm(0, dl), getI64Imm(MB - 32, dl),
4998 getI64Imm(ME - 32, dl)};
5006bool PPCDAGToDAGISel::tryAsPairOfRLDICL(
SDNode *
N) {
5014 if (isUInt<16>(Imm64))
5026 if (NumOfLeadingZeros != 0)
5027 Imm64 |= maskLeadingOnes<uint64_t>(NumOfLeadingZeros);
5039 unsigned OnesOnLeft = ME + 1;
5040 unsigned ZerosInBetween = (MB - ME + 63) & 63;
5044 getI64Imm(OnesOnLeft, Loc),
5045 getI64Imm(ZerosInBetween, Loc)),
5054 SDValue Ops[] = {Val, getI64Imm(64 - OnesOnLeft, Loc),
5055 getI64Imm(NumOfLeadingZeros, Loc)};
5060bool PPCDAGToDAGISel::tryAsSingleRLWIMI(
SDNode *
N) {
5087 if (
isRunOfOnes(~(Imm ^ Imm2), MB, ME) && !(~Imm & Imm2)) {
5090 getI32Imm(MB, dl), getI32Imm(ME, dl)};
5091 ReplaceNode(
N, CurDAG->
getMachineNode(PPC::RLWIMI, dl, MVT::i32, Ops));
5098bool PPCDAGToDAGISel::tryAsSingleRLDCL(
SDNode *
N) {
5127bool PPCDAGToDAGISel::tryAsSingleRLDICL(
SDNode *
N) {
5146 auto ImDef = CurDAG->
getMachineNode(PPC::IMPLICIT_DEF, dl, ResultType);
5164 assert(Imm < 64 &&
"Illegal shift amount");
5169 SDValue Ops[] = {Val, getI32Imm(SH, dl), getI32Imm(MB, dl)};
5174bool PPCDAGToDAGISel::tryAsSingleRLDICR(
SDNode *
N) {
5187 SDValue Ops[] = {
N->getOperand(0), getI32Imm(SH, dl), getI32Imm(MB, dl)};
5192bool PPCDAGToDAGISel::tryAsSingleRLDIMI(
SDNode *
N) {
5206 unsigned SH = 63 - ME;
5212 getI32Imm(SH, Dl), getI32Imm(MB, Dl)};
5219void PPCDAGToDAGISel::Select(
SDNode *
N) {
5221 if (
N->isMachineOpcode()) {
5234 if (tryBitPermutation(
N))
5238 if (tryIntCompareInGPR(
N))
5241 switch (
N->getOpcode()) {
5245 if (
N->getValueType(0) == MVT::i64) {
5252 auto IntrinsicID =
N->getConstantOperandVal(1);
5253 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
5254 IntrinsicID != Intrinsic::ppc_trapd &&
5255 IntrinsicID != Intrinsic::ppc_trap)
5257 unsigned Opcode = (IntrinsicID == Intrinsic::ppc_tdw ||
5258 IntrinsicID == Intrinsic::ppc_trapd)
5263 if (IntrinsicID == Intrinsic::ppc_tdw ||
5264 IntrinsicID == Intrinsic::ppc_tw) {
5265 SDValue Ops[] = {
N->getOperand(4),
N->getOperand(2),
N->getOperand(3)};
5266 int16_t SImmOperand2;
5267 int16_t SImmOperand3;
5268 int16_t SImmOperand4;
5269 bool isOperand2IntS16Immediate =
5271 bool isOperand3IntS16Immediate =
5276 if (isOperand2IntS16Immediate == isOperand3IntS16Immediate)
5277 Opcode = IntrinsicID == Intrinsic::ppc_tdw ? PPC::TD : PPC::TW;
5278 else if (isOperand3IntS16Immediate)
5280 Ops[2] = getI32Imm(
int(SImmOperand3) & 0xFFFF, dl);
5283 bool isOperand4IntS16Immediate =
5285 (void)isOperand4IntS16Immediate;
5286 assert(isOperand4IntS16Immediate &&
5287 "The 4th operand is not an Immediate");
5289 int16_t TO = int(SImmOperand4) & 0x1F;
5291 if ((TO & 0x1) != ((TO & 0x2) >> 1))
5292 TO = (TO & 0x1) ? TO + 1 : TO - 1;
5294 if ((TO & 0x8) != ((TO & 0x10) >> 1))
5295 TO = (TO & 0x8) ? TO + 8 : TO - 8;
5296 Ops[0] = getI32Imm(TO, dl);
5297 Ops[1] =
N->getOperand(3);
5298 Ops[2] = getI32Imm(
int(SImmOperand2) & 0xFFFF, dl);
5300 OpsWithMD = {Ops[0], Ops[1], Ops[2]};
5303 OpsWithMD = {getI32Imm(24, dl),
N->getOperand(2), getI32Imm(0, dl)};
5307 if (
N->getNumOperands() > MDIndex) {
5308 SDValue MDV =
N->getOperand(MDIndex);
5309 const MDNode *MD = cast<MDNodeSDNode>(MDV)->getMD();
5312 cast<MDString>(MD->
getOperand(0))->getString() ==
5313 "ppc-trap-reason") &&
5314 "Unsupported annotation data type!");
5317 "Invalid data type for annotation ppc-trap-reason!");
5319 getI32Imm(std::stoi(cast<MDString>(
5320 MD->
getOperand(i))->getString().str()), dl));
5335 auto IntID =
N->getConstantOperandVal(0);
5336 if (IntID == Intrinsic::ppc_fsels) {
5337 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2),
N->getOperand(3)};
5342 if (IntID == Intrinsic::ppc_bcdadd_p || IntID == Intrinsic::ppc_bcdsub_p) {
5343 auto Pred =
N->getConstantOperandVal(1);
5345 IntID == Intrinsic::ppc_bcdadd_p ? PPC::BCDADD_rec : PPC::BCDSUB_rec;
5347 unsigned ShiftVal = 0;
5386 EVT VTs[] = {MVT::v16i8, MVT::Glue};
5387 SDValue Ops[] = {
N->getOperand(2),
N->getOperand(3),
5393 if (Subtarget->isISA3_1()) {
5396 CurDAG->
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
5397 CR6Reg, SubRegIdx, BCDOp.
getValue(1)),
5406 SDValue Ops[] = {Move, getI32Imm((32 - (4 + ShiftVal)) & 31, dl),
5407 getI32Imm(31, dl), getI32Imm(31, dl)};
5413 CurDAG->
SelectNodeTo(
N, PPC::XORI, MVT::i32, Shift, getI32Imm(1, dl));
5419 if (!Subtarget->isISA3_1())
5421 unsigned Opcode = 0;
5425 case Intrinsic::ppc_altivec_vstribr_p:
5426 Opcode = PPC::VSTRIBR_rec;
5428 case Intrinsic::ppc_altivec_vstribl_p:
5429 Opcode = PPC::VSTRIBL_rec;
5431 case Intrinsic::ppc_altivec_vstrihr_p:
5432 Opcode = PPC::VSTRIHR_rec;
5434 case Intrinsic::ppc_altivec_vstrihl_p:
5435 Opcode = PPC::VSTRIHL_rec;
5442 EVT VTs[] = {MVT::v16i8, MVT::Glue};
5450 CurDAG->
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
5451 CR6Reg, SubRegIdx, VecStrOp.
getValue(1)),
5468 if (PPCLowering->getPointerTy(CurDAG->
getDataLayout()) != MVT::i32 ||
5469 !Subtarget->isSecurePlt() || !Subtarget->
isTargetELF() ||
5477 if (PPCLowering->getPointerTy(CurDAG->
getDataLayout()) != MVT::i32 ||
5478 !
TM.isPositionIndependent() || !Subtarget->isSecurePlt() ||
5496 ReplaceNode(
N, getGlobalBaseReg());
5500 selectFrameIndex(
N,
N);
5506 N->getOperand(0), InGlue));
5511 ReplaceNode(
N, CurDAG->
getMachineNode(PPC::ReadTB, dl, MVT::i32, MVT::i32,
5512 MVT::Other,
N->getOperand(0)));
5519 getConstantIntValue(), dl,
5520 N->getValueType(0));
5521 if (
N->getValueType(0) == MVT::i64) {
5529 assert(
N->getValueType(0) == MVT::i32 &&
5530 "Expecting i64 or i32 in PPCISD::SRA_ADDZE");
5546 if (tryTLSXFormStore(ST))
5553 EVT LoadedVT =
LD->getMemoryVT();
5560 if (tryTLSXFormLoad(LD))
5571 if (
LD->getValueType(0) != MVT::i64) {
5573 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5576 case MVT::f64: Opcode = PPC::LFDU;
break;
5577 case MVT::f32: Opcode = PPC::LFSU;
break;
5578 case MVT::i32: Opcode = PPC::LWZU;
break;
5579 case MVT::i16: Opcode = isSExt ? PPC::LHAU : PPC::LHZU;
break;
5581 case MVT::i8: Opcode = PPC::LBZU;
break;
5584 assert(
LD->getValueType(0) == MVT::i64 &&
"Unknown load result type!");
5585 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5588 case MVT::i64: Opcode = PPC::LDU;
break;
5589 case MVT::i32: Opcode = PPC::LWZU8;
break;
5590 case MVT::i16: Opcode = isSExt ? PPC::LHAU8 : PPC::LHZU8;
break;
5592 case MVT::i8: Opcode = PPC::LBZU8;
break;
5600 Opcode, dl,
LD->getValueType(0),
5601 PPCLowering->getPointerTy(CurDAG->
getDataLayout()), MVT::Other, Ops);
5602 transferMemOperands(
N, MN);
5608 if (
LD->getValueType(0) != MVT::i64) {
5610 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5613 case MVT::f64: Opcode = PPC::LFDUX;
break;
5614 case MVT::f32: Opcode = PPC::LFSUX;
break;
5615 case MVT::i32: Opcode = PPC::LWZUX;
break;
5616 case MVT::i16: Opcode = isSExt ? PPC::LHAUX : PPC::LHZUX;
break;
5618 case MVT::i8: Opcode = PPC::LBZUX;
break;
5621 assert(
LD->getValueType(0) == MVT::i64 &&
"Unknown load result type!");
5622 assert((!isSExt || LoadedVT == MVT::i16 || LoadedVT == MVT::i32) &&
5623 "Invalid sext update load");
5626 case MVT::i64: Opcode = PPC::LDUX;
break;
5627 case MVT::i32: Opcode = isSExt ? PPC::LWAUX : PPC::LWZUX8;
break;
5628 case MVT::i16: Opcode = isSExt ? PPC::LHAUX8 : PPC::LHZUX8;
break;
5630 case MVT::i8: Opcode = PPC::LBZUX8;
break;
5638 Opcode, dl,
LD->getValueType(0),
5639 PPCLowering->getPointerTy(CurDAG->
getDataLayout()), MVT::Other, Ops);
5640 transferMemOperands(
N, MN);
5648 if (tryAsSingleRLWINM(
N) || tryAsSingleRLWIMI(
N) || tryAsSingleRLDCL(
N) ||
5649 tryAsSingleRLDICL(
N) || tryAsSingleRLDICR(
N) || tryAsSingleRLWINM8(
N) ||
5650 tryAsPairOfRLDICL(
N))
5656 if (
N->getValueType(0) == MVT::i32)
5657 if (tryBitfieldInsert(
N))
5668 selectFrameIndex(
N,
N->getOperand(0).getNode(), (int64_t)Imm);
5675 if (tryAsSingleRLDIMI(
N))
5681 bool IsPPC64 = Subtarget->
isPPC64();
5683 (Imm64 & ~0xFFFFFFFFuLL) == 0) {
5687 if (ImmHi != 0 && ImmLo != 0) {
5690 getI16Imm(ImmLo, dl));
5704 bool IsPPC64 = Subtarget->
isPPC64();
5706 (Imm64 & ~0xFFFFFFFFuLL) == 0) {
5710 if (ImmHi != 0 && ImmLo != 0) {
5713 getI16Imm(ImmLo, dl));
5726 selectFrameIndex(
N,
N->getOperand(0).getNode(), (int64_t)Imm);
5733 unsigned Imm, SH, MB, ME;
5735 isRotateAndMask(
N, Imm,
true, SH, MB, ME)) {
5736 SDValue Ops[] = {
N->getOperand(0).getOperand(0),
5737 getI32Imm(SH, dl), getI32Imm(MB, dl),
5738 getI32Imm(ME, dl) };
5747 unsigned Imm, SH, MB, ME;
5749 isRotateAndMask(
N, Imm,
true, SH, MB, ME)) {
5750 SDValue Ops[] = {
N->getOperand(0).getOperand(0),
5751 getI32Imm(SH, dl), getI32Imm(MB, dl),
5752 getI32Imm(ME, dl) };
5768 unsigned Shift = llvm::countr_zero<uint64_t>(Imm);
5769 if (isInt<16>(Imm) || !Shift)
5776 if (!isInt<16>(ImmSh))
5783 N->getOperand(0), SDImm);
5786 getI32Imm(63 - Shift, dl)};
5792 N->getOperand(0), SDImm);
5795 getI32Imm(0, dl), getI32Imm(31 - Shift, dl)};
5807 EVT InVT =
N->getOperand(0).getValueType();
5808 assert((InVT == MVT::i64 || InVT == MVT::i32) &&
5809 "Invalid input type for ANDI_rec_1_EQ_BIT");
5811 unsigned Opcode = (InVT == MVT::i64) ? PPC::ANDI8_rec : PPC::ANDI_rec;
5821 CurDAG->
SelectNodeTo(
N, TargetOpcode::EXTRACT_SUBREG, MVT::i1, CR0Reg,
5822 SRIdxVal,
SDValue(AndI.getNode(), 1) );
5829 bool isPPC64 = (PtrVT == MVT::i64);
5832 if (Subtarget->useCRBits() &&
N->getOperand(0).getValueType() == MVT::i1)
5835 if (Subtarget->isISA3_0() && Subtarget->
isPPC64()) {
5836 bool NeedSwapOps =
false;
5837 bool IsUnCmp =
false;
5853 N,
N->getSimpleValueType(0) == MVT::i64 ? PPC::SETB8 : PPC::SETB,
5854 N->getValueType(0), GenCC);
5865 N->getValueType(0) == MVT::i32) {
5868 N->getOperand(0), getI32Imm(~0U, dl));
5870 N->getOperand(0),
SDValue(Tmp, 1));
5874 SDValue CCReg = SelectCC(
N->getOperand(0),
N->getOperand(1),
CC, dl);
5876 if (
N->getValueType(0) == MVT::i1) {
5884 case 0: SRI = PPC::sub_lt;
break;
5885 case 1: SRI = PPC::sub_gt;
break;
5886 case 2: SRI = PPC::sub_eq;
break;
5887 case 3: SRI = PPC::sub_un;
break;
5894 SDValue C = Inv ? NotCCBit : CCBit,
5895 NotC = Inv ? CCBit : NotCCBit;
5898 C,
N->getOperand(2)), 0);
5900 NotC,
N->getOperand(3)), 0);
5902 CurDAG->
SelectNodeTo(
N, PPC::CROR, MVT::i1, CAndT, NotCAndF);
5909 unsigned SelectCCOp;
5910 if (
N->getValueType(0) == MVT::i32)
5911 SelectCCOp = PPC::SELECT_CC_I4;
5912 else if (
N->getValueType(0) == MVT::i64)
5913 SelectCCOp = PPC::SELECT_CC_I8;
5914 else if (
N->getValueType(0) == MVT::f32) {
5915 if (Subtarget->hasP8Vector())
5916 SelectCCOp = PPC::SELECT_CC_VSSRC;
5917 else if (Subtarget->hasSPE())
5918 SelectCCOp = PPC::SELECT_CC_SPE4;
5920 SelectCCOp = PPC::SELECT_CC_F4;
5921 }
else if (
N->getValueType(0) == MVT::f64) {
5922 if (Subtarget->hasVSX())
5923 SelectCCOp = PPC::SELECT_CC_VSFRC;
5924 else if (Subtarget->hasSPE())
5925 SelectCCOp = PPC::SELECT_CC_SPE;
5927 SelectCCOp = PPC::SELECT_CC_F8;
5928 }
else if (
N->getValueType(0) == MVT::f128)
5929 SelectCCOp = PPC::SELECT_CC_F16;
5930 else if (Subtarget->hasSPE())
5931 SelectCCOp = PPC::SELECT_CC_SPE;
5932 else if (
N->getValueType(0) == MVT::v2f64 ||
5933 N->getValueType(0) == MVT::v2i64)
5934 SelectCCOp = PPC::SELECT_CC_VSRC;
5936 SelectCCOp = PPC::SELECT_CC_VRRC;
5938 SDValue Ops[] = { CCReg,
N->getOperand(2),
N->getOperand(3),
5939 getI32Imm(BROpc, dl) };
5944 if (Subtarget->hasVSX() && (
N->getValueType(0) == MVT::v2f64 ||
5945 N->getValueType(0) == MVT::v2i64)) {
5949 Op2 =
N->getOperand(SVN->
getMaskElt(1) < 2 ? 0 : 1);
5952 for (
int i = 0; i < 2; ++i)
5958 if (Op1 == Op2 &&
DM[0] == 0 &&
DM[1] == 0 &&
5964 if (
LD->isUnindexed() &&
LD->hasOneUse() && Op1.
hasOneUse() &&
5965 (
LD->getMemoryVT() == MVT::f64 ||
5966 LD->getMemoryVT() == MVT::i64) &&
5972 N->getValueType(0), Ops);
5982 unsigned tmp =
DM[0];
5989 SDValue Ops[] = { Op1, Op2, DMV };
5997 bool IsPPC64 = Subtarget->
isPPC64();
5998 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(0) };
6000 ? (IsPPC64 ? PPC::BDNZ8 : PPC::BDNZ)
6001 : (IsPPC64 ? PPC::BDZ8 : PPC::BDZ),
6012 unsigned PCC =
N->getConstantOperandVal(1);
6016 SDValue Pred = getI32Imm(PCC, dl);
6017 SDValue Ops[] = { Pred,
N->getOperand(2),
N->getOperand(3),
6018 N->getOperand(0),
N->getOperand(4) };
6023 if (tryFoldSWTestBRCC(
N))
6025 if (trySelectLoopCountIntrinsic(
N))
6031 if (
N->getOperand(2).getValueType() == MVT::i1) {
6036 case PPC::PRED_LT: Opc = PPC::CRANDC; Swap =
true;
break;
6037 case PPC::PRED_LE: Opc = PPC::CRORC; Swap =
true;
break;
6038 case PPC::PRED_EQ: Opc = PPC::CREQV; Swap =
false;
break;
6039 case PPC::PRED_GE: Opc = PPC::CRORC; Swap =
false;
break;
6040 case PPC::PRED_GT: Opc = PPC::CRANDC; Swap =
false;
break;
6041 case PPC::PRED_NE: Opc = PPC::CRXOR; Swap =
false;
break;
6054 N->getOperand(Swap ? 3 : 2),
6055 N->getOperand(Swap ? 2 : 3)), 0);
6056 CurDAG->
SelectNodeTo(
N, PPC::BC, MVT::Other, BitComp,
N->getOperand(4),
6066 N->getOperand(4),
N->getOperand(0) };
6074 unsigned Opc =
Target.getValueType() == MVT::i32 ? PPC::MTCTR : PPC::MTCTR8;
6075 unsigned Reg =
Target.getValueType() == MVT::i32 ? PPC::BCTR : PPC::BCTR8;
6082 const bool isPPC64 = Subtarget->
isPPC64();
6083 const bool isELFABI = Subtarget->
isSVR4ABI();
6084 const bool isAIXABI = Subtarget->
isAIXABI();
6090 "PowerPC doesn't support tiny or kernel code models.");
6101 auto replaceWith = [
this, &dl](
unsigned OpCode,
SDNode *TocEntry,
6106 if (OpCode == PPC::ADDItoc || OpCode == PPC::ADDItoc8)
6112 transferMemOperands(TocEntry, MN);
6114 ReplaceNode(TocEntry, MN);
6122 assert(
TM.isPositionIndependent() &&
6123 "32-bit ELF can only have TOC entries in position independent"
6126 replaceWith(PPC::LWZtoc,
N, MVT::i32);
6130 assert(isAIXABI &&
"ELF ABI already handled");
6133 replaceWith(PPC::ADDItoc,
N, MVT::i32);
6137 replaceWith(PPC::LWZtoc,
N, MVT::i32);
6142 assert(isAIXABI &&
"ELF ABI handled in common SelectCode");
6145 replaceWith(PPC::ADDItoc8,
N, MVT::i64);
6155 assert((isPPC64 || (isAIXABI && !isPPC64)) &&
"We are dealing with 64-bit"
6156 " ELF/AIX or 32-bit AIX in the following.");
6177 SDValue TOCbase =
N->getOperand(1);
6181 isPPC64 ? PPC::ADDIStocHA8 : PPC::ADDIStocHA, dl, VT, TOCbase, GA);
6188 dl, VT,
SDValue(Tmp, 0), GA));
6192 if (PPCLowering->isAccessedAsGotIndirect(GA)) {
6196 isPPC64 ? PPC::LDtocL : PPC::LWZtocL, dl, VT, GA,
SDValue(Tmp, 0));
6198 transferMemOperands(
N, MN);
6203 assert(isPPC64 &&
"TOC_ENTRY already handled for 32-bit.");
6212 "PPCISD::PPC32_PICGOT is only supported for 32-bit SVR4");
6221 assert(isa<ConstantSDNode>(
N->getOperand(0)) &&
6222 isa<ConstantSDNode>(
N->getOperand(1)) &&
6223 "Invalid operand on VADD_SPLAT!");
6225 int Elt =
N->getConstantOperandVal(0);
6226 int EltSize =
N->getConstantOperandVal(1);
6227 unsigned Opc1, Opc2, Opc3;
6231 Opc1 = PPC::VSPLTISB;
6232 Opc2 = PPC::VADDUBM;
6233 Opc3 = PPC::VSUBUBM;
6235 }
else if (EltSize == 2) {
6236 Opc1 = PPC::VSPLTISH;
6237 Opc2 = PPC::VADDUHM;
6238 Opc3 = PPC::VSUBUHM;
6241 assert(EltSize == 4 &&
"Invalid element size on VADD_SPLAT!");
6242 Opc1 = PPC::VSPLTISW;
6243 Opc2 = PPC::VADDUWM;
6244 Opc3 = PPC::VSUBUWM;
6248 if ((Elt & 1) == 0) {
6255 SDValue EltVal = getI32Imm(Elt >> 1, dl);
6260 }
else if (Elt > 0) {
6267 SDValue EltVal = getI32Imm(Elt - 16, dl);
6269 EltVal = getI32Imm(-16, dl);
6281 SDValue EltVal = getI32Imm(Elt + 16, dl);
6283 EltVal = getI32Imm(-16, dl);
6294 if (!Subtarget->hasAltivec() || Subtarget->hasDirectMove())
6298 if (
Type != MVT::v16i8 &&
Type != MVT::v8i16)
6307 isOffsetMultipleOf(
N, 16))
6313 unsigned LIOpcode = Subtarget->
isPPC64() ? PPC::LI8 : PPC::LI;
6328 unsigned SplatOp = (
Type == MVT::v16i8) ? PPC::VSPLTB : PPC::VSPLTH;
6329 unsigned SplatElemIndex =
6338 {ZeroReg,
N->getOperand(1),
N->getOperand(0)});
6340 SDNode *LoadHigh = LoadLow;
6341 if (
Type == MVT::v8i16) {
6343 PPC::LVX, dl, MVT::v16i8, MVT::Other,
6345 LIOpcode, dl, MVT::i32,
6348 N->getOperand(1),
SDValue(LoadLow, 1)});
6352 transferMemOperands(
N, LoadHigh);
6377 "Only OR nodes are supported for CMPB");
6380 if (!Subtarget->hasCMPB())
6383 if (
N->getValueType(0) != MVT::i32 &&
6384 N->getValueType(0) != MVT::i64)
6387 EVT VT =
N->getValueType(0);
6390 bool BytesFound[8] = {
false,
false,
false,
false,
false,
false,
false,
false};
6393 auto IsByteSelectCC = [
this](
SDValue O,
unsigned &
b,
6400 if (!isa<ConstantSDNode>(
O.getOperand(2)) ||
6401 !isa<ConstantSDNode>(
O.getOperand(3)))
6404 uint64_t PM =
O.getConstantOperandVal(2);
6405 uint64_t PAlt =
O.getConstantOperandVal(3);
6406 for (b = 0;
b < 8; ++
b) {
6408 if (PM && (PM & Mask) == PM && (PAlt &
Mask) == PAlt)
6417 if (!isa<ConstantSDNode>(
O.getOperand(1)) ||
6418 O.getConstantOperandVal(1) != 0) {
6419 SDValue Op0 =
O.getOperand(0), Op1 =
O.getOperand(1);
6449 isa<ConstantSDNode>(
O.getOperand(1))) {
6451 uint64_t ULim =
O.getConstantOperandVal(1);
6452 if (ULim != (UINT64_C(1) << b*8))
6475 if (!isa<ConstantSDNode>(
Op.getOperand(1)))
6477 if (
Op.getConstantOperandVal(1) != (UINT64_C(0xFF) << (8*
b)))
6482 XOR =
XOR.getOperand(0);
6490 if (!isa<ConstantSDNode>(
Op.getOperand(1)))
6492 unsigned Bits =
Op.getValueSizeInBits();
6495 if (
Op.getConstantOperandVal(1) !=
Bits-8)
6500 XOR =
XOR.getOperand(0);
6513 while (!
Queue.empty()) {
6516 for (
const SDValue &O :
V.getNode()->ops()) {
6522 }
else if (IsByteSelectCC(O, b, M,
A, OLHS, ORHS)) {
6526 BytesFound[
b] =
true;
6529 }
else if ((LHS == ORHS && RHS == OLHS) ||
6530 (RHS == ORHS && LHS == OLHS)) {
6531 BytesFound[
b] =
true;
6543 unsigned LastB = 0, BCnt = 0;
6544 for (
unsigned i = 0; i < 8; ++i)
6545 if (BytesFound[LastB]) {
6550 if (!LastB || BCnt < 2)
6555 if (
LHS.getValueType() != VT) {
6562 bool NonTrivialMask = ((int64_t) Mask) != INT64_C(-1);
6563 if (NonTrivialMask && !Alt) {
6591 if (!Subtarget->useCRBits())
6599 if (
N->getOperand(0).getValueType() != MVT::i1)
6602 if (!
N->hasOneUse())
6606 EVT VT =
N->getValueType(0);
6623 User->getValueType(0), {O0, O1});
6628 SDValue TrueRes = TryFold(ConstTrue);
6629 if (!TrueRes || TrueRes.
isUndef())
6631 SDValue FalseRes = TryFold(ConstFalse);
6632 if (!FalseRes || FalseRes.
isUndef())
6638 if (!isInt<16>(True) || !isInt<16>(False))
6645 ConstTrue = TrueRes;
6646 ConstFalse = FalseRes;
6647 }
while (
N->hasOneUse());
6650void PPCDAGToDAGISel::PreprocessISelDAG() {
6653 bool MadeChange =
false;
6660 switch (
N->getOpcode()) {
6663 Res = combineToCMPB(
N);
6668 foldBoolExts(Res,
N);
6688void PPCDAGToDAGISel::PostprocessISelDAG() {
6690 if (
TM.getOptLevel() == CodeGenOptLevel::None)
6695 PeepholePPC64ZExt();
6703bool PPCDAGToDAGISel::AllUsersSelectZero(
SDNode *
N) {
6705 if (!
User->isMachineOpcode())
6707 if (
User->getMachineOpcode() != PPC::SELECT_I4 &&
6708 User->getMachineOpcode() != PPC::SELECT_I8)
6732void PPCDAGToDAGISel::SwapAllSelectUsers(
SDNode *
N) {
6735 assert((
User->getMachineOpcode() == PPC::SELECT_I4 ||
6736 User->getMachineOpcode() == PPC::SELECT_I8) &&
6737 "Must have all select users");
6754 ReplaceUses(
User, ResNode);
6758void PPCDAGToDAGISel::PeepholeCROps() {
6764 if (!MachineNode || MachineNode->
use_empty())
6766 SDNode *ResNode = MachineNode;
6768 bool Op1Set =
false, Op1Unset =
false,
6770 Op2Set =
false, Op2Unset =
false,
6785 if (
Op.isMachineOpcode()) {
6786 if (
Op.getMachineOpcode() == PPC::CRSET)
6788 else if (
Op.getMachineOpcode() == PPC::CRUNSET)
6790 else if ((
Op.getMachineOpcode() == PPC::CRNOR &&
6791 Op.getOperand(0) ==
Op.getOperand(1)) ||
6792 Op.getMachineOpcode() == PPC::CRNOT)
6799 case PPC::SELECT_I4:
6800 case PPC::SELECT_I8:
6801 case PPC::SELECT_F4:
6802 case PPC::SELECT_F8:
6803 case PPC::SELECT_SPE:
6804 case PPC::SELECT_SPE4:
6805 case PPC::SELECT_VRRC:
6806 case PPC::SELECT_VSFRC:
6807 case PPC::SELECT_VSSRC:
6808 case PPC::SELECT_VSRC: {
6810 if (
Op.isMachineOpcode()) {
6811 if (
Op.getMachineOpcode() == PPC::CRSET)
6813 else if (
Op.getMachineOpcode() == PPC::CRUNSET)
6815 else if ((
Op.getMachineOpcode() == PPC::CRNOR &&
6816 Op.getOperand(0) ==
Op.getOperand(1)) ||
6817 Op.getMachineOpcode() == PPC::CRNOT)
6824 bool SelectSwap =
false;
6837 else if (Op1Unset || Op2Unset)
6853 else if (AllUsersSelectZero(MachineNode)) {
6876 else if (Op1Unset || Op2Unset)
6892 else if (AllUsersSelectZero(MachineNode)) {
6903 else if (Op1Set || Op2Set)
6925 else if (AllUsersSelectZero(MachineNode)) {
6965 else if (AllUsersSelectZero(MachineNode)) {
6973 if (Op1Set || Op2Set)
6999 else if (AllUsersSelectZero(MachineNode)) {
7039 else if (AllUsersSelectZero(MachineNode)) {
7056 else if (Op1Unset || Op2Set)
7075 else if (AllUsersSelectZero(MachineNode)) {
7087 else if (Op1Set || Op2Unset)
7111 else if (AllUsersSelectZero(MachineNode)) {
7118 case PPC::SELECT_I4:
7119 case PPC::SELECT_I8:
7120 case PPC::SELECT_F4:
7121 case PPC::SELECT_F8:
7122 case PPC::SELECT_SPE:
7123 case PPC::SELECT_SPE4:
7124 case PPC::SELECT_VRRC:
7125 case PPC::SELECT_VSFRC:
7126 case PPC::SELECT_VSSRC:
7127 case PPC::SELECT_VSRC:
7159 SwapAllSelectUsers(MachineNode);
7161 if (ResNode != MachineNode) {
7168 ReplaceUses(MachineNode, ResNode);
7174 }
while (IsModified);
7285 if (!Op0OK && !Op1OK)
7308 if (!Op0OK && !Op1OK)
7322void PPCDAGToDAGISel::PeepholePPC64ZExt() {
7337 bool MadeChange =
false;
7341 if (
N->use_empty() || !
N->isMachineOpcode())
7344 if (
N->getMachineOpcode() != PPC::RLDICL)
7347 if (
N->getConstantOperandVal(1) != 0 ||
7348 N->getConstantOperandVal(2) != 32)
7383 bool OutsideUse =
false;
7384 for (
SDNode *PN : ToPromote) {
7386 if (!ToPromote.count(UN) && UN != ISR.
getNode()) {
7404 for (
SDNode *PN : ToPromote) {
7406 switch (PN->getMachineOpcode()) {
7409 case PPC::RLWINM: NewOpcode = PPC::RLWINM8;
break;
7410 case PPC::RLWNM: NewOpcode = PPC::RLWNM8;
break;
7411 case PPC::SLW: NewOpcode = PPC::SLW8;
break;
7412 case PPC::SRW: NewOpcode = PPC::SRW8;
break;
7413 case PPC::LI: NewOpcode = PPC::LI8;
break;
7414 case PPC::LIS: NewOpcode = PPC::LIS8;
break;
7415 case PPC::LHBRX: NewOpcode = PPC::LHBRX8;
break;
7416 case PPC::LWBRX: NewOpcode = PPC::LWBRX8;
break;
7417 case PPC::CNTLZW: NewOpcode = PPC::CNTLZW8;
break;
7418 case PPC::CNTTZW: NewOpcode = PPC::CNTTZW8;
break;
7419 case PPC::RLWIMI: NewOpcode = PPC::RLWIMI8;
break;
7420 case PPC::OR: NewOpcode = PPC::OR8;
break;
7421 case PPC::SELECT_I4: NewOpcode = PPC::SELECT_I8;
break;
7422 case PPC::ORI: NewOpcode = PPC::ORI8;
break;
7423 case PPC::ORIS: NewOpcode = PPC::ORIS8;
break;
7424 case PPC::AND: NewOpcode = PPC::AND8;
break;
7426 NewOpcode = PPC::ANDI8_rec;
7428 case PPC::ANDIS_rec:
7429 NewOpcode = PPC::ANDIS8_rec;
7440 if (!ToPromote.count(
V.getNode()) &&
V.getValueType() == MVT::i32 &&
7441 !isa<ConstantSDNode>(V)) {
7458 for (
unsigned i = 0, ie = VTs.
NumVTs; i != ie; ++i)
7459 if (VTs.
VTs[i] == MVT::i32)
7492 if (!
N->isMachineOpcode())
7494 unsigned Opc =
N->getMachineOpcode();
7498 if (Opc == PPC::XXPERMDIs) {
7499 return isa<ConstantSDNode>(
N->getOperand(1)) &&
7500 N->getConstantOperandVal(1) == 2;
7501 }
else if (Opc == PPC::XXPERMDI || Opc == PPC::XXSLDWI) {
7502 return N->getOperand(0) ==
N->getOperand(1) &&
7503 isa<ConstantSDNode>(
N->getOperand(2)) &&
7504 N->getConstantOperandVal(2) == 2;
7512 if (!
N->isMachineOpcode())
7514 unsigned Opc =
N->getMachineOpcode();
7563 auto SkipRCCopy = [](
SDValue V) {
7564 while (V->isMachineOpcode() &&
7565 V->getMachineOpcode() == TargetOpcode::COPY_TO_REGCLASS) {
7567 if (V->use_empty() || !V->user_begin()->isOnlyUserOf(V.getNode()))
7569 V = V->getOperand(0);
7571 return V.hasOneUse() ? V :
SDValue();
7574 SDValue VecOp = SkipRCCopy(
N->getOperand(0));
7593 if (
const GlobalVariable *GV = dyn_cast<GlobalVariable>(GA->getGlobal()))
7594 if (GV->hasAttribute(
"aix-small-tls"))
7615 if (!(Subtarget.hasAIXSmallLocalDynamicTLS() ||
7656 if (
N->getMachineOpcode() != PPC::ADDI8)
7661 SDValue InitialADDI =
N->getOperand(0);
7672 assert(GA &&
"Expecting a valid GlobalAddressSDNode when folding addi into "
7673 "local-[exec|dynamic] accesses!");
7681 int Offset =
N->getConstantOperandVal(1);
7690void PPCDAGToDAGISel::PeepholePPC64() {
7696 if (
N->use_empty() || !
N->isMachineOpcode())
7707 unsigned StorageOpcode =
N->getMachineOpcode();
7708 bool RequiresMod4Offset =
false;
7710 switch (StorageOpcode) {
7715 case PPC::DFLOADf64:
7716 case PPC::DFLOADf32:
7717 RequiresMod4Offset =
true;
7733 case PPC::DFSTOREf64:
7734 case PPC::DFSTOREf32:
7735 RequiresMod4Offset =
true;
7753 if (!isa<ConstantSDNode>(
N->getOperand(FirstOp)))
7757 if (!
Base.isMachineOpcode())
7761 bool ReplaceFlags =
true;
7773 switch (
Base.getMachineOpcode()) {
7781 ReplaceFlags =
false;
7783 case PPC::ADDIdtprelL:
7786 case PPC::ADDItlsldL:
7789 case PPC::ADDItocL8:
7804 int MaxDisplacement = 7;
7808 MaxDisplacement = std::min((
int)Alignment.
value() - 1, MaxDisplacement);
7811 bool UpdateHBase =
false;
7814 int Offset =
N->getConstantOperandVal(FirstOp);
7816 if (Offset < 0 || Offset > MaxDisplacement) {
7820 if (
Base.getMachineOpcode() != PPC::ADDItocL8)
7831 if (HImmOpnd != ImmOpnd)
7839 if (RequiresMod4Offset) {
7841 dyn_cast<GlobalAddressSDNode>(ImmOpnd)) {
7854 if (
auto *
C = dyn_cast<ConstantSDNode>(ImmOpnd)) {
7857 if (RequiresMod4Offset && (
Offset % 4) != 0)
7865 }
else if (
Offset != 0) {
7873 assert(GA &&
"Expecting a valid GlobalAddressSDNode when folding "
7874 "addi into local-[exec|dynamic] accesses!");
7887 LLVM_DEBUG(
dbgs() <<
"Folding add-immediate into mem-op:\nBase: ");
7902 if (Alignment < 4 && (RequiresMod4Offset || (
Offset % 4) != 0)) {
7903 LLVM_DEBUG(
dbgs() <<
"Rejected this candidate for alignment.\n\n");
7908 dyn_cast<ConstantPoolSDNode>(ImmOpnd)) {
7917 Base.getOperand(0),
N->getOperand(3));
7927 if (
Base.getNode()->use_empty())
7937 return new PPCDAGToDAGISelLegacy(TM, OptLevel);
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
AMDGPU Register Bank Select
This file implements a class to represent arbitrary precision integral constant values and operations...
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
MachineBasicBlock MachineBasicBlock::iterator MBBI
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)
Module.h This file contains the declarations for the Module class.
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
unsigned const TargetRegisterInfo * TRI
cl::opt< bool > ANDIGlueBug("expose-ppc-andi-glue-bug", cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden)
static cl::opt< bool > UseBitPermRewriter("ppc-use-bit-perm-rewriter", cl::init(true), cl::desc("use aggressive ppc isel for bit permutations"), cl::Hidden)
static bool isEligibleToFoldADDIForFasterLocalAccesses(SelectionDAG *DAG, SDValue ADDIToFold)
static bool canOptimizeTLSDFormToXForm(SelectionDAG *CurDAG, SDValue Base)
static cl::opt< bool > EnableBranchHint("ppc-use-branch-hint", cl::init(true), cl::desc("Enable static hinting of branches on ppc"), cl::Hidden)
static bool hasTocDataAttr(SDValue Val)
static void foldADDIForFasterLocalAccesses(SDNode *N, SelectionDAG *DAG)
static bool isThreadPointerAcquisitionNode(SDValue Base, SelectionDAG *CurDAG)
static bool PeepholePPC64ZExtGather(SDValue Op32, SmallPtrSetImpl< SDNode * > &ToPromote)
static bool isLaneInsensitive(SDValue N)
static unsigned allUsesTruncate(SelectionDAG *CurDAG, SDNode *N)
static CodeModel::Model getCodeModel(const PPCSubtarget &Subtarget, const TargetMachine &TM, const SDNode *Node)
static void reduceVSXSwap(SDNode *N, SelectionDAG *DAG)
static bool isOpcWithIntImmediate(SDNode *N, unsigned Opc, unsigned &Imm)
static PPC::Predicate getPredicateForSetCC(ISD::CondCode CC, const EVT &VT, const PPCSubtarget *Subtarget)
static unsigned getCRIdxForSetCC(ISD::CondCode CC, bool &Invert)
getCRIdxForSetCC - Return the index of the condition register field associated with the SetCC conditi...
static bool isInt64Immediate(SDNode *N, uint64_t &Imm)
isInt64Immediate - This method tests to see if the node is a 64-bit constant operand.
static bool isInt32Immediate(SDNode *N, unsigned &Imm)
isInt32Immediate - This method tests to see if the node is a 32-bit constant operand.
static 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 cl::opt< ICmpInGPRType > CmpInGPR("ppc-gpr-icmps", cl::Hidden, cl::init(ICGPR_All), cl::desc("Specify the types of comparisons to emit GPR-only code for."), cl::values(clEnumValN(ICGPR_None, "none", "Do not modify integer comparisons."), clEnumValN(ICGPR_All, "all", "All possible int comparisons in GPRs."), clEnumValN(ICGPR_I32, "i32", "Only i32 comparisons in GPRs."), clEnumValN(ICGPR_I64, "i64", "Only i64 comparisons in GPRs."), clEnumValN(ICGPR_NonExtIn, "nonextin", "Only comparisons where inputs don't need [sz]ext."), clEnumValN(ICGPR_Zext, "zext", "Only comparisons with zext result."), clEnumValN(ICGPR_ZextI32, "zexti32", "Only i32 comparisons with zext result."), clEnumValN(ICGPR_ZextI64, "zexti64", "Only i64 comparisons with zext result."), clEnumValN(ICGPR_Sext, "sext", "Only comparisons with sext result."), clEnumValN(ICGPR_SextI32, "sexti32", "Only i32 comparisons with sext result."), clEnumValN(ICGPR_SextI64, "sexti64", "Only i64 comparisons with sext result.")))
static SDNode * selectI64ImmDirectPrefix(SelectionDAG *CurDAG, const SDLoc &dl, uint64_t Imm, unsigned &InstCnt)
static SDNode * selectI64ImmDirect(SelectionDAG *CurDAG, const SDLoc &dl, uint64_t Imm, unsigned &InstCnt)
static bool hasAIXSmallTLSAttr(SDValue Val)
static cl::opt< bool > BPermRewriterNoMasking("ppc-bit-perm-rewriter-stress-rotates", cl::desc("stress rotate selection in aggressive ppc isel for " "bit permutations"), cl::Hidden)
static bool isSWTestOp(SDValue N)
static SDNode * selectI64Imm(SelectionDAG *CurDAG, const SDLoc &dl, uint64_t Imm, unsigned *InstCnt=nullptr)
static bool isVSXSwap(SDValue N)
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
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.
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.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
void setROPProtectionHashSaveIndex(int Idx)
static int getRecordFormOpcode(unsigned Opcode)
bool is32BitELFABI() const
MVT getScalarIntVT() const
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...
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.
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.
iterator_range< user_iterator > users()
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
bool isMachineOpcode() const
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
unsigned getMachineOpcode() const
unsigned getOpcode() const
unsigned getNumOperands() const
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
virtual bool 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...
virtual bool runOnMachineFunction(MachineFunction &mf)
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
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,...
SDValue getRegister(Register Reg, EVT VT)
const TargetLowering & getTargetLoweringInfo() const
allnodes_const_iterator allnodes_begin() const
allnodes_const_iterator allnodes_end() const
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
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 getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
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.
SDValue FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDValue > Ops, SDNodeFlags Flags=SDNodeFlags())
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...
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
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.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
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.
User * getUser() const
Returns the User that contains this Use.
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.
@ C
The default llvm calling convention, compatible with C.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ 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_TLSLD_FLAG
MO_TLSLD_FLAG - If this bit is set the symbol reference is relative to TLS Local Dynamic model.
@ MO_PLT
On PPC, the 12 bits are not enough for all target operand flags.
@ MO_DTPREL_LO
These values identify relocations on immediates folded into memory operations.
@ MO_TPREL_FLAG
MO_TPREL_FLAG - If this bit is set, the symbol reference is relative to the thread pointer and the sy...
@ 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.
Implement std::hash so that hash_code can be used in STL containers.
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.