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);
2979 bool Output32Bit =
N->getValueType(0) == MVT::i32;
2985 if (Input32Bit != Output32Bit)
2986 ConvOp = addExtOrTrunc(WideRes, Input32Bit ? ExtOrTruncConversion::Ext :
2987 ExtOrTruncConversion::Trunc);
2995SDNode *IntegerCompareEliminator::tryLogicOpOfCompares(
SDNode *
N) {
2996 if (
N->getValueType(0) != MVT::i1)
2999 "Expected a logic operation on setcc results.");
3001 if (!LoweredLogical)
3006 unsigned SubRegToExtract = IsBitwiseNegate ? PPC::sub_eq : PPC::sub_gt;
3015 if (IsBitwiseNegate &&
3018 else if (IsBitwiseNegate)
3020 OpToConvToRecForm = LoweredLogical.
getOperand(0);
3024 OpToConvToRecForm = LoweredLogical;
3034 if (NewOpc != -1 && IsBitwiseNegate) {
3037 "Expected a PPC::XORI8 only for bitwise negation.");
3039 std::vector<SDValue> Ops;
3040 for (
int i = 0, e = OpToConvToRecForm.
getNumOperands(); i < e; i++)
3041 Ops.push_back(OpToConvToRecForm.
getOperand(i));
3046 MVT::Glue, Ops), 0);
3048 assert((NewOpc != -1 || !IsBitwiseNegate) &&
3049 "No record form available for AND8/OR8/XOR8?");
3052 dl, MVT::i64, MVT::Glue, LHS, RHS),
3064 MVT::i1, CR0Reg, SRIdxVal,
3077SDValue IntegerCompareEliminator::computeLogicOpInGPR(
SDValue LogicOp) {
3079 "Can only handle logic operations here.");
3081 "Can only handle logic operations on i1 values here.");
3093 unsigned OperandOpcode = Operand.
getOpcode();
3095 return getSETCCInGPR(Operand, SetccInGPROpts::ZExtOrig);
3100 PPC::RLDICL, dl, InVT, InputOp,
3101 S->getI64Imm(0, dl),
3102 S->getI64Imm(63, dl)), 0);
3104 return computeLogicOpInGPR(Operand);
3113 if (!LHS || (!RHS && !IsBitwiseNegation))
3116 NumLogicOpsOnComparison++;
3119 if (
LHS.getValueType() == MVT::i32)
3120 LHS = addExtOrTrunc(LHS, ExtOrTruncConversion::Ext);
3121 if (!IsBitwiseNegation &&
RHS.getValueType() == MVT::i32)
3122 RHS = addExtOrTrunc(RHS, ExtOrTruncConversion::Ext);
3127 case ISD::AND: NewOpc = PPC::AND8;
break;
3128 case ISD::OR: NewOpc = PPC::OR8;
break;
3129 case ISD::XOR: NewOpc = PPC::XOR8;
break;
3132 if (IsBitwiseNegation) {
3133 RHS = S->getI64Imm(1, dl);
3134 NewOpc = PPC::XORI8;
3145SDValue IntegerCompareEliminator::signExtendInputIfNeeded(
SDValue Input) {
3147 "Can only sign-extend 32-bit values here.");
3155 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3157 LoadSDNode *InputLoad = dyn_cast<LoadSDNode>(Input);
3161 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3166 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3169 SignExtensionsAdded++;
3171 MVT::i64, Input), 0);
3178SDValue IntegerCompareEliminator::zeroExtendInputIfNeeded(
SDValue Input) {
3180 "Can only zero-extend 32-bit values here.");
3190 if (IsTruncateOfZExt)
3191 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3195 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3197 LoadSDNode *InputLoad = dyn_cast<LoadSDNode>(Input);
3200 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3204 ZeroExtensionsAdded++;
3206 S->getI64Imm(0, dl),
3207 S->getI64Imm(32, dl)), 0);
3214SDValue IntegerCompareEliminator::addExtOrTrunc(
SDValue NatWidthRes,
3215 ExtOrTruncConversion Conv) {
3216 SDLoc dl(NatWidthRes);
3220 if (Conv == ExtOrTruncConversion::Ext) {
3225 ImDef, NatWidthRes, SubRegIdx), 0);
3228 assert(Conv == ExtOrTruncConversion::Trunc &&
3229 "Unknown convertion between 32 and 64 bit values.");
3235 NatWidthRes, SubRegIdx), 0);
3241IntegerCompareEliminator::getCompoundZeroComparisonInGPR(
SDValue LHS,
SDLoc dl,
3242 ZeroCompare CmpTy) {
3243 EVT InVT =
LHS.getValueType();
3244 bool Is32Bit = InVT == MVT::i32;
3249 case ZeroCompare::GEZExt:
3250 case ZeroCompare::GESExt:
3252 dl, InVT, LHS, LHS), 0);
3254 case ZeroCompare::LEZExt:
3255 case ZeroCompare::LESExt: {
3258 LHS = signExtendInputIfNeeded(LHS);
3263 Neg, S->getI64Imm(1, dl),
3264 S->getI64Imm(63, dl)), 0);
3268 S->getI64Imm(~0ULL, dl)), 0);
3278 (CmpTy == ZeroCompare::GEZExt || CmpTy == ZeroCompare::LEZExt))
3280 ToExtend, S->getI64Imm(1, dl),
3281 S->getI64Imm(63, dl)), 0);
3283 (CmpTy == ZeroCompare::GESExt || CmpTy == ZeroCompare::LESExt))
3285 S->getI64Imm(63, dl)), 0);
3287 assert(Is32Bit &&
"Should have handled the 32-bit sequences above.");
3290 case ZeroCompare::GEZExt: {
3291 SDValue ShiftOps[] = { ToExtend, S->getI32Imm(1, dl), S->getI32Imm(31, dl),
3292 S->getI32Imm(31, dl) };
3296 case ZeroCompare::GESExt:
3298 S->getI32Imm(31, dl)), 0);
3299 case ZeroCompare::LEZExt:
3301 S->getI32Imm(1, dl)), 0);
3302 case ZeroCompare::LESExt:
3304 S->getI32Imm(-1, dl)), 0);
3315IntegerCompareEliminator::get32BitZExtCompare(
SDValue LHS,
SDValue RHS,
3317 int64_t RHSValue,
SDLoc dl) {
3321 bool IsRHSZero = RHSValue == 0;
3322 bool IsRHSOne = RHSValue == 1;
3323 bool IsRHSNegOne = RHSValue == -1LL;
3333 SDValue ShiftOps[] = { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl),
3334 S->getI32Imm(31, dl) };
3345 SDValue ShiftOps[] = { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl),
3346 S->getI32Imm(31, dl) };
3350 S->getI32Imm(1, dl)), 0);
3356 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt);
3362 IsRHSZero = RHSConst && RHSConst->
isZero();
3373 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LEZExt);
3377 LHS = signExtendInputIfNeeded(LHS);
3378 RHS = signExtendInputIfNeeded(RHS);
3383 S->getI64Imm(1, dl), S->getI64Imm(63, dl)),
3387 MVT::i64, Shift, S->getI32Imm(1, dl)), 0);
3395 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt);
3401 LHS = signExtendInputIfNeeded(LHS);
3402 RHS = signExtendInputIfNeeded(RHS);
3406 Neg, S->getI32Imm(1, dl), S->getI32Imm(63, dl)), 0);
3412 IsRHSZero = RHSConst && RHSConst->
isZero();
3424 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LEZExt);
3428 SDValue ShiftOps[] = {
LHS, S->getI32Imm(1, dl), S->getI32Imm(31, dl),
3429 S->getI32Imm(31, dl) };
3437 LHS = signExtendInputIfNeeded(LHS);
3438 RHS = signExtendInputIfNeeded(RHS);
3442 SUBFNode, S->getI64Imm(1, dl),
3443 S->getI64Imm(63, dl)), 0);
3454 LHS = zeroExtendInputIfNeeded(LHS);
3455 RHS = zeroExtendInputIfNeeded(RHS);
3460 Subtract, S->getI64Imm(1, dl),
3461 S->getI64Imm(63, dl)), 0);
3463 S->getI32Imm(1, dl)), 0);
3474 LHS = zeroExtendInputIfNeeded(LHS);
3475 RHS = zeroExtendInputIfNeeded(RHS);
3479 Subtract, S->getI64Imm(1, dl),
3480 S->getI64Imm(63, dl)), 0);
3488IntegerCompareEliminator::get32BitSExtCompare(
SDValue LHS,
SDValue RHS,
3490 int64_t RHSValue,
SDLoc dl) {
3494 bool IsRHSZero = RHSValue == 0;
3495 bool IsRHSOne = RHSValue == 1;
3496 bool IsRHSNegOne = RHSValue == -1LL;
3509 SDValue SHLOps[] = { Cntlzw, S->getI32Imm(27, dl),
3510 S->getI32Imm(5, dl), S->getI32Imm(31, dl) };
3528 { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl), S->getI32Imm(31, dl) };
3533 S->getI32Imm(1, dl)), 0);
3540 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt);
3546 IsRHSZero = RHSConst && RHSConst->
isZero();
3555 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LESExt);
3558 LHS = signExtendInputIfNeeded(LHS);
3559 RHS = signExtendInputIfNeeded(RHS);
3565 SUBFNode, S->getI64Imm(1, dl),
3566 S->getI64Imm(63, dl)), 0);
3568 S->getI32Imm(-1, dl)), 0);
3575 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt);
3580 LHS = signExtendInputIfNeeded(LHS);
3581 RHS = signExtendInputIfNeeded(RHS);
3585 S->getI64Imm(63, dl)), 0);
3591 IsRHSZero = RHSConst && RHSConst->
isZero();
3602 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LESExt);
3606 S->getI32Imm(31, dl)), 0);
3611 LHS = signExtendInputIfNeeded(LHS);
3612 RHS = signExtendInputIfNeeded(RHS);
3616 SUBFNode, S->getI64Imm(63, dl)), 0);
3627 LHS = zeroExtendInputIfNeeded(LHS);
3628 RHS = zeroExtendInputIfNeeded(RHS);
3633 S->getI32Imm(1, dl), S->getI32Imm(63,dl)),
3636 S->getI32Imm(-1, dl)), 0);
3647 LHS = zeroExtendInputIfNeeded(LHS);
3648 RHS = zeroExtendInputIfNeeded(RHS);
3652 Subtract, S->getI64Imm(63, dl)), 0);
3660IntegerCompareEliminator::get64BitZExtCompare(
SDValue LHS,
SDValue RHS,
3662 int64_t RHSValue,
SDLoc dl) {
3666 bool IsRHSZero = RHSValue == 0;
3667 bool IsRHSOne = RHSValue == 1;
3668 bool IsRHSNegOne = RHSValue == -1LL;
3679 S->getI64Imm(58, dl),
3680 S->getI64Imm(63, dl)), 0);
3691 Xor, S->getI32Imm(~0U, dl)), 0);
3701 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt);
3704 IsRHSZero = RHSConst && RHSConst->
isZero();
3713 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LEZExt);
3716 S->getI64Imm(1, dl),
3717 S->getI64Imm(63, dl)), 0);
3720 S->getI64Imm(63, dl)), 0);
3725 ShiftR, ShiftL, SubtractCarry), 0);
3733 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt);
3737 S->getI64Imm(~0ULL, dl)), 0);
3741 S->getI64Imm(1, dl),
3742 S->getI64Imm(63, dl)), 0);
3746 IsRHSZero = RHSConst && RHSConst->
isZero();
3756 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LEZExt);
3759 S->getI64Imm(1, dl),
3760 S->getI64Imm(63, dl)), 0);
3763 LHS, S->getI64Imm(63, dl)), 0);
3766 RHS, S->getI64Imm(1, dl),
3767 S->getI64Imm(63, dl)), 0);
3773 SRDINode, SRADINode, SUBFC8Carry), 0);
3775 ADDE8Node, S->getI64Imm(1, dl)), 0);
3790 LHS, LHS, SUBFC8Carry), 0);
3792 SUBFE8Node, S->getI64Imm(1, dl)), 0);
3807 LHS, LHS, SubtractCarry), 0);
3817IntegerCompareEliminator::get64BitSExtCompare(
SDValue LHS,
SDValue RHS,
3819 int64_t RHSValue,
SDLoc dl) {
3823 bool IsRHSZero = RHSValue == 0;
3824 bool IsRHSOne = RHSValue == 1;
3825 bool IsRHSNegOne = RHSValue == -1LL;
3837 AddInput, S->getI32Imm(~0U, dl)), 0);
3850 Xor, S->getI32Imm(0, dl)), 0);
3860 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt);
3863 IsRHSZero = RHSConst && RHSConst->
isZero();
3872 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LESExt);
3875 S->getI64Imm(63, dl)), 0);
3878 S->getI64Imm(1, dl),
3879 S->getI64Imm(63, dl)), 0);
3885 ShiftR, ShiftL, SubtractCarry), 0);
3894 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt);
3898 S->getI64Imm(-1, dl)), 0);
3902 S->getI64Imm(63, dl)), 0);
3906 IsRHSZero = RHSConst && RHSConst->
isZero();
3916 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LESExt);
3919 S->getI64Imm(63, dl)), 0);
3923 LHS, S->getI64Imm(63, dl)), 0);
3926 RHS, S->getI64Imm(1, dl),
3927 S->getI64Imm(63, dl)), 0);
3933 SRDINode, SRADINode, SUBFC8Carry), 0);
3936 ADDE8Node, S->getI64Imm(1, dl)), 0);
3953 LHS, SubtractCarry), 0);
3955 ExtSub, ExtSub), 0);
3969 LHS, LHS, SubCarry), 0);
3980 "An ISD::SETCC node required here.");
3988 for (
auto *CompareUse :
Compare.getNode()->users())
3993 OmittedForNonExtendUses++;
4003 SetccInGPROpts ConvOpts) {
4006 "An ISD::SETCC node required here.");
4019 cast<CondCodeSDNode>(
Compare.getOperand(CCOpNum))->get();
4020 EVT InputVT =
LHS.getValueType();
4021 if (InputVT != MVT::i32 && InputVT != MVT::i64)
4024 if (ConvOpts == SetccInGPROpts::ZExtInvert ||
4025 ConvOpts == SetccInGPROpts::SExtInvert)
4028 bool Inputs32Bit = InputVT == MVT::i32;
4033 bool IsSext = ConvOpts == SetccInGPROpts::SExtOrig ||
4034 ConvOpts == SetccInGPROpts::SExtInvert;
4036 if (IsSext && Inputs32Bit)
4037 return get32BitSExtCompare(LHS, RHS, CC, RHSValue, dl);
4038 else if (Inputs32Bit)
4039 return get32BitZExtCompare(LHS, RHS, CC, RHSValue, dl);
4041 return get64BitSExtCompare(LHS, RHS, CC, RHSValue, dl);
4042 return get64BitZExtCompare(LHS, RHS, CC, RHSValue, dl);
4047bool PPCDAGToDAGISel::tryIntCompareInGPR(
SDNode *
N) {
4048 if (
N->getValueType(0) != MVT::i32 &&
4049 N->getValueType(0) != MVT::i64)
4055 if (
TM.getOptLevel() == CodeGenOptLevel::None || !
TM.isPPC64())
4061 if (!(
CmpInGPR.getNumOccurrences() > 0) && Subtarget->isISA3_1())
4064 switch (
N->getOpcode()) {
4071 IntegerCompareEliminator ICmpElim(CurDAG,
this);
4072 if (
SDNode *New = ICmpElim.Select(
N)) {
4073 ReplaceNode(
N, New);
4081bool PPCDAGToDAGISel::tryBitPermutation(
SDNode *
N) {
4082 if (
N->getValueType(0) != MVT::i32 &&
4083 N->getValueType(0) != MVT::i64)
4089 switch (
N->getOpcode()) {
4094 if (Subtarget->isISA3_1() &&
N->getValueType(0) == MVT::i32 &&
4096 auto &OpRight =
N->getOperand(1);
4106 BitPermutationSelector BPS(CurDAG);
4107 if (
SDNode *New = BPS.Select(
N)) {
4108 ReplaceNode(
N, New);
4125 if (
LHS.getValueType() == MVT::i32) {
4130 if (isUInt<16>(Imm))
4132 getI32Imm(Imm & 0xFFFF, dl)),
4135 if (isInt<16>((
int)Imm))
4137 getI32Imm(Imm & 0xFFFF, dl)),
4150 getI32Imm(Imm >> 16, dl)), 0);
4152 getI32Imm(Imm & 0xFFFF, dl)), 0);
4158 getI32Imm(Imm & 0xFFFF, dl)), 0);
4164 getI32Imm((
int)SImm & 0xFFFF,
4169 }
else if (
LHS.getValueType() == MVT::i64) {
4174 if (isUInt<16>(Imm))
4176 getI32Imm(Imm & 0xFFFF, dl)),
4181 getI32Imm(Imm & 0xFFFF, dl)),
4193 if (isUInt<32>(Imm)) {
4195 getI64Imm(Imm >> 16, dl)), 0);
4197 getI64Imm(Imm & 0xFFFF, dl)),
4205 getI64Imm(Imm & 0xFFFF, dl)), 0);
4211 getI64Imm(SImm & 0xFFFF, dl)),
4215 }
else if (
LHS.getValueType() == MVT::f32) {
4216 if (Subtarget->hasSPE()) {
4221 Opc = PPC::EFSCMPEQ;
4229 Opc = PPC::EFSCMPLT;
4237 Opc = PPC::EFSCMPGT;
4242 }
else if (
LHS.getValueType() == MVT::f64) {
4243 if (Subtarget->hasSPE()) {
4248 Opc = PPC::EFDCMPEQ;
4256 Opc = PPC::EFDCMPLT;
4264 Opc = PPC::EFDCMPGT;
4268 Opc = Subtarget->hasVSX() ? PPC::XSCMPUDP : PPC::FCMPUD;
4270 assert(
LHS.getValueType() == MVT::f128 &&
"Unknown vt!");
4271 assert(Subtarget->hasP9Vector() &&
"XSCMPUQP requires Power9 Vector");
4272 Opc = PPC::XSCMPUQP;
4340 case ISD::SETO: Invert =
true;
return 3;
4357 bool HasVSX,
bool &Swap,
bool &Negate) {
4384 if (VecVT == MVT::v4f32)
4385 return HasVSX ? PPC::XVCMPEQSP : PPC::VCMPEQFP;
4386 else if (VecVT == MVT::v2f64)
4387 return PPC::XVCMPEQDP;
4391 if (VecVT == MVT::v4f32)
4392 return HasVSX ? PPC::XVCMPGTSP : PPC::VCMPGTFP;
4393 else if (VecVT == MVT::v2f64)
4394 return PPC::XVCMPGTDP;
4398 if (VecVT == MVT::v4f32)
4399 return HasVSX ? PPC::XVCMPGESP : PPC::VCMPGEFP;
4400 else if (VecVT == MVT::v2f64)
4401 return PPC::XVCMPGEDP;
4428 if (VecVT == MVT::v16i8)
4429 return PPC::VCMPEQUB;
4430 else if (VecVT == MVT::v8i16)
4431 return PPC::VCMPEQUH;
4432 else if (VecVT == MVT::v4i32)
4433 return PPC::VCMPEQUW;
4434 else if (VecVT == MVT::v2i64)
4435 return PPC::VCMPEQUD;
4436 else if (VecVT == MVT::v1i128)
4437 return PPC::VCMPEQUQ;
4440 if (VecVT == MVT::v16i8)
4441 return PPC::VCMPGTSB;
4442 else if (VecVT == MVT::v8i16)
4443 return PPC::VCMPGTSH;
4444 else if (VecVT == MVT::v4i32)
4445 return PPC::VCMPGTSW;
4446 else if (VecVT == MVT::v2i64)
4447 return PPC::VCMPGTSD;
4448 else if (VecVT == MVT::v1i128)
4449 return PPC::VCMPGTSQ;
4452 if (VecVT == MVT::v16i8)
4453 return PPC::VCMPGTUB;
4454 else if (VecVT == MVT::v8i16)
4455 return PPC::VCMPGTUH;
4456 else if (VecVT == MVT::v4i32)
4457 return PPC::VCMPGTUW;
4458 else if (VecVT == MVT::v2i64)
4459 return PPC::VCMPGTUD;
4460 else if (VecVT == MVT::v1i128)
4461 return PPC::VCMPGTUQ;
4470bool PPCDAGToDAGISel::trySETCC(
SDNode *
N) {
4473 bool IsStrict =
N->isStrictFPOpcode();
4475 cast<CondCodeSDNode>(
N->getOperand(IsStrict ? 3 : 2))->get();
4478 bool isPPC64 = (PtrVT == MVT::i64);
4494 SDValue Ops[] = {
Op, getI32Imm(27, dl), getI32Imm(5, dl),
4495 getI32Imm(31, dl) };
4503 Op, getI32Imm(~0U, dl)), 0);
4508 SDValue Ops[] = {
Op, getI32Imm(1, dl), getI32Imm(31, dl),
4509 getI32Imm(31, dl) };
4517 SDValue Ops[] = {
T, getI32Imm(1, dl), getI32Imm(31, dl),
4518 getI32Imm(31, dl) };
4523 }
else if (Imm == ~0U) {
4530 Op, getI32Imm(1, dl)), 0);
4535 0),
Op.getValue(1));
4541 Op, getI32Imm(~0U, dl));
4548 getI32Imm(1, dl)), 0);
4551 SDValue Ops[] = { AN, getI32Imm(1, dl), getI32Imm(31, dl),
4552 getI32Imm(31, dl) };
4557 SDValue Ops[] = {
Op, getI32Imm(1, dl), getI32Imm(31, dl),
4558 getI32Imm(31, dl) };
4569 if (!IsStrict &&
LHS.getValueType().isVector()) {
4570 if (Subtarget->hasSPE())
4573 EVT VecVT =
LHS.getValueType();
4575 unsigned int VCmpInst =
4583 CurDAG->
SelectNodeTo(
N, Subtarget->hasVSX() ? PPC::XXLNOR : PPC::VNOR,
4592 if (Subtarget->useCRBits())
4597 SDValue CCReg = SelectCC(LHS, RHS, CC, dl, Chain);
4604 if (Subtarget->hasSPE() &&
LHS.getValueType().isFloatingPoint()) {
4618 SDValue Ops[] = { IntCR, getI32Imm((32 - (3 -
Idx)) & 31, dl),
4619 getI32Imm(31, dl), getI32Imm(31, dl) };
4628 CurDAG->
SelectNodeTo(
N, PPC::XORI, MVT::i32, Tmp, getI32Imm(1, dl));
4634bool PPCDAGToDAGISel::isOffsetMultipleOf(
SDNode *
N,
unsigned Val)
const {
4640 AddrOp =
N->getOperand(1);
4655 if ((SlotAlign % Val) != 0)
4670void PPCDAGToDAGISel::transferMemOperands(
SDNode *
N,
SDNode *Result) {
4677 bool &NeedSwapOps,
bool &IsUnCmp) {
4683 SDValue TrueRes =
N->getOperand(2);
4684 SDValue FalseRes =
N->getOperand(3);
4686 if (!TrueConst || (
N->getSimpleValueType(0) != MVT::i64 &&
4687 N->getSimpleValueType(0) != MVT::i32))
4696 if ((TrueResVal < -1 || TrueResVal > 1) ||
4725 cast<CondCodeSDNode>(SetOrSelCC.
getOperand(InnerIsSel ? 4 : 2))->get();
4730 dyn_cast<ConstantSDNode>(SetOrSelCC.
getOperand(2));
4732 dyn_cast<ConstantSDNode>(SetOrSelCC.
getOperand(3));
4733 if (!SelCCTrueConst || !SelCCFalseConst)
4738 if (SelCCTVal == -1 && SelCCFVal == 1) {
4740 }
else if (SelCCTVal != 1 || SelCCFVal != -1)
4750 bool InnerSwapped =
false;
4751 if (
LHS == InnerRHS &&
RHS == InnerLHS)
4752 InnerSwapped =
true;
4753 else if (
LHS != InnerLHS ||
RHS != InnerRHS)
4764 NeedSwapOps = (InnerCC ==
ISD::SETGT) ? InnerSwapped : !InnerSwapped;
4781 NeedSwapOps = (TrueResVal == 1);
4800 NeedSwapOps = (TrueResVal == -1);
4809 LLVM_DEBUG(
dbgs() <<
"Found a node that can be lowered to a SETB: ");
4819 if (
N.getNumOperands() < 1 || !isa<ConstantSDNode>(
N.getOperand(0)) ||
4822 switch (
N.getConstantOperandVal(0)) {
4823 case Intrinsic::ppc_vsx_xvtdivdp:
4824 case Intrinsic::ppc_vsx_xvtdivsp:
4825 case Intrinsic::ppc_vsx_xvtsqrtdp:
4826 case Intrinsic::ppc_vsx_xvtsqrtsp:
4832bool PPCDAGToDAGISel::tryFoldSWTestBRCC(
SDNode *
N) {
4844 ISD::CondCode CC = cast<CondCodeSDNode>(
N->getOperand(1))->get();
4890bool PPCDAGToDAGISel::trySelectLoopCountIntrinsic(
SDNode *
N) {
4894 ISD::CondCode CC = cast<CondCodeSDNode>(
N->getOperand(1))->get();
4897 if (
LHS.getOpcode() !=
ISD::AND || !isa<ConstantSDNode>(
LHS.getOperand(1)) ||
4902 LHS.getOperand(0).getConstantOperandVal(1) != Intrinsic::loop_decrement)
4905 if (!isa<ConstantSDNode>(RHS))
4909 "Counter decrement comparison is not EQ or NE");
4912 assert(OldDecrement.
hasOneUse() &&
"loop decrement has more than one use!");
4914 SDLoc DecrementLoc(OldDecrement);
4916 SDValue DecrementOps[] = {Subtarget->
isPPC64() ? getI64Imm(1, DecrementLoc)
4917 : getI32Imm(1, DecrementLoc)};
4918 unsigned DecrementOpcode =
4919 Subtarget->
isPPC64() ? PPC::DecreaseCTR8loop : PPC::DecreaseCTRloop;
4921 MVT::i1, DecrementOps);
4923 unsigned Val =
RHS->getAsZExtVal();
4925 unsigned Opcode = IsBranchOnTrue ? PPC::BC : PPC::BCn;
4927 ReplaceUses(
LHS.getValue(0),
LHS.getOperand(1));
4931 ReplaceUses(OldDecrement.
getValue(1), ChainInput);
4935 ChainInput,
N->getOperand(0));
4938 N->getOperand(4), Chain);
4942bool PPCDAGToDAGISel::tryAsSingleRLWINM(
SDNode *
N) {
4950 unsigned SH, MB, ME;
4953 if (isRotateAndMask(Val.
getNode(), Imm,
false, SH, MB, ME)) {
4955 SDValue Ops[] = {Val, getI32Imm(SH, dl), getI32Imm(MB, dl),
4966 unsigned AlreadyCleared = 0;
4969 if (IntrinsicID == Intrinsic::ppc_lbarx)
4970 AlreadyCleared = 24;
4971 else if (IntrinsicID == Intrinsic::ppc_lharx)
4972 AlreadyCleared = 16;
4973 if (AlreadyCleared != 0 && AlreadyCleared == MB && ME == 31) {
4974 ReplaceUses(
SDValue(
N, 0),
N->getOperand(0));
4979 SDValue Ops[] = {Val, getI32Imm(0, dl), getI32Imm(MB, dl),
4987 ReplaceUses(
SDValue(
N, 0),
N->getOperand(1));
4994bool PPCDAGToDAGISel::tryAsSingleRLWINM8(
SDNode *
N) {
5011 SDValue Ops[] = {
N->getOperand(0), getI64Imm(0, dl), getI64Imm(MB - 32, dl),
5012 getI64Imm(ME - 32, dl)};
5020bool PPCDAGToDAGISel::tryAsPairOfRLDICL(
SDNode *
N) {
5028 if (isUInt<16>(Imm64))
5040 if (NumOfLeadingZeros != 0)
5041 Imm64 |= maskLeadingOnes<uint64_t>(NumOfLeadingZeros);
5053 unsigned OnesOnLeft = ME + 1;
5054 unsigned ZerosInBetween = (MB - ME + 63) & 63;
5058 getI64Imm(OnesOnLeft, Loc),
5059 getI64Imm(ZerosInBetween, Loc)),
5068 SDValue Ops[] = {Val, getI64Imm(64 - OnesOnLeft, Loc),
5069 getI64Imm(NumOfLeadingZeros, Loc)};
5074bool PPCDAGToDAGISel::tryAsSingleRLWIMI(
SDNode *
N) {
5101 if (
isRunOfOnes(~(Imm ^ Imm2), MB, ME) && !(~Imm & Imm2)) {
5104 getI32Imm(MB, dl), getI32Imm(ME, dl)};
5105 ReplaceNode(
N, CurDAG->
getMachineNode(PPC::RLWIMI, dl, MVT::i32, Ops));
5112bool PPCDAGToDAGISel::tryAsSingleRLDCL(
SDNode *
N) {
5141bool PPCDAGToDAGISel::tryAsSingleRLDICL(
SDNode *
N) {
5160 auto ImDef = CurDAG->
getMachineNode(PPC::IMPLICIT_DEF, dl, ResultType);
5178 assert(Imm < 64 &&
"Illegal shift amount");
5183 SDValue Ops[] = {Val, getI32Imm(SH, dl), getI32Imm(MB, dl)};
5188bool PPCDAGToDAGISel::tryAsSingleRLDICR(
SDNode *
N) {
5201 SDValue Ops[] = {
N->getOperand(0), getI32Imm(SH, dl), getI32Imm(MB, dl)};
5206bool PPCDAGToDAGISel::tryAsSingleRLDIMI(
SDNode *
N) {
5220 unsigned SH = 63 - ME;
5226 getI32Imm(SH, Dl), getI32Imm(MB, Dl)};
5233void PPCDAGToDAGISel::Select(
SDNode *
N) {
5235 if (
N->isMachineOpcode()) {
5248 if (tryBitPermutation(
N))
5252 if (tryIntCompareInGPR(
N))
5255 switch (
N->getOpcode()) {
5259 if (
N->getValueType(0) == MVT::i64) {
5266 auto IntrinsicID =
N->getConstantOperandVal(1);
5267 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
5268 IntrinsicID != Intrinsic::ppc_trapd &&
5269 IntrinsicID != Intrinsic::ppc_trap)
5271 unsigned Opcode = (IntrinsicID == Intrinsic::ppc_tdw ||
5272 IntrinsicID == Intrinsic::ppc_trapd)
5277 if (IntrinsicID == Intrinsic::ppc_tdw ||
5278 IntrinsicID == Intrinsic::ppc_tw) {
5279 SDValue Ops[] = {
N->getOperand(4),
N->getOperand(2),
N->getOperand(3)};
5280 int16_t SImmOperand2;
5281 int16_t SImmOperand3;
5282 int16_t SImmOperand4;
5283 bool isOperand2IntS16Immediate =
5285 bool isOperand3IntS16Immediate =
5290 if (isOperand2IntS16Immediate == isOperand3IntS16Immediate)
5291 Opcode = IntrinsicID == Intrinsic::ppc_tdw ? PPC::TD : PPC::TW;
5292 else if (isOperand3IntS16Immediate)
5294 Ops[2] = getI32Imm(
int(SImmOperand3) & 0xFFFF, dl);
5297 bool isOperand4IntS16Immediate =
5299 (void)isOperand4IntS16Immediate;
5300 assert(isOperand4IntS16Immediate &&
5301 "The 4th operand is not an Immediate");
5303 int16_t TO = int(SImmOperand4) & 0x1F;
5305 if ((TO & 0x1) != ((TO & 0x2) >> 1))
5306 TO = (TO & 0x1) ? TO + 1 : TO - 1;
5308 if ((TO & 0x8) != ((TO & 0x10) >> 1))
5309 TO = (TO & 0x8) ? TO + 8 : TO - 8;
5310 Ops[0] = getI32Imm(TO, dl);
5311 Ops[1] =
N->getOperand(3);
5312 Ops[2] = getI32Imm(
int(SImmOperand2) & 0xFFFF, dl);
5314 OpsWithMD = {Ops[0], Ops[1], Ops[2]};
5317 OpsWithMD = {getI32Imm(24, dl),
N->getOperand(2), getI32Imm(0, dl)};
5321 if (
N->getNumOperands() > MDIndex) {
5322 SDValue MDV =
N->getOperand(MDIndex);
5323 const MDNode *MD = cast<MDNodeSDNode>(MDV)->getMD();
5326 cast<MDString>(MD->
getOperand(0))->getString() ==
5327 "ppc-trap-reason") &&
5328 "Unsupported annotation data type!");
5331 "Invalid data type for annotation ppc-trap-reason!");
5333 getI32Imm(std::stoi(cast<MDString>(
5334 MD->
getOperand(i))->getString().str()), dl));
5349 auto IntID =
N->getConstantOperandVal(0);
5350 if (IntID == Intrinsic::ppc_fsels) {
5351 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2),
N->getOperand(3)};
5356 if (IntID == Intrinsic::ppc_bcdadd_p || IntID == Intrinsic::ppc_bcdsub_p) {
5357 auto Pred =
N->getConstantOperandVal(1);
5359 IntID == Intrinsic::ppc_bcdadd_p ? PPC::BCDADD_rec : PPC::BCDSUB_rec;
5361 unsigned ShiftVal = 0;
5400 EVT VTs[] = {MVT::v16i8, MVT::Glue};
5401 SDValue Ops[] = {
N->getOperand(2),
N->getOperand(3),
5407 if (Subtarget->isISA3_1()) {
5410 CurDAG->
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
5411 CR6Reg, SubRegIdx, BCDOp.
getValue(1)),
5420 SDValue Ops[] = {Move, getI32Imm((32 - (4 + ShiftVal)) & 31, dl),
5421 getI32Imm(31, dl), getI32Imm(31, dl)};
5427 CurDAG->
SelectNodeTo(
N, PPC::XORI, MVT::i32, Shift, getI32Imm(1, dl));
5433 if (!Subtarget->isISA3_1())
5435 unsigned Opcode = 0;
5439 case Intrinsic::ppc_altivec_vstribr_p:
5440 Opcode = PPC::VSTRIBR_rec;
5442 case Intrinsic::ppc_altivec_vstribl_p:
5443 Opcode = PPC::VSTRIBL_rec;
5445 case Intrinsic::ppc_altivec_vstrihr_p:
5446 Opcode = PPC::VSTRIHR_rec;
5448 case Intrinsic::ppc_altivec_vstrihl_p:
5449 Opcode = PPC::VSTRIHL_rec;
5456 EVT VTs[] = {MVT::v16i8, MVT::Glue};
5464 CurDAG->
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
5465 CR6Reg, SubRegIdx, VecStrOp.
getValue(1)),
5482 if (PPCLowering->getPointerTy(CurDAG->
getDataLayout()) != MVT::i32 ||
5483 !Subtarget->isSecurePlt() || !Subtarget->
isTargetELF() ||
5492 if (Subtarget->
isPPC64() || !
TM.isPositionIndependent() ||
5493 !Subtarget->isSecurePlt() || !Subtarget->
isTargetELF())
5509 ReplaceNode(
N, getGlobalBaseReg());
5513 selectFrameIndex(
N,
N);
5519 N->getOperand(0), InGlue));
5524 ReplaceNode(
N, CurDAG->
getMachineNode(PPC::ReadTB, dl, MVT::i32, MVT::i32,
5525 MVT::Other,
N->getOperand(0)));
5532 getConstantIntValue(), dl,
5533 N->getValueType(0));
5534 if (
N->getValueType(0) == MVT::i64) {
5542 assert(
N->getValueType(0) == MVT::i32 &&
5543 "Expecting i64 or i32 in PPCISD::SRA_ADDZE");
5559 if (tryTLSXFormStore(ST))
5566 EVT LoadedVT =
LD->getMemoryVT();
5573 if (tryTLSXFormLoad(LD))
5584 if (
LD->getValueType(0) != MVT::i64) {
5586 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5589 case MVT::f64: Opcode = PPC::LFDU;
break;
5590 case MVT::f32: Opcode = PPC::LFSU;
break;
5591 case MVT::i32: Opcode = PPC::LWZU;
break;
5592 case MVT::i16: Opcode = isSExt ? PPC::LHAU : PPC::LHZU;
break;
5594 case MVT::i8: Opcode = PPC::LBZU;
break;
5597 assert(
LD->getValueType(0) == MVT::i64 &&
"Unknown load result type!");
5598 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5601 case MVT::i64: Opcode = PPC::LDU;
break;
5602 case MVT::i32: Opcode = PPC::LWZU8;
break;
5603 case MVT::i16: Opcode = isSExt ? PPC::LHAU8 : PPC::LHZU8;
break;
5605 case MVT::i8: Opcode = PPC::LBZU8;
break;
5613 Opcode, dl,
LD->getValueType(0),
5614 PPCLowering->getPointerTy(CurDAG->
getDataLayout()), MVT::Other, Ops);
5615 transferMemOperands(
N, MN);
5621 if (
LD->getValueType(0) != MVT::i64) {
5623 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5626 case MVT::f64: Opcode = PPC::LFDUX;
break;
5627 case MVT::f32: Opcode = PPC::LFSUX;
break;
5628 case MVT::i32: Opcode = PPC::LWZUX;
break;
5629 case MVT::i16: Opcode = isSExt ? PPC::LHAUX : PPC::LHZUX;
break;
5631 case MVT::i8: Opcode = PPC::LBZUX;
break;
5634 assert(
LD->getValueType(0) == MVT::i64 &&
"Unknown load result type!");
5635 assert((!isSExt || LoadedVT == MVT::i16 || LoadedVT == MVT::i32) &&
5636 "Invalid sext update load");
5639 case MVT::i64: Opcode = PPC::LDUX;
break;
5640 case MVT::i32: Opcode = isSExt ? PPC::LWAUX : PPC::LWZUX8;
break;
5641 case MVT::i16: Opcode = isSExt ? PPC::LHAUX8 : PPC::LHZUX8;
break;
5643 case MVT::i8: Opcode = PPC::LBZUX8;
break;
5651 Opcode, dl,
LD->getValueType(0),
5652 PPCLowering->getPointerTy(CurDAG->
getDataLayout()), MVT::Other, Ops);
5653 transferMemOperands(
N, MN);
5661 if (tryAsSingleRLWINM(
N) || tryAsSingleRLWIMI(
N) || tryAsSingleRLDCL(
N) ||
5662 tryAsSingleRLDICL(
N) || tryAsSingleRLDICR(
N) || tryAsSingleRLWINM8(
N) ||
5663 tryAsPairOfRLDICL(
N))
5669 if (
N->getValueType(0) == MVT::i32)
5670 if (tryBitfieldInsert(
N))
5681 selectFrameIndex(
N,
N->getOperand(0).getNode(), (int64_t)Imm);
5688 if (tryAsSingleRLDIMI(
N))
5694 bool IsPPC64 = Subtarget->
isPPC64();
5696 (Imm64 & ~0xFFFFFFFFuLL) == 0) {
5700 if (ImmHi != 0 && ImmLo != 0) {
5703 getI16Imm(ImmLo, dl));
5717 bool IsPPC64 = Subtarget->
isPPC64();
5719 (Imm64 & ~0xFFFFFFFFuLL) == 0) {
5723 if (ImmHi != 0 && ImmLo != 0) {
5726 getI16Imm(ImmLo, dl));
5739 selectFrameIndex(
N,
N->getOperand(0).getNode(), (int64_t)Imm);
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) };
5760 unsigned Imm, SH, MB, ME;
5762 isRotateAndMask(
N, Imm,
true, SH, MB, ME)) {
5763 SDValue Ops[] = {
N->getOperand(0).getOperand(0),
5764 getI32Imm(SH, dl), getI32Imm(MB, dl),
5765 getI32Imm(ME, dl) };
5781 unsigned Shift = llvm::countr_zero<uint64_t>(Imm);
5782 if (isInt<16>(Imm) || !Shift)
5789 if (!isInt<16>(ImmSh))
5796 N->getOperand(0), SDImm);
5799 getI32Imm(63 - Shift, dl)};
5805 N->getOperand(0), SDImm);
5808 getI32Imm(0, dl), getI32Imm(31 - Shift, dl)};
5820 EVT InVT =
N->getOperand(0).getValueType();
5821 assert((InVT == MVT::i64 || InVT == MVT::i32) &&
5822 "Invalid input type for ANDI_rec_1_EQ_BIT");
5824 unsigned Opcode = (InVT == MVT::i64) ? PPC::ANDI8_rec : PPC::ANDI_rec;
5834 CurDAG->
SelectNodeTo(
N, TargetOpcode::EXTRACT_SUBREG, MVT::i1, CR0Reg,
5835 SRIdxVal,
SDValue(AndI.getNode(), 1) );
5839 ISD::CondCode CC = cast<CondCodeSDNode>(
N->getOperand(4))->get();
5842 bool isPPC64 = (PtrVT == MVT::i64);
5845 if (Subtarget->useCRBits() &&
N->getOperand(0).getValueType() == MVT::i1)
5848 if (Subtarget->isISA3_0() && Subtarget->
isPPC64()) {
5849 bool NeedSwapOps =
false;
5850 bool IsUnCmp =
false;
5866 N,
N->getSimpleValueType(0) == MVT::i64 ? PPC::SETB8 : PPC::SETB,
5867 N->getValueType(0), GenCC);
5878 N->getValueType(0) == MVT::i32) {
5881 N->getOperand(0), getI32Imm(~0U, dl));
5883 N->getOperand(0),
SDValue(Tmp, 1));
5887 SDValue CCReg = SelectCC(
N->getOperand(0),
N->getOperand(1), CC, dl);
5889 if (
N->getValueType(0) == MVT::i1) {
5897 case 0: SRI = PPC::sub_lt;
break;
5898 case 1: SRI = PPC::sub_gt;
break;
5899 case 2: SRI = PPC::sub_eq;
break;
5900 case 3: SRI = PPC::sub_un;
break;
5907 SDValue C = Inv ? NotCCBit : CCBit,
5908 NotC = Inv ? CCBit : NotCCBit;
5911 C,
N->getOperand(2)), 0);
5913 NotC,
N->getOperand(3)), 0);
5915 CurDAG->
SelectNodeTo(
N, PPC::CROR, MVT::i1, CAndT, NotCAndF);
5922 unsigned SelectCCOp;
5923 if (
N->getValueType(0) == MVT::i32)
5924 SelectCCOp = PPC::SELECT_CC_I4;
5925 else if (
N->getValueType(0) == MVT::i64)
5926 SelectCCOp = PPC::SELECT_CC_I8;
5927 else if (
N->getValueType(0) == MVT::f32) {
5928 if (Subtarget->hasP8Vector())
5929 SelectCCOp = PPC::SELECT_CC_VSSRC;
5930 else if (Subtarget->hasSPE())
5931 SelectCCOp = PPC::SELECT_CC_SPE4;
5933 SelectCCOp = PPC::SELECT_CC_F4;
5934 }
else if (
N->getValueType(0) == MVT::f64) {
5935 if (Subtarget->hasVSX())
5936 SelectCCOp = PPC::SELECT_CC_VSFRC;
5937 else if (Subtarget->hasSPE())
5938 SelectCCOp = PPC::SELECT_CC_SPE;
5940 SelectCCOp = PPC::SELECT_CC_F8;
5941 }
else if (
N->getValueType(0) == MVT::f128)
5942 SelectCCOp = PPC::SELECT_CC_F16;
5943 else if (Subtarget->hasSPE())
5944 SelectCCOp = PPC::SELECT_CC_SPE;
5945 else if (
N->getValueType(0) == MVT::v2f64 ||
5946 N->getValueType(0) == MVT::v2i64)
5947 SelectCCOp = PPC::SELECT_CC_VSRC;
5949 SelectCCOp = PPC::SELECT_CC_VRRC;
5951 SDValue Ops[] = { CCReg,
N->getOperand(2),
N->getOperand(3),
5952 getI32Imm(BROpc, dl) };
5957 if (Subtarget->hasVSX() && (
N->getValueType(0) == MVT::v2f64 ||
5958 N->getValueType(0) == MVT::v2i64)) {
5962 Op2 =
N->getOperand(SVN->
getMaskElt(1) < 2 ? 0 : 1);
5965 for (
int i = 0; i < 2; ++i)
5971 if (Op1 == Op2 &&
DM[0] == 0 &&
DM[1] == 0 &&
5977 if (
LD->isUnindexed() &&
LD->hasOneUse() && Op1.
hasOneUse() &&
5978 (
LD->getMemoryVT() == MVT::f64 ||
5979 LD->getMemoryVT() == MVT::i64) &&
5985 N->getValueType(0), Ops);
5995 unsigned tmp =
DM[0];
6002 SDValue Ops[] = { Op1, Op2, DMV };
6010 bool IsPPC64 = Subtarget->
isPPC64();
6011 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(0) };
6013 ? (IsPPC64 ? PPC::BDNZ8 : PPC::BDNZ)
6014 : (IsPPC64 ? PPC::BDZ8 : PPC::BDZ),
6025 unsigned PCC =
N->getConstantOperandVal(1);
6029 SDValue Pred = getI32Imm(PCC, dl);
6030 SDValue Ops[] = { Pred,
N->getOperand(2),
N->getOperand(3),
6031 N->getOperand(0),
N->getOperand(4) };
6036 if (tryFoldSWTestBRCC(
N))
6038 if (trySelectLoopCountIntrinsic(
N))
6040 ISD::CondCode CC = cast<CondCodeSDNode>(
N->getOperand(1))->get();
6044 if (
N->getOperand(2).getValueType() == MVT::i1) {
6067 N->getOperand(Swap ? 3 : 2),
6068 N->getOperand(Swap ? 2 : 3)), 0);
6069 CurDAG->
SelectNodeTo(
N, PPC::BC, MVT::Other, BitComp,
N->getOperand(4),
6079 N->getOperand(4),
N->getOperand(0) };
6087 unsigned Opc =
Target.getValueType() == MVT::i32 ? PPC::MTCTR : PPC::MTCTR8;
6088 unsigned Reg =
Target.getValueType() == MVT::i32 ? PPC::BCTR : PPC::BCTR8;
6095 const bool isPPC64 = Subtarget->
isPPC64();
6096 const bool isELFABI = Subtarget->
isSVR4ABI();
6097 const bool isAIXABI = Subtarget->
isAIXABI();
6103 "PowerPC doesn't support tiny or kernel code models.");
6114 auto replaceWith = [
this, &dl](
unsigned OpCode,
SDNode *TocEntry,
6119 if (OpCode == PPC::ADDItoc || OpCode == PPC::ADDItoc8)
6125 transferMemOperands(TocEntry, MN);
6127 ReplaceNode(TocEntry, MN);
6135 assert(
TM.isPositionIndependent() &&
6136 "32-bit ELF can only have TOC entries in position independent"
6139 replaceWith(PPC::LWZtoc,
N, MVT::i32);
6143 assert(isAIXABI &&
"ELF ABI already handled");
6146 replaceWith(PPC::ADDItoc,
N, MVT::i32);
6150 replaceWith(PPC::LWZtoc,
N, MVT::i32);
6155 assert(isAIXABI &&
"ELF ABI handled in common SelectCode");
6158 replaceWith(PPC::ADDItoc8,
N, MVT::i64);
6168 assert((isPPC64 || (isAIXABI && !isPPC64)) &&
"We are dealing with 64-bit"
6169 " ELF/AIX or 32-bit AIX in the following.");
6190 SDValue TOCbase =
N->getOperand(1);
6194 isPPC64 ? PPC::ADDIStocHA8 : PPC::ADDIStocHA, dl, VT, TOCbase, GA);
6201 dl, VT,
SDValue(Tmp, 0), GA));
6205 if (PPCLowering->isAccessedAsGotIndirect(GA)) {
6209 isPPC64 ? PPC::LDtocL : PPC::LWZtocL, dl, VT, GA,
SDValue(Tmp, 0));
6211 transferMemOperands(
N, MN);
6216 assert(isPPC64 &&
"TOC_ENTRY already handled for 32-bit.");
6225 "PPCISD::PPC32_PICGOT is only supported for 32-bit SVR4");
6234 assert(isa<ConstantSDNode>(
N->getOperand(0)) &&
6235 isa<ConstantSDNode>(
N->getOperand(1)) &&
6236 "Invalid operand on VADD_SPLAT!");
6238 int Elt =
N->getConstantOperandVal(0);
6239 int EltSize =
N->getConstantOperandVal(1);
6240 unsigned Opc1, Opc2, Opc3;
6244 Opc1 = PPC::VSPLTISB;
6245 Opc2 = PPC::VADDUBM;
6246 Opc3 = PPC::VSUBUBM;
6248 }
else if (EltSize == 2) {
6249 Opc1 = PPC::VSPLTISH;
6250 Opc2 = PPC::VADDUHM;
6251 Opc3 = PPC::VSUBUHM;
6254 assert(EltSize == 4 &&
"Invalid element size on VADD_SPLAT!");
6255 Opc1 = PPC::VSPLTISW;
6256 Opc2 = PPC::VADDUWM;
6257 Opc3 = PPC::VSUBUWM;
6261 if ((Elt & 1) == 0) {
6268 SDValue EltVal = getI32Imm(Elt >> 1, dl);
6273 }
else if (Elt > 0) {
6280 SDValue EltVal = getI32Imm(Elt - 16, dl);
6282 EltVal = getI32Imm(-16, dl);
6294 SDValue EltVal = getI32Imm(Elt + 16, dl);
6296 EltVal = getI32Imm(-16, dl);
6307 if (!Subtarget->hasAltivec() || Subtarget->hasDirectMove())
6311 if (
Type != MVT::v16i8 &&
Type != MVT::v8i16)
6320 isOffsetMultipleOf(
N, 16))
6326 unsigned LIOpcode = Subtarget->
isPPC64() ? PPC::LI8 : PPC::LI;
6341 unsigned SplatOp = (
Type == MVT::v16i8) ? PPC::VSPLTB : PPC::VSPLTH;
6342 unsigned SplatElemIndex =
6351 {ZeroReg,
N->getOperand(1),
N->getOperand(0)});
6353 SDNode *LoadHigh = LoadLow;
6354 if (
Type == MVT::v8i16) {
6356 PPC::LVX, dl, MVT::v16i8, MVT::Other,
6358 LIOpcode, dl, MVT::i32,
6361 N->getOperand(1),
SDValue(LoadLow, 1)});
6365 transferMemOperands(
N, LoadHigh);
6390 "Only OR nodes are supported for CMPB");
6393 if (!Subtarget->hasCMPB())
6396 if (
N->getValueType(0) != MVT::i32 &&
6397 N->getValueType(0) != MVT::i64)
6400 EVT VT =
N->getValueType(0);
6403 bool BytesFound[8] = {
false,
false,
false,
false,
false,
false,
false,
false};
6406 auto IsByteSelectCC = [
this](
SDValue O,
unsigned &
b,
6413 if (!isa<ConstantSDNode>(
O.getOperand(2)) ||
6414 !isa<ConstantSDNode>(
O.getOperand(3)))
6417 uint64_t PM =
O.getConstantOperandVal(2);
6418 uint64_t PAlt =
O.getConstantOperandVal(3);
6419 for (b = 0;
b < 8; ++
b) {
6421 if (PM && (PM & Mask) == PM && (PAlt &
Mask) == PAlt)
6430 if (!isa<ConstantSDNode>(
O.getOperand(1)) ||
6431 O.getConstantOperandVal(1) != 0) {
6432 SDValue Op0 =
O.getOperand(0), Op1 =
O.getOperand(1);
6462 isa<ConstantSDNode>(
O.getOperand(1))) {
6464 uint64_t ULim =
O.getConstantOperandVal(1);
6465 if (ULim != (UINT64_C(1) << b*8))
6488 if (!isa<ConstantSDNode>(
Op.getOperand(1)))
6490 if (
Op.getConstantOperandVal(1) != (UINT64_C(0xFF) << (8*
b)))
6495 XOR =
XOR.getOperand(0);
6503 if (!isa<ConstantSDNode>(
Op.getOperand(1)))
6505 unsigned Bits =
Op.getValueSizeInBits();
6508 if (
Op.getConstantOperandVal(1) !=
Bits-8)
6513 XOR =
XOR.getOperand(0);
6526 while (!
Queue.empty()) {
6529 for (
const SDValue &O :
V.getNode()->ops()) {
6535 }
else if (IsByteSelectCC(O, b, M,
A, OLHS, ORHS)) {
6539 BytesFound[
b] =
true;
6542 }
else if ((LHS == ORHS && RHS == OLHS) ||
6543 (RHS == ORHS && LHS == OLHS)) {
6544 BytesFound[
b] =
true;
6556 unsigned LastB = 0, BCnt = 0;
6557 for (
unsigned i = 0; i < 8; ++i)
6558 if (BytesFound[LastB]) {
6563 if (!LastB || BCnt < 2)
6568 if (
LHS.getValueType() != VT) {
6575 bool NonTrivialMask = ((int64_t) Mask) != INT64_C(-1);
6576 if (NonTrivialMask && !Alt) {
6604 if (!Subtarget->useCRBits())
6612 if (
N->getOperand(0).getValueType() != MVT::i1)
6615 if (!
N->hasOneUse())
6619 EVT VT =
N->getValueType(0);
6636 User->getValueType(0), {O0, O1});
6641 SDValue TrueRes = TryFold(ConstTrue);
6642 if (!TrueRes || TrueRes.
isUndef())
6644 SDValue FalseRes = TryFold(ConstFalse);
6645 if (!FalseRes || FalseRes.
isUndef())
6651 if (!isInt<16>(True) || !isInt<16>(False))
6658 ConstTrue = TrueRes;
6659 ConstFalse = FalseRes;
6660 }
while (
N->hasOneUse());
6663void PPCDAGToDAGISel::PreprocessISelDAG() {
6666 bool MadeChange =
false;
6673 switch (
N->getOpcode()) {
6676 Res = combineToCMPB(
N);
6681 foldBoolExts(Res,
N);
6701void PPCDAGToDAGISel::PostprocessISelDAG() {
6703 if (
TM.getOptLevel() == CodeGenOptLevel::None)
6708 PeepholePPC64ZExt();
6716bool PPCDAGToDAGISel::AllUsersSelectZero(
SDNode *
N) {
6718 if (!
User->isMachineOpcode())
6720 if (
User->getMachineOpcode() != PPC::SELECT_I4 &&
6721 User->getMachineOpcode() != PPC::SELECT_I8)
6745void PPCDAGToDAGISel::SwapAllSelectUsers(
SDNode *
N) {
6748 assert((
User->getMachineOpcode() == PPC::SELECT_I4 ||
6749 User->getMachineOpcode() == PPC::SELECT_I8) &&
6750 "Must have all select users");
6767 ReplaceUses(
User, ResNode);
6771void PPCDAGToDAGISel::PeepholeCROps() {
6777 if (!MachineNode || MachineNode->
use_empty())
6779 SDNode *ResNode = MachineNode;
6781 bool Op1Set =
false, Op1Unset =
false,
6783 Op2Set =
false, Op2Unset =
false,
6798 if (
Op.isMachineOpcode()) {
6799 if (
Op.getMachineOpcode() == PPC::CRSET)
6801 else if (
Op.getMachineOpcode() == PPC::CRUNSET)
6803 else if ((
Op.getMachineOpcode() == PPC::CRNOR &&
6804 Op.getOperand(0) ==
Op.getOperand(1)) ||
6805 Op.getMachineOpcode() == PPC::CRNOT)
6812 case PPC::SELECT_I4:
6813 case PPC::SELECT_I8:
6814 case PPC::SELECT_F4:
6815 case PPC::SELECT_F8:
6816 case PPC::SELECT_SPE:
6817 case PPC::SELECT_SPE4:
6818 case PPC::SELECT_VRRC:
6819 case PPC::SELECT_VSFRC:
6820 case PPC::SELECT_VSSRC:
6821 case PPC::SELECT_VSRC: {
6823 if (
Op.isMachineOpcode()) {
6824 if (
Op.getMachineOpcode() == PPC::CRSET)
6826 else if (
Op.getMachineOpcode() == PPC::CRUNSET)
6828 else if ((
Op.getMachineOpcode() == PPC::CRNOR &&
6829 Op.getOperand(0) ==
Op.getOperand(1)) ||
6830 Op.getMachineOpcode() == PPC::CRNOT)
6837 bool SelectSwap =
false;
6850 else if (Op1Unset || Op2Unset)
6866 else if (AllUsersSelectZero(MachineNode)) {
6889 else if (Op1Unset || Op2Unset)
6905 else if (AllUsersSelectZero(MachineNode)) {
6916 else if (Op1Set || Op2Set)
6938 else if (AllUsersSelectZero(MachineNode)) {
6978 else if (AllUsersSelectZero(MachineNode)) {
6986 if (Op1Set || Op2Set)
7012 else if (AllUsersSelectZero(MachineNode)) {
7052 else if (AllUsersSelectZero(MachineNode)) {
7069 else if (Op1Unset || Op2Set)
7088 else if (AllUsersSelectZero(MachineNode)) {
7100 else if (Op1Set || Op2Unset)
7124 else if (AllUsersSelectZero(MachineNode)) {
7131 case PPC::SELECT_I4:
7132 case PPC::SELECT_I8:
7133 case PPC::SELECT_F4:
7134 case PPC::SELECT_F8:
7135 case PPC::SELECT_SPE:
7136 case PPC::SELECT_SPE4:
7137 case PPC::SELECT_VRRC:
7138 case PPC::SELECT_VSFRC:
7139 case PPC::SELECT_VSSRC:
7140 case PPC::SELECT_VSRC:
7172 SwapAllSelectUsers(MachineNode);
7174 if (ResNode != MachineNode) {
7181 ReplaceUses(MachineNode, ResNode);
7187 }
while (IsModified);
7298 if (!Op0OK && !Op1OK)
7321 if (!Op0OK && !Op1OK)
7335void PPCDAGToDAGISel::PeepholePPC64ZExt() {
7350 bool MadeChange =
false;
7354 if (
N->use_empty() || !
N->isMachineOpcode())
7357 if (
N->getMachineOpcode() != PPC::RLDICL)
7360 if (
N->getConstantOperandVal(1) != 0 ||
7361 N->getConstantOperandVal(2) != 32)
7396 bool OutsideUse =
false;
7397 for (
SDNode *PN : ToPromote) {
7399 if (!ToPromote.count(UN) && UN != ISR.
getNode()) {
7417 for (
SDNode *PN : ToPromote) {
7419 switch (PN->getMachineOpcode()) {
7422 case PPC::RLWINM: NewOpcode = PPC::RLWINM8;
break;
7423 case PPC::RLWNM: NewOpcode = PPC::RLWNM8;
break;
7424 case PPC::SLW: NewOpcode = PPC::SLW8;
break;
7425 case PPC::SRW: NewOpcode = PPC::SRW8;
break;
7426 case PPC::LI: NewOpcode = PPC::LI8;
break;
7427 case PPC::LIS: NewOpcode = PPC::LIS8;
break;
7428 case PPC::LHBRX: NewOpcode = PPC::LHBRX8;
break;
7429 case PPC::LWBRX: NewOpcode = PPC::LWBRX8;
break;
7430 case PPC::CNTLZW: NewOpcode = PPC::CNTLZW8;
break;
7431 case PPC::CNTTZW: NewOpcode = PPC::CNTTZW8;
break;
7432 case PPC::RLWIMI: NewOpcode = PPC::RLWIMI8;
break;
7433 case PPC::OR: NewOpcode = PPC::OR8;
break;
7434 case PPC::SELECT_I4: NewOpcode = PPC::SELECT_I8;
break;
7435 case PPC::ORI: NewOpcode = PPC::ORI8;
break;
7436 case PPC::ORIS: NewOpcode = PPC::ORIS8;
break;
7437 case PPC::AND: NewOpcode = PPC::AND8;
break;
7439 NewOpcode = PPC::ANDI8_rec;
7441 case PPC::ANDIS_rec:
7442 NewOpcode = PPC::ANDIS8_rec;
7453 if (!ToPromote.count(
V.getNode()) &&
V.getValueType() == MVT::i32 &&
7454 !isa<ConstantSDNode>(V)) {
7471 for (
unsigned i = 0, ie = VTs.
NumVTs; i != ie; ++i)
7472 if (VTs.
VTs[i] == MVT::i32)
7505 if (!
N->isMachineOpcode())
7507 unsigned Opc =
N->getMachineOpcode();
7511 if (
Opc == PPC::XXPERMDIs) {
7512 return isa<ConstantSDNode>(
N->getOperand(1)) &&
7513 N->getConstantOperandVal(1) == 2;
7514 }
else if (
Opc == PPC::XXPERMDI ||
Opc == PPC::XXSLDWI) {
7515 return N->getOperand(0) ==
N->getOperand(1) &&
7516 isa<ConstantSDNode>(
N->getOperand(2)) &&
7517 N->getConstantOperandVal(2) == 2;
7525 if (!
N->isMachineOpcode())
7527 unsigned Opc =
N->getMachineOpcode();
7576 auto SkipRCCopy = [](
SDValue V) {
7577 while (V->isMachineOpcode() &&
7578 V->getMachineOpcode() == TargetOpcode::COPY_TO_REGCLASS) {
7580 if (V->use_empty() || !V->user_begin()->isOnlyUserOf(V.getNode()))
7582 V = V->getOperand(0);
7584 return V.hasOneUse() ? V :
SDValue();
7587 SDValue VecOp = SkipRCCopy(
N->getOperand(0));
7606 if (
const GlobalVariable *GV = dyn_cast<GlobalVariable>(GA->getGlobal()))
7607 if (GV->hasAttribute(
"aix-small-tls"))
7628 if (!(Subtarget.hasAIXSmallLocalDynamicTLS() ||
7669 if (
N->getMachineOpcode() != PPC::ADDI8)
7674 SDValue InitialADDI =
N->getOperand(0);
7685 assert(GA &&
"Expecting a valid GlobalAddressSDNode when folding addi into "
7686 "local-[exec|dynamic] accesses!");
7694 int Offset =
N->getConstantOperandVal(1);
7703void PPCDAGToDAGISel::PeepholePPC64() {
7709 if (
N->use_empty() || !
N->isMachineOpcode())
7720 unsigned StorageOpcode =
N->getMachineOpcode();
7721 bool RequiresMod4Offset =
false;
7723 switch (StorageOpcode) {
7728 case PPC::DFLOADf64:
7729 case PPC::DFLOADf32:
7730 RequiresMod4Offset =
true;
7746 case PPC::DFSTOREf64:
7747 case PPC::DFSTOREf32:
7748 RequiresMod4Offset =
true;
7766 if (!isa<ConstantSDNode>(
N->getOperand(FirstOp)))
7770 if (!
Base.isMachineOpcode())
7774 bool ReplaceFlags =
true;
7786 switch (
Base.getMachineOpcode()) {
7794 ReplaceFlags =
false;
7796 case PPC::ADDIdtprelL:
7799 case PPC::ADDItlsldL:
7802 case PPC::ADDItocL8:
7817 int MaxDisplacement = 7;
7821 MaxDisplacement = std::min((
int)Alignment.
value() - 1, MaxDisplacement);
7824 bool UpdateHBase =
false;
7827 int Offset =
N->getConstantOperandVal(FirstOp);
7829 if (Offset < 0 || Offset > MaxDisplacement) {
7833 if (
Base.getMachineOpcode() != PPC::ADDItocL8)
7844 if (HImmOpnd != ImmOpnd)
7852 if (RequiresMod4Offset) {
7854 dyn_cast<GlobalAddressSDNode>(ImmOpnd)) {
7867 if (
auto *
C = dyn_cast<ConstantSDNode>(ImmOpnd)) {
7870 if (RequiresMod4Offset && (
Offset % 4) != 0)
7878 }
else if (
Offset != 0) {
7886 assert(GA &&
"Expecting a valid GlobalAddressSDNode when folding "
7887 "addi into local-[exec|dynamic] accesses!");
7900 LLVM_DEBUG(
dbgs() <<
"Folding add-immediate into mem-op:\nBase: ");
7915 if (Alignment < 4 && (RequiresMod4Offset || (
Offset % 4) != 0)) {
7916 LLVM_DEBUG(
dbgs() <<
"Rejected this candidate for alignment.\n\n");
7921 dyn_cast<ConstantPoolSDNode>(ImmOpnd)) {
7930 Base.getOperand(0),
N->getOperand(3));
7940 if (
Base.getNode()->use_empty())
7950 return new PPCDAGToDAGISelLegacy(TM, OptLevel);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
AMDGPU Register Bank Select
This file implements a class to represent arbitrary precision integral constant values and operations...
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
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)
Register 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
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.
LLVM_ABI APInt rotr(unsigned rotateAmt) const
Rotate right by rotateAmt.
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
MachineBasicBlock * getBasicBlock() const
LLVM Basic Block Representation.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
LLVM_ABI BranchProbability getEdgeProbability(const BasicBlock *Src, unsigned IndexInSuccessors) const
Get an edge's probability, relative to other out-edges of the Src.
int64_t getSExtValue() const
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)
LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
This class is used to represent ISD::LOAD nodes.
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
const MDOperand & getOperand(unsigned I) const
unsigned getNumOperands() const
Return number of MDNode operands.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI 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.
LLVM_ABI int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
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.
LLVM_ABI void dump() const
Dump this node, for debugging.
bool hasOneUse() const
Return true if there is exactly one use of this node.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
bool use_empty() const
Return true if there are no uses of this node.
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
SDVTList getVTList() const
const SDValue & getOperand(unsigned Num) const
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
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)
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDNode * SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT)
These are used for target selectors to mutate the specified node to have the specified return type,...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
const TargetLowering & getTargetLoweringInfo() const
allnodes_const_iterator allnodes_begin() const
allnodes_const_iterator allnodes_end() const
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
LLVM_ABI void setNodeMemRefs(MachineSDNode *N, ArrayRef< MachineMemOperand * > NewMemRefs)
Mutate the specified machine node's memory references to the provided list.
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
LLVM_ABI void RemoveDeadNodes()
This method deletes all unreachable nodes in the SelectionDAG.
LLVM_ABI void RemoveDeadNode(SDNode *N)
Remove the specified node from the system.
LLVM_ABI SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
LLVM_ABI SDValue FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDValue > Ops, SDNodeFlags Flags=SDNodeFlags())
const TargetMachine & getTarget() const
LLVM_ABI SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
iterator_range< allnodes_iterator > allnodes()
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
LLVM_ABI SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
ilist< SDNode >::iterator allnodes_iterator
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...
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This 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.
LLVM_ABI unsigned getOperandNo() const
Return the operand # of this use in its User.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void dump() const
Support for debugging, callable in GDB: V->dump()
An efficient, type-erasing, non-owning reference to a callable.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ BSWAP
Byte Swap and Counting operators.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ BR_CC
BR_CC - Conditional branch.
@ BRIND
BRIND - Indirect branch.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ CopyFromReg
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ TargetConstant
TargetConstant* - Like Constant*, but the DAG does not do any folding, simplification,...
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
LLVM_ABI CondCode getSetCCInverse(CondCode Operation, EVT Type)
Return the operation corresponding to !(X op Y), where 'op' is a valid SetCC operation.
bool isBitwiseLogicOp(unsigned Opcode)
Whether this is bitwise logic opcode.
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
bool isUnsignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs an unsigned comparison when used with intege...
@ MO_TLSLD_FLAG
MO_TLSLD_FLAG - If this bit is set the symbol reference is relative to TLS Local Dynamic model.
@ MO_PLT
On PPC, the 12 bits are not enough for all target operand flags.
@ MO_DTPREL_LO
These values identify relocations on immediates folded into memory operations.
@ MO_TPREL_FLAG
MO_TPREL_FLAG - If this bit is set, the symbol reference is relative to the thread pointer and the sy...
@ 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.
@ 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.
LLVM_ABI 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.
LLVM_ABI bool isBitwiseNot(SDValue V, bool AllowUndefs=false)
Returns true if V is a bitwise not operation.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
void sort(IteratorTy Start, IteratorTy End)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isMask_64(uint64_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
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,...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Xor
Bitwise or logical XOR of integers.
@ Sub
Subtraction of integers.
DWARFExpression::Operation Op
LLVM_ABI bool isOneConstant(SDValue V)
Returns true if V is a constant integer one.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME)
Returns true iff Val consists of one contiguous run of 1s with any number of 0s on either side.
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.