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() ||
5478 if (Subtarget->
isPPC64() || !
TM.isPositionIndependent() ||
5479 !Subtarget->isSecurePlt() || !Subtarget->
isTargetELF())
5495 ReplaceNode(
N, getGlobalBaseReg());
5499 selectFrameIndex(
N,
N);
5505 N->getOperand(0), InGlue));
5510 ReplaceNode(
N, CurDAG->
getMachineNode(PPC::ReadTB, dl, MVT::i32, MVT::i32,
5511 MVT::Other,
N->getOperand(0)));
5518 getConstantIntValue(), dl,
5519 N->getValueType(0));
5520 if (
N->getValueType(0) == MVT::i64) {
5528 assert(
N->getValueType(0) == MVT::i32 &&
5529 "Expecting i64 or i32 in PPCISD::SRA_ADDZE");
5545 if (tryTLSXFormStore(ST))
5552 EVT LoadedVT =
LD->getMemoryVT();
5559 if (tryTLSXFormLoad(LD))
5570 if (
LD->getValueType(0) != MVT::i64) {
5572 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5575 case MVT::f64: Opcode = PPC::LFDU;
break;
5576 case MVT::f32: Opcode = PPC::LFSU;
break;
5577 case MVT::i32: Opcode = PPC::LWZU;
break;
5578 case MVT::i16: Opcode = isSExt ? PPC::LHAU : PPC::LHZU;
break;
5580 case MVT::i8: Opcode = PPC::LBZU;
break;
5583 assert(
LD->getValueType(0) == MVT::i64 &&
"Unknown load result type!");
5584 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5587 case MVT::i64: Opcode = PPC::LDU;
break;
5588 case MVT::i32: Opcode = PPC::LWZU8;
break;
5589 case MVT::i16: Opcode = isSExt ? PPC::LHAU8 : PPC::LHZU8;
break;
5591 case MVT::i8: Opcode = PPC::LBZU8;
break;
5599 Opcode, dl,
LD->getValueType(0),
5600 PPCLowering->getPointerTy(CurDAG->
getDataLayout()), MVT::Other, Ops);
5601 transferMemOperands(
N, MN);
5607 if (
LD->getValueType(0) != MVT::i64) {
5609 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5612 case MVT::f64: Opcode = PPC::LFDUX;
break;
5613 case MVT::f32: Opcode = PPC::LFSUX;
break;
5614 case MVT::i32: Opcode = PPC::LWZUX;
break;
5615 case MVT::i16: Opcode = isSExt ? PPC::LHAUX : PPC::LHZUX;
break;
5617 case MVT::i8: Opcode = PPC::LBZUX;
break;
5620 assert(
LD->getValueType(0) == MVT::i64 &&
"Unknown load result type!");
5621 assert((!isSExt || LoadedVT == MVT::i16 || LoadedVT == MVT::i32) &&
5622 "Invalid sext update load");
5625 case MVT::i64: Opcode = PPC::LDUX;
break;
5626 case MVT::i32: Opcode = isSExt ? PPC::LWAUX : PPC::LWZUX8;
break;
5627 case MVT::i16: Opcode = isSExt ? PPC::LHAUX8 : PPC::LHZUX8;
break;
5629 case MVT::i8: Opcode = PPC::LBZUX8;
break;
5637 Opcode, dl,
LD->getValueType(0),
5638 PPCLowering->getPointerTy(CurDAG->
getDataLayout()), MVT::Other, Ops);
5639 transferMemOperands(
N, MN);
5647 if (tryAsSingleRLWINM(
N) || tryAsSingleRLWIMI(
N) || tryAsSingleRLDCL(
N) ||
5648 tryAsSingleRLDICL(
N) || tryAsSingleRLDICR(
N) || tryAsSingleRLWINM8(
N) ||
5649 tryAsPairOfRLDICL(
N))
5655 if (
N->getValueType(0) == MVT::i32)
5656 if (tryBitfieldInsert(
N))
5667 selectFrameIndex(
N,
N->getOperand(0).getNode(), (int64_t)Imm);
5674 if (tryAsSingleRLDIMI(
N))
5680 bool IsPPC64 = Subtarget->
isPPC64();
5682 (Imm64 & ~0xFFFFFFFFuLL) == 0) {
5686 if (ImmHi != 0 && ImmLo != 0) {
5689 getI16Imm(ImmLo, dl));
5703 bool IsPPC64 = Subtarget->
isPPC64();
5705 (Imm64 & ~0xFFFFFFFFuLL) == 0) {
5709 if (ImmHi != 0 && ImmLo != 0) {
5712 getI16Imm(ImmLo, dl));
5725 selectFrameIndex(
N,
N->getOperand(0).getNode(), (int64_t)Imm);
5732 unsigned Imm, SH, MB, ME;
5734 isRotateAndMask(
N, Imm,
true, SH, MB, ME)) {
5735 SDValue Ops[] = {
N->getOperand(0).getOperand(0),
5736 getI32Imm(SH, dl), getI32Imm(MB, dl),
5737 getI32Imm(ME, dl) };
5746 unsigned Imm, SH, MB, ME;
5748 isRotateAndMask(
N, Imm,
true, SH, MB, ME)) {
5749 SDValue Ops[] = {
N->getOperand(0).getOperand(0),
5750 getI32Imm(SH, dl), getI32Imm(MB, dl),
5751 getI32Imm(ME, dl) };
5767 unsigned Shift = llvm::countr_zero<uint64_t>(Imm);
5768 if (isInt<16>(Imm) || !Shift)
5775 if (!isInt<16>(ImmSh))
5782 N->getOperand(0), SDImm);
5785 getI32Imm(63 - Shift, dl)};
5791 N->getOperand(0), SDImm);
5794 getI32Imm(0, dl), getI32Imm(31 - Shift, dl)};
5806 EVT InVT =
N->getOperand(0).getValueType();
5807 assert((InVT == MVT::i64 || InVT == MVT::i32) &&
5808 "Invalid input type for ANDI_rec_1_EQ_BIT");
5810 unsigned Opcode = (InVT == MVT::i64) ? PPC::ANDI8_rec : PPC::ANDI_rec;
5820 CurDAG->
SelectNodeTo(
N, TargetOpcode::EXTRACT_SUBREG, MVT::i1, CR0Reg,
5821 SRIdxVal,
SDValue(AndI.getNode(), 1) );
5828 bool isPPC64 = (PtrVT == MVT::i64);
5831 if (Subtarget->useCRBits() &&
N->getOperand(0).getValueType() == MVT::i1)
5834 if (Subtarget->isISA3_0() && Subtarget->
isPPC64()) {
5835 bool NeedSwapOps =
false;
5836 bool IsUnCmp =
false;
5852 N,
N->getSimpleValueType(0) == MVT::i64 ? PPC::SETB8 : PPC::SETB,
5853 N->getValueType(0), GenCC);
5864 N->getValueType(0) == MVT::i32) {
5867 N->getOperand(0), getI32Imm(~0U, dl));
5869 N->getOperand(0),
SDValue(Tmp, 1));
5873 SDValue CCReg = SelectCC(
N->getOperand(0),
N->getOperand(1),
CC, dl);
5875 if (
N->getValueType(0) == MVT::i1) {
5883 case 0: SRI = PPC::sub_lt;
break;
5884 case 1: SRI = PPC::sub_gt;
break;
5885 case 2: SRI = PPC::sub_eq;
break;
5886 case 3: SRI = PPC::sub_un;
break;
5893 SDValue C = Inv ? NotCCBit : CCBit,
5894 NotC = Inv ? CCBit : NotCCBit;
5897 C,
N->getOperand(2)), 0);
5899 NotC,
N->getOperand(3)), 0);
5901 CurDAG->
SelectNodeTo(
N, PPC::CROR, MVT::i1, CAndT, NotCAndF);
5908 unsigned SelectCCOp;
5909 if (
N->getValueType(0) == MVT::i32)
5910 SelectCCOp = PPC::SELECT_CC_I4;
5911 else if (
N->getValueType(0) == MVT::i64)
5912 SelectCCOp = PPC::SELECT_CC_I8;
5913 else if (
N->getValueType(0) == MVT::f32) {
5914 if (Subtarget->hasP8Vector())
5915 SelectCCOp = PPC::SELECT_CC_VSSRC;
5916 else if (Subtarget->hasSPE())
5917 SelectCCOp = PPC::SELECT_CC_SPE4;
5919 SelectCCOp = PPC::SELECT_CC_F4;
5920 }
else if (
N->getValueType(0) == MVT::f64) {
5921 if (Subtarget->hasVSX())
5922 SelectCCOp = PPC::SELECT_CC_VSFRC;
5923 else if (Subtarget->hasSPE())
5924 SelectCCOp = PPC::SELECT_CC_SPE;
5926 SelectCCOp = PPC::SELECT_CC_F8;
5927 }
else if (
N->getValueType(0) == MVT::f128)
5928 SelectCCOp = PPC::SELECT_CC_F16;
5929 else if (Subtarget->hasSPE())
5930 SelectCCOp = PPC::SELECT_CC_SPE;
5931 else if (
N->getValueType(0) == MVT::v2f64 ||
5932 N->getValueType(0) == MVT::v2i64)
5933 SelectCCOp = PPC::SELECT_CC_VSRC;
5935 SelectCCOp = PPC::SELECT_CC_VRRC;
5937 SDValue Ops[] = { CCReg,
N->getOperand(2),
N->getOperand(3),
5938 getI32Imm(BROpc, dl) };
5943 if (Subtarget->hasVSX() && (
N->getValueType(0) == MVT::v2f64 ||
5944 N->getValueType(0) == MVT::v2i64)) {
5948 Op2 =
N->getOperand(SVN->
getMaskElt(1) < 2 ? 0 : 1);
5951 for (
int i = 0; i < 2; ++i)
5957 if (Op1 == Op2 &&
DM[0] == 0 &&
DM[1] == 0 &&
5963 if (
LD->isUnindexed() &&
LD->hasOneUse() && Op1.
hasOneUse() &&
5964 (
LD->getMemoryVT() == MVT::f64 ||
5965 LD->getMemoryVT() == MVT::i64) &&
5971 N->getValueType(0), Ops);
5981 unsigned tmp =
DM[0];
5988 SDValue Ops[] = { Op1, Op2, DMV };
5996 bool IsPPC64 = Subtarget->
isPPC64();
5997 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(0) };
5999 ? (IsPPC64 ? PPC::BDNZ8 : PPC::BDNZ)
6000 : (IsPPC64 ? PPC::BDZ8 : PPC::BDZ),
6011 unsigned PCC =
N->getConstantOperandVal(1);
6015 SDValue Pred = getI32Imm(PCC, dl);
6016 SDValue Ops[] = { Pred,
N->getOperand(2),
N->getOperand(3),
6017 N->getOperand(0),
N->getOperand(4) };
6022 if (tryFoldSWTestBRCC(
N))
6024 if (trySelectLoopCountIntrinsic(
N))
6030 if (
N->getOperand(2).getValueType() == MVT::i1) {
6035 case PPC::PRED_LT: Opc = PPC::CRANDC; Swap =
true;
break;
6036 case PPC::PRED_LE: Opc = PPC::CRORC; Swap =
true;
break;
6037 case PPC::PRED_EQ: Opc = PPC::CREQV; Swap =
false;
break;
6038 case PPC::PRED_GE: Opc = PPC::CRORC; Swap =
false;
break;
6039 case PPC::PRED_GT: Opc = PPC::CRANDC; Swap =
false;
break;
6040 case PPC::PRED_NE: Opc = PPC::CRXOR; Swap =
false;
break;
6053 N->getOperand(Swap ? 3 : 2),
6054 N->getOperand(Swap ? 2 : 3)), 0);
6055 CurDAG->
SelectNodeTo(
N, PPC::BC, MVT::Other, BitComp,
N->getOperand(4),
6065 N->getOperand(4),
N->getOperand(0) };
6073 unsigned Opc =
Target.getValueType() == MVT::i32 ? PPC::MTCTR : PPC::MTCTR8;
6074 unsigned Reg =
Target.getValueType() == MVT::i32 ? PPC::BCTR : PPC::BCTR8;
6081 const bool isPPC64 = Subtarget->
isPPC64();
6082 const bool isELFABI = Subtarget->
isSVR4ABI();
6083 const bool isAIXABI = Subtarget->
isAIXABI();
6089 "PowerPC doesn't support tiny or kernel code models.");
6100 auto replaceWith = [
this, &dl](
unsigned OpCode,
SDNode *TocEntry,
6105 if (OpCode == PPC::ADDItoc || OpCode == PPC::ADDItoc8)
6111 transferMemOperands(TocEntry, MN);
6113 ReplaceNode(TocEntry, MN);
6121 assert(
TM.isPositionIndependent() &&
6122 "32-bit ELF can only have TOC entries in position independent"
6125 replaceWith(PPC::LWZtoc,
N, MVT::i32);
6129 assert(isAIXABI &&
"ELF ABI already handled");
6132 replaceWith(PPC::ADDItoc,
N, MVT::i32);
6136 replaceWith(PPC::LWZtoc,
N, MVT::i32);
6141 assert(isAIXABI &&
"ELF ABI handled in common SelectCode");
6144 replaceWith(PPC::ADDItoc8,
N, MVT::i64);
6154 assert((isPPC64 || (isAIXABI && !isPPC64)) &&
"We are dealing with 64-bit"
6155 " ELF/AIX or 32-bit AIX in the following.");
6176 SDValue TOCbase =
N->getOperand(1);
6180 isPPC64 ? PPC::ADDIStocHA8 : PPC::ADDIStocHA, dl, VT, TOCbase, GA);
6187 dl, VT,
SDValue(Tmp, 0), GA));
6191 if (PPCLowering->isAccessedAsGotIndirect(GA)) {
6195 isPPC64 ? PPC::LDtocL : PPC::LWZtocL, dl, VT, GA,
SDValue(Tmp, 0));
6197 transferMemOperands(
N, MN);
6202 assert(isPPC64 &&
"TOC_ENTRY already handled for 32-bit.");
6211 "PPCISD::PPC32_PICGOT is only supported for 32-bit SVR4");
6220 assert(isa<ConstantSDNode>(
N->getOperand(0)) &&
6221 isa<ConstantSDNode>(
N->getOperand(1)) &&
6222 "Invalid operand on VADD_SPLAT!");
6224 int Elt =
N->getConstantOperandVal(0);
6225 int EltSize =
N->getConstantOperandVal(1);
6226 unsigned Opc1, Opc2, Opc3;
6230 Opc1 = PPC::VSPLTISB;
6231 Opc2 = PPC::VADDUBM;
6232 Opc3 = PPC::VSUBUBM;
6234 }
else if (EltSize == 2) {
6235 Opc1 = PPC::VSPLTISH;
6236 Opc2 = PPC::VADDUHM;
6237 Opc3 = PPC::VSUBUHM;
6240 assert(EltSize == 4 &&
"Invalid element size on VADD_SPLAT!");
6241 Opc1 = PPC::VSPLTISW;
6242 Opc2 = PPC::VADDUWM;
6243 Opc3 = PPC::VSUBUWM;
6247 if ((Elt & 1) == 0) {
6254 SDValue EltVal = getI32Imm(Elt >> 1, dl);
6259 }
else if (Elt > 0) {
6266 SDValue EltVal = getI32Imm(Elt - 16, dl);
6268 EltVal = getI32Imm(-16, dl);
6280 SDValue EltVal = getI32Imm(Elt + 16, dl);
6282 EltVal = getI32Imm(-16, dl);
6293 if (!Subtarget->hasAltivec() || Subtarget->hasDirectMove())
6297 if (
Type != MVT::v16i8 &&
Type != MVT::v8i16)
6306 isOffsetMultipleOf(
N, 16))
6312 unsigned LIOpcode = Subtarget->
isPPC64() ? PPC::LI8 : PPC::LI;
6327 unsigned SplatOp = (
Type == MVT::v16i8) ? PPC::VSPLTB : PPC::VSPLTH;
6328 unsigned SplatElemIndex =
6337 {ZeroReg,
N->getOperand(1),
N->getOperand(0)});
6339 SDNode *LoadHigh = LoadLow;
6340 if (
Type == MVT::v8i16) {
6342 PPC::LVX, dl, MVT::v16i8, MVT::Other,
6344 LIOpcode, dl, MVT::i32,
6347 N->getOperand(1),
SDValue(LoadLow, 1)});
6351 transferMemOperands(
N, LoadHigh);
6376 "Only OR nodes are supported for CMPB");
6379 if (!Subtarget->hasCMPB())
6382 if (
N->getValueType(0) != MVT::i32 &&
6383 N->getValueType(0) != MVT::i64)
6386 EVT VT =
N->getValueType(0);
6389 bool BytesFound[8] = {
false,
false,
false,
false,
false,
false,
false,
false};
6392 auto IsByteSelectCC = [
this](
SDValue O,
unsigned &
b,
6399 if (!isa<ConstantSDNode>(
O.getOperand(2)) ||
6400 !isa<ConstantSDNode>(
O.getOperand(3)))
6403 uint64_t PM =
O.getConstantOperandVal(2);
6404 uint64_t PAlt =
O.getConstantOperandVal(3);
6405 for (b = 0;
b < 8; ++
b) {
6407 if (PM && (PM & Mask) == PM && (PAlt &
Mask) == PAlt)
6416 if (!isa<ConstantSDNode>(
O.getOperand(1)) ||
6417 O.getConstantOperandVal(1) != 0) {
6418 SDValue Op0 =
O.getOperand(0), Op1 =
O.getOperand(1);
6448 isa<ConstantSDNode>(
O.getOperand(1))) {
6450 uint64_t ULim =
O.getConstantOperandVal(1);
6451 if (ULim != (UINT64_C(1) << b*8))
6474 if (!isa<ConstantSDNode>(
Op.getOperand(1)))
6476 if (
Op.getConstantOperandVal(1) != (UINT64_C(0xFF) << (8*
b)))
6481 XOR =
XOR.getOperand(0);
6489 if (!isa<ConstantSDNode>(
Op.getOperand(1)))
6491 unsigned Bits =
Op.getValueSizeInBits();
6494 if (
Op.getConstantOperandVal(1) !=
Bits-8)
6499 XOR =
XOR.getOperand(0);
6512 while (!
Queue.empty()) {
6515 for (
const SDValue &O :
V.getNode()->ops()) {
6521 }
else if (IsByteSelectCC(O, b, M,
A, OLHS, ORHS)) {
6525 BytesFound[
b] =
true;
6528 }
else if ((LHS == ORHS && RHS == OLHS) ||
6529 (RHS == ORHS && LHS == OLHS)) {
6530 BytesFound[
b] =
true;
6542 unsigned LastB = 0, BCnt = 0;
6543 for (
unsigned i = 0; i < 8; ++i)
6544 if (BytesFound[LastB]) {
6549 if (!LastB || BCnt < 2)
6554 if (
LHS.getValueType() != VT) {
6561 bool NonTrivialMask = ((int64_t) Mask) != INT64_C(-1);
6562 if (NonTrivialMask && !Alt) {
6590 if (!Subtarget->useCRBits())
6598 if (
N->getOperand(0).getValueType() != MVT::i1)
6601 if (!
N->hasOneUse())
6605 EVT VT =
N->getValueType(0);
6622 User->getValueType(0), {O0, O1});
6627 SDValue TrueRes = TryFold(ConstTrue);
6628 if (!TrueRes || TrueRes.
isUndef())
6630 SDValue FalseRes = TryFold(ConstFalse);
6631 if (!FalseRes || FalseRes.
isUndef())
6637 if (!isInt<16>(True) || !isInt<16>(False))
6644 ConstTrue = TrueRes;
6645 ConstFalse = FalseRes;
6646 }
while (
N->hasOneUse());
6649void PPCDAGToDAGISel::PreprocessISelDAG() {
6652 bool MadeChange =
false;
6659 switch (
N->getOpcode()) {
6662 Res = combineToCMPB(
N);
6667 foldBoolExts(Res,
N);
6687void PPCDAGToDAGISel::PostprocessISelDAG() {
6689 if (
TM.getOptLevel() == CodeGenOptLevel::None)
6694 PeepholePPC64ZExt();
6702bool PPCDAGToDAGISel::AllUsersSelectZero(
SDNode *
N) {
6704 if (!
User->isMachineOpcode())
6706 if (
User->getMachineOpcode() != PPC::SELECT_I4 &&
6707 User->getMachineOpcode() != PPC::SELECT_I8)
6731void PPCDAGToDAGISel::SwapAllSelectUsers(
SDNode *
N) {
6734 assert((
User->getMachineOpcode() == PPC::SELECT_I4 ||
6735 User->getMachineOpcode() == PPC::SELECT_I8) &&
6736 "Must have all select users");
6753 ReplaceUses(
User, ResNode);
6757void PPCDAGToDAGISel::PeepholeCROps() {
6763 if (!MachineNode || MachineNode->
use_empty())
6765 SDNode *ResNode = MachineNode;
6767 bool Op1Set =
false, Op1Unset =
false,
6769 Op2Set =
false, Op2Unset =
false,
6784 if (
Op.isMachineOpcode()) {
6785 if (
Op.getMachineOpcode() == PPC::CRSET)
6787 else if (
Op.getMachineOpcode() == PPC::CRUNSET)
6789 else if ((
Op.getMachineOpcode() == PPC::CRNOR &&
6790 Op.getOperand(0) ==
Op.getOperand(1)) ||
6791 Op.getMachineOpcode() == PPC::CRNOT)
6798 case PPC::SELECT_I4:
6799 case PPC::SELECT_I8:
6800 case PPC::SELECT_F4:
6801 case PPC::SELECT_F8:
6802 case PPC::SELECT_SPE:
6803 case PPC::SELECT_SPE4:
6804 case PPC::SELECT_VRRC:
6805 case PPC::SELECT_VSFRC:
6806 case PPC::SELECT_VSSRC:
6807 case PPC::SELECT_VSRC: {
6809 if (
Op.isMachineOpcode()) {
6810 if (
Op.getMachineOpcode() == PPC::CRSET)
6812 else if (
Op.getMachineOpcode() == PPC::CRUNSET)
6814 else if ((
Op.getMachineOpcode() == PPC::CRNOR &&
6815 Op.getOperand(0) ==
Op.getOperand(1)) ||
6816 Op.getMachineOpcode() == PPC::CRNOT)
6823 bool SelectSwap =
false;
6836 else if (Op1Unset || Op2Unset)
6852 else if (AllUsersSelectZero(MachineNode)) {
6875 else if (Op1Unset || Op2Unset)
6891 else if (AllUsersSelectZero(MachineNode)) {
6902 else if (Op1Set || Op2Set)
6924 else if (AllUsersSelectZero(MachineNode)) {
6964 else if (AllUsersSelectZero(MachineNode)) {
6972 if (Op1Set || Op2Set)
6998 else if (AllUsersSelectZero(MachineNode)) {
7038 else if (AllUsersSelectZero(MachineNode)) {
7055 else if (Op1Unset || Op2Set)
7074 else if (AllUsersSelectZero(MachineNode)) {
7086 else if (Op1Set || Op2Unset)
7110 else if (AllUsersSelectZero(MachineNode)) {
7117 case PPC::SELECT_I4:
7118 case PPC::SELECT_I8:
7119 case PPC::SELECT_F4:
7120 case PPC::SELECT_F8:
7121 case PPC::SELECT_SPE:
7122 case PPC::SELECT_SPE4:
7123 case PPC::SELECT_VRRC:
7124 case PPC::SELECT_VSFRC:
7125 case PPC::SELECT_VSSRC:
7126 case PPC::SELECT_VSRC:
7158 SwapAllSelectUsers(MachineNode);
7160 if (ResNode != MachineNode) {
7167 ReplaceUses(MachineNode, ResNode);
7173 }
while (IsModified);
7284 if (!Op0OK && !Op1OK)
7307 if (!Op0OK && !Op1OK)
7321void PPCDAGToDAGISel::PeepholePPC64ZExt() {
7336 bool MadeChange =
false;
7340 if (
N->use_empty() || !
N->isMachineOpcode())
7343 if (
N->getMachineOpcode() != PPC::RLDICL)
7346 if (
N->getConstantOperandVal(1) != 0 ||
7347 N->getConstantOperandVal(2) != 32)
7382 bool OutsideUse =
false;
7383 for (
SDNode *PN : ToPromote) {
7385 if (!ToPromote.count(UN) && UN != ISR.
getNode()) {
7403 for (
SDNode *PN : ToPromote) {
7405 switch (PN->getMachineOpcode()) {
7408 case PPC::RLWINM: NewOpcode = PPC::RLWINM8;
break;
7409 case PPC::RLWNM: NewOpcode = PPC::RLWNM8;
break;
7410 case PPC::SLW: NewOpcode = PPC::SLW8;
break;
7411 case PPC::SRW: NewOpcode = PPC::SRW8;
break;
7412 case PPC::LI: NewOpcode = PPC::LI8;
break;
7413 case PPC::LIS: NewOpcode = PPC::LIS8;
break;
7414 case PPC::LHBRX: NewOpcode = PPC::LHBRX8;
break;
7415 case PPC::LWBRX: NewOpcode = PPC::LWBRX8;
break;
7416 case PPC::CNTLZW: NewOpcode = PPC::CNTLZW8;
break;
7417 case PPC::CNTTZW: NewOpcode = PPC::CNTTZW8;
break;
7418 case PPC::RLWIMI: NewOpcode = PPC::RLWIMI8;
break;
7419 case PPC::OR: NewOpcode = PPC::OR8;
break;
7420 case PPC::SELECT_I4: NewOpcode = PPC::SELECT_I8;
break;
7421 case PPC::ORI: NewOpcode = PPC::ORI8;
break;
7422 case PPC::ORIS: NewOpcode = PPC::ORIS8;
break;
7423 case PPC::AND: NewOpcode = PPC::AND8;
break;
7425 NewOpcode = PPC::ANDI8_rec;
7427 case PPC::ANDIS_rec:
7428 NewOpcode = PPC::ANDIS8_rec;
7439 if (!ToPromote.count(
V.getNode()) &&
V.getValueType() == MVT::i32 &&
7440 !isa<ConstantSDNode>(V)) {
7457 for (
unsigned i = 0, ie = VTs.
NumVTs; i != ie; ++i)
7458 if (VTs.
VTs[i] == MVT::i32)
7491 if (!
N->isMachineOpcode())
7493 unsigned Opc =
N->getMachineOpcode();
7497 if (Opc == PPC::XXPERMDIs) {
7498 return isa<ConstantSDNode>(
N->getOperand(1)) &&
7499 N->getConstantOperandVal(1) == 2;
7500 }
else if (Opc == PPC::XXPERMDI || Opc == PPC::XXSLDWI) {
7501 return N->getOperand(0) ==
N->getOperand(1) &&
7502 isa<ConstantSDNode>(
N->getOperand(2)) &&
7503 N->getConstantOperandVal(2) == 2;
7511 if (!
N->isMachineOpcode())
7513 unsigned Opc =
N->getMachineOpcode();
7562 auto SkipRCCopy = [](
SDValue V) {
7563 while (V->isMachineOpcode() &&
7564 V->getMachineOpcode() == TargetOpcode::COPY_TO_REGCLASS) {
7566 if (V->use_empty() || !V->user_begin()->isOnlyUserOf(V.getNode()))
7568 V = V->getOperand(0);
7570 return V.hasOneUse() ? V :
SDValue();
7573 SDValue VecOp = SkipRCCopy(
N->getOperand(0));
7592 if (
const GlobalVariable *GV = dyn_cast<GlobalVariable>(GA->getGlobal()))
7593 if (GV->hasAttribute(
"aix-small-tls"))
7614 if (!(Subtarget.hasAIXSmallLocalDynamicTLS() ||
7655 if (
N->getMachineOpcode() != PPC::ADDI8)
7660 SDValue InitialADDI =
N->getOperand(0);
7671 assert(GA &&
"Expecting a valid GlobalAddressSDNode when folding addi into "
7672 "local-[exec|dynamic] accesses!");
7680 int Offset =
N->getConstantOperandVal(1);
7689void PPCDAGToDAGISel::PeepholePPC64() {
7695 if (
N->use_empty() || !
N->isMachineOpcode())
7706 unsigned StorageOpcode =
N->getMachineOpcode();
7707 bool RequiresMod4Offset =
false;
7709 switch (StorageOpcode) {
7714 case PPC::DFLOADf64:
7715 case PPC::DFLOADf32:
7716 RequiresMod4Offset =
true;
7732 case PPC::DFSTOREf64:
7733 case PPC::DFSTOREf32:
7734 RequiresMod4Offset =
true;
7752 if (!isa<ConstantSDNode>(
N->getOperand(FirstOp)))
7756 if (!
Base.isMachineOpcode())
7760 bool ReplaceFlags =
true;
7772 switch (
Base.getMachineOpcode()) {
7780 ReplaceFlags =
false;
7782 case PPC::ADDIdtprelL:
7785 case PPC::ADDItlsldL:
7788 case PPC::ADDItocL8:
7803 int MaxDisplacement = 7;
7807 MaxDisplacement = std::min((
int)Alignment.
value() - 1, MaxDisplacement);
7810 bool UpdateHBase =
false;
7813 int Offset =
N->getConstantOperandVal(FirstOp);
7815 if (Offset < 0 || Offset > MaxDisplacement) {
7819 if (
Base.getMachineOpcode() != PPC::ADDItocL8)
7830 if (HImmOpnd != ImmOpnd)
7838 if (RequiresMod4Offset) {
7840 dyn_cast<GlobalAddressSDNode>(ImmOpnd)) {
7853 if (
auto *
C = dyn_cast<ConstantSDNode>(ImmOpnd)) {
7856 if (RequiresMod4Offset && (
Offset % 4) != 0)
7864 }
else if (
Offset != 0) {
7872 assert(GA &&
"Expecting a valid GlobalAddressSDNode when folding "
7873 "addi into local-[exec|dynamic] accesses!");
7886 LLVM_DEBUG(
dbgs() <<
"Folding add-immediate into mem-op:\nBase: ");
7901 if (Alignment < 4 && (RequiresMod4Offset || (
Offset % 4) != 0)) {
7902 LLVM_DEBUG(
dbgs() <<
"Rejected this candidate for alignment.\n\n");
7907 dyn_cast<ConstantPoolSDNode>(ImmOpnd)) {
7916 Base.getOperand(0),
N->getOperand(3));
7926 if (
Base.getNode()->use_empty())
7936 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 ...
@ CALL_RM
The variants that implicitly define rounding mode for calls with strictfp semantics.
@ 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.