50#include "llvm/IR/IntrinsicsPowerPC.h"
73#define DEBUG_TYPE "ppc-isel"
74#define PASS_NAME "PowerPC DAG->DAG Pattern Instruction Selection"
77 "Number of (sext(setcc)) nodes expanded into GPR sequence.");
79 "Number of (zext(setcc)) nodes expanded into GPR sequence.");
81 "Number of sign extensions for compare inputs added.");
83 "Number of zero extensions for compare inputs added.");
85 "Number of logical ops on i1 values calculated in GPR.");
87 "Number of compares not eliminated as they have non-extending uses.");
89 "Number of compares lowered to setb.");
97 cl::desc(
"use aggressive ppc isel for bit permutations"),
100 "ppc-bit-perm-rewriter-stress-rotates",
101 cl::desc(
"stress rotate selection in aggressive ppc isel for "
106 "ppc-use-branch-hint",
cl::init(
true),
107 cl::desc(
"Enable static hinting of branches on ppc"),
112 cl::desc(
"Enable tls optimization peephole"),
121 cl::desc(
"Specify the types of comparisons to emit GPR-only code for."),
127 "Only comparisons where inputs don't need [sz]ext."),
130 "Only i32 comparisons with zext result."),
132 "Only i64 comparisons with zext result."),
135 "Only i32 comparisons with sext result."),
137 "Only i64 comparisons with sext result.")));
148 unsigned GlobalBaseReg = 0;
151 PPCDAGToDAGISel() =
delete;
156 bool runOnMachineFunction(MachineFunction &MF)
override {
161 if (Subtarget->hasROPProtect()) {
166 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
175 void PreprocessISelDAG()
override;
176 void PostprocessISelDAG()
override;
180 inline SDValue getI16Imm(
unsigned Imm,
const SDLoc &dl) {
181 return CurDAG->getTargetConstant(Imm, dl, MVT::i16);
186 inline SDValue getI32Imm(
unsigned Imm,
const SDLoc &dl) {
187 return CurDAG->getTargetConstant(Imm, dl, MVT::i32);
192 inline SDValue getI64Imm(uint64_t Imm,
const SDLoc &dl) {
193 return CurDAG->getTargetConstant(Imm, dl, MVT::i64);
197 inline SDValue getSmallIPtrImm(int64_t Imm,
const SDLoc &dl) {
198 return CurDAG->getSignedTargetConstant(
199 Imm, dl, PPCLowering->getPointerTy(CurDAG->getDataLayout()));
204 static bool isRotateAndMask(SDNode *
N,
unsigned Mask,
bool isShiftMask,
205 unsigned &SH,
unsigned &MB,
unsigned &ME);
209 SDNode *getGlobalBaseReg();
211 void selectFrameIndex(SDNode *SN, SDNode *
N, int64_t
Offset = 0);
215 void Select(SDNode *
N)
override;
217 bool tryBitfieldInsert(SDNode *
N);
218 bool tryBitPermutation(SDNode *
N);
219 bool tryIntCompareInGPR(SDNode *
N);
224 bool tryTLSXFormLoad(LoadSDNode *
N);
228 bool tryTLSXFormStore(StoreSDNode *
N);
251 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
259 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
267 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
275 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
282 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
290 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
298 return PPCLowering->SelectForceXFormMode(
N, Disp,
Base, *CurDAG) ==
309 return PPCLowering->SelectAddressRegReg(
N,
Base, Index, *CurDAG,
320 return PPCLowering->SelectAddressRegReg(
N,
Base, Index, *CurDAG,
331 return PPCLowering->SelectAddressRegReg(
N,
Base, Index, *CurDAG,
338 return PPCLowering->SelectAddressRegRegOnly(
N,
Base, Index, *CurDAG);
347 return PPCLowering->SelectAddressRegImm(
N, Disp,
Base, *CurDAG,
355 return PPCLowering->SelectAddressRegImm(
N, Disp,
Base, *CurDAG,
Align(4));
362 return PPCLowering->SelectAddressRegImm(
N, Disp,
Base, *CurDAG,
370 return PPCLowering->SelectAddressRegImm34(
N, Disp,
Base, *CurDAG);
380 return PPCLowering->SelectAddressPCRel(
N,
Base);
388 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
390 std::vector<SDValue> &OutOps)
override {
391 switch(ConstraintID) {
393 errs() <<
"ConstraintID: "
396 case InlineAsm::ConstraintCode::es:
397 case InlineAsm::ConstraintCode::m:
398 case InlineAsm::ConstraintCode::o:
399 case InlineAsm::ConstraintCode::Q:
400 case InlineAsm::ConstraintCode::Z:
401 case InlineAsm::ConstraintCode::Zy:
404 const TargetRegisterInfo *
TRI = Subtarget->getRegisterInfo();
405 const TargetRegisterClass *TRC =
TRI->getPointerRegClass(1);
407 SDValue RC = CurDAG->getTargetConstant(TRC->
getID(), dl, MVT::i32);
409 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
410 dl,
Op.getValueType(),
413 OutOps.push_back(NewOp);
420#include "PPCGenDAGISel.inc"
423 bool trySETCC(SDNode *
N);
424 bool tryFoldSWTestBRCC(SDNode *
N);
425 bool trySelectLoopCountIntrinsic(SDNode *
N);
426 bool tryAsSingleRLDICL(SDNode *
N);
427 bool tryAsSingleRLDCL(SDNode *
N);
428 bool tryAsSingleRLDICR(SDNode *
N);
429 bool tryAsSingleRLWINM(SDNode *
N);
430 bool tryAsSingleRLWINM8(SDNode *
N);
431 bool tryAsSingleRLWIMI(SDNode *
N);
432 bool tryAsPairOfRLDICL(SDNode *
N);
433 bool tryAsSingleRLDIMI(SDNode *
N);
435 void PeepholePPC64();
436 void PeepholePPC64ZExt();
437 void PeepholeCROps();
440 void foldBoolExts(
SDValue &Res, SDNode *&
N);
442 bool AllUsersSelectZero(SDNode *
N);
443 void SwapAllSelectUsers(SDNode *
N);
445 bool isOffsetMultipleOf(SDNode *
N,
unsigned Val)
const;
446 void transferMemOperands(SDNode *
N, SDNode *Result);
452 explicit PPCDAGToDAGISelLegacy(PPCTargetMachine &tm,
454 : SelectionDAGISelLegacy(
455 ID, std::make_unique<PPCDAGToDAGISel>(tm, OptLevel)) {}
459char PPCDAGToDAGISelLegacy::ID = 0;
466SDNode *PPCDAGToDAGISel::getGlobalBaseReg() {
467 if (!GlobalBaseReg) {
475 if (PPCLowering->getPointerTy(CurDAG->getDataLayout()) == MVT::i32) {
478 if (!Subtarget->isSecurePlt() &&
488 TII.get(PPC::UpdateGBR), GlobalBaseReg)
494 RegInfo->createVirtualRegister(&PPC::GPRC_and_GPRC_NOR0RegClass);
514 return CurDAG->getRegister(GlobalBaseReg,
515 PPCLowering->getPointerTy(CurDAG->getDataLayout()))
555 if (
N->getOpcode() ==
ISD::Constant &&
N->getValueType(0) == MVT::i32) {
556 Imm =
N->getAsZExtVal();
565 if (
N->getOpcode() ==
ISD::Constant &&
N->getValueType(0) == MVT::i64) {
566 Imm =
N->getAsZExtVal();
617 if (std::max(TProb, FProb) / Threshold < std::min(TProb, FProb))
621 <<
"::" << BB->
getName() <<
"'\n"
622 <<
" -> " <<
TBB->getName() <<
": " << TProb <<
"\n"
623 <<
" -> " << FBB->
getName() <<
": " << FProb <<
"\n");
639 return N->getOpcode() ==
Opc
646 SDValue TFI = CurDAG->getTargetFrameIndex(FI,
N->getValueType(0));
647 unsigned Opc =
N->getValueType(0) == MVT::i32 ? PPC::ADDI : PPC::ADDI8;
649 CurDAG->SelectNodeTo(SN,
Opc,
N->getValueType(0), TFI,
650 getSmallIPtrImm(
Offset, dl));
652 ReplaceNode(SN, CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0), TFI,
653 getSmallIPtrImm(
Offset, dl)));
656bool PPCDAGToDAGISel::isRotateAndMask(SDNode *
N,
unsigned Mask,
657 bool isShiftMask,
unsigned &SH,
658 unsigned &MB,
unsigned &ME) {
661 if (
N->getValueType(0) != MVT::i32)
665 unsigned Indeterminant = ~0;
666 unsigned Opcode =
N->getOpcode();
667 if (
N->getNumOperands() != 2 ||
673 if (isShiftMask)
Mask =
Mask << Shift;
675 Indeterminant = ~(0xFFFFFFFFu << Shift);
678 if (isShiftMask)
Mask =
Mask >> Shift;
680 Indeterminant = ~(0xFFFFFFFFu >> Shift);
690 if (Mask && !(Mask & Indeterminant)) {
702 Base.getOpcode() == PPCISD::ADD_TLS &&
703 "Only expecting the ADD_TLS instruction to acquire the thread pointer!");
707 unsigned ADDTLSOp1Opcode = ADDTLSOp1.getOpcode();
716 if (ADDTLSOp1Opcode == PPCISD::LD_GOT_TPREL_L)
721 if (LD && LD->getBasePtr().getOpcode() == PPCISD::MAT_PCREL_ADDR)
727 if (ADDTLSOp1Opcode == PPCISD::GET_TPOINTER)
752 if (
Base.getOpcode() != PPCISD::ADD_TLS)
754 for (
auto *ADDTLSUse :
Base.getNode()->users()) {
759 if (LD->getSrcValueOffset() != 0 || !LD->getOffset().isUndef())
762 if (ST->getSrcValueOffset() != 0 || !ST->getOffset().isUndef())
768 if (
Base.getOperand(1).getOpcode() == PPCISD::TLS_LOCAL_EXEC_MAT_ADDR)
777bool PPCDAGToDAGISel::tryTLSXFormStore(StoreSDNode *ST) {
783 EVT MemVT =
ST->getMemoryVT();
784 EVT RegVT =
ST->getValue().getValueType();
791 Opcode = (RegVT == MVT::i32) ? PPC::STBXTLS_32 : PPC::STBXTLS;
795 Opcode = (RegVT == MVT::i32) ? PPC::STHXTLS_32 : PPC::STHXTLS;
799 Opcode = (RegVT == MVT::i32) ? PPC::STWXTLS_32 : PPC::STWXTLS;
803 Opcode = PPC::STDXTLS;
807 Opcode = PPC::STFSXTLS;
811 Opcode = PPC::STFDXTLS;
816 SDVTList VTs =
ST->getVTList();
819 SDNode *MN = CurDAG->getMachineNode(Opcode, dl, VTs,
Ops);
820 transferMemOperands(ST, MN);
825bool PPCDAGToDAGISel::tryTLSXFormLoad(LoadSDNode *LD) {
831 EVT MemVT =
LD->getMemoryVT();
832 EVT RegVT =
LD->getValueType(0);
839 Opcode = (RegVT == MVT::i32) ? PPC::LBZXTLS_32 : PPC::LBZXTLS;
843 if (RegVT == MVT::i32)
844 Opcode = isSExt ? PPC::LHAXTLS_32 : PPC::LHZXTLS_32;
846 Opcode = isSExt ? PPC::LHAXTLS : PPC::LHZXTLS;
850 if (RegVT == MVT::i32)
851 Opcode = isSExt ? PPC::LWAXTLS_32 : PPC::LWZXTLS_32;
853 Opcode = isSExt ? PPC::LWAXTLS : PPC::LWZXTLS;
857 Opcode = PPC::LDXTLS;
861 Opcode = PPC::LFSXTLS;
865 Opcode = PPC::LFDXTLS;
870 SDVTList VTs =
LD->getVTList();
872 SDNode *MN = CurDAG->getMachineNode(Opcode, dl, VTs,
Ops);
873 transferMemOperands(LD, MN);
880bool PPCDAGToDAGISel::tryBitfieldInsert(SDNode *
N) {
891 KnownBits LKnown = CurDAG->computeKnownBits(Op0);
892 KnownBits RKnown = CurDAG->computeKnownBits(Op1);
897 if ((TargetMask | InsertMask) == 0xFFFFFFFF) {
900 unsigned Value, SH = 0;
901 TargetMask = ~TargetMask;
902 InsertMask = ~InsertMask;
936 KnownBits MKnown = CurDAG->computeKnownBits(Op1.
getOperand(1));
950 SDValue Ops[] = { Op0, Op1, getI32Imm(SH, dl), getI32Imm(MB, dl),
952 ReplaceNode(
N, CurDAG->getMachineNode(PPC::RLWIMI, dl, MVT::i32,
Ops));
960 unsigned MaxTruncation = 0;
967 User->isMachineOpcode() ?
User->getMachineOpcode() :
User->getOpcode();
971 if (
User->isMachineOpcode())
973 MaxTruncation = std::max(MaxTruncation,
974 (
unsigned)
User->getValueType(0).getSizeInBits());
977 if (
User->isMachineOpcode())
983 MaxTruncation = std::max(MaxTruncation, MemVTSize);
992 MaxTruncation = std::max(MaxTruncation, 32u);
1000 MaxTruncation = std::max(MaxTruncation, 16u);
1008 MaxTruncation = std::max(MaxTruncation, 8u);
1012 return MaxTruncation;
1020 if ((HiTZ + LoLZ) >= Num)
1032 unsigned Hi32 =
Hi_32(Imm);
1033 unsigned Lo32 =
Lo_32(Imm);
1034 SDNode *Result =
nullptr;
1037 auto getI32Imm = [CurDAG, dl](
unsigned Imm) {
1051 if (TZ > 15 && (LZ > 32 || LO > 32))
1053 getI32Imm((Imm >> 16) & 0xffff));
1057 assert(LZ < 64 &&
"Unexpected leading zeros here.");
1063 uint64_t ImmHi16 = (Imm >> 16) & 0xffff;
1064 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
1065 Result = CurDAG->
getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
1067 getI32Imm(Imm & 0xffff));
1075 if ((LZ + FO + TZ) > 48) {
1077 getI32Imm((Imm >> TZ) & 0xffff));
1079 getI32Imm(TZ), getI32Imm(LZ));
1096 if ((LZ + TO) > 48) {
1100 assert(LZ <= 32 &&
"Unexpected shift value.");
1102 getI32Imm((Imm >> (48 - LZ) & 0xffff)));
1104 getI32Imm(48 - LZ), getI32Imm(LZ));
1122 if ((LZ + FO + TO) > 48) {
1124 getI32Imm((Imm >> TO) & 0xffff));
1126 getI32Imm(TO), getI32Imm(LZ));
1132 if (LZ == 32 && ((Lo32 & 0x8000) == 0)) {
1134 getI32Imm(Lo32 & 0xffff));
1136 getI32Imm(Lo32 >> 16));
1160 getI32Imm(RotImm & 0xffff));
1162 getI32Imm(Shift), getI32Imm(0));
1169 uint64_t ImmHi16 = (Lo32 >> 16) & 0xffff;
1173 CurDAG->
getMachineNode(PPC::LI8, dl, MVT::i64, getI32Imm(ImmLo16));
1176 CurDAG->
getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(ImmHi16));
1180 CurDAG->
getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(ImmHi16));
1182 SDValue(Result, 0), getI32Imm(ImmLo16));
1199 if ((LZ + FO + TZ) > 32) {
1200 uint64_t ImmHi16 = (Imm >> (TZ + 16)) & 0xffff;
1201 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
1202 Result = CurDAG->
getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
1204 getI32Imm((Imm >> TZ) & 0xffff));
1206 getI32Imm(TZ), getI32Imm(LZ));
1213 if ((LZ + TO) > 32) {
1217 assert(LZ <= 32 &&
"Unexpected shift value.");
1219 getI32Imm((Imm >> (48 - LZ)) & 0xffff));
1221 getI32Imm((Imm >> (32 - LZ)) & 0xffff));
1223 getI32Imm(32 - LZ), getI32Imm(LZ));
1231 if ((LZ + FO + TO) > 32) {
1233 getI32Imm((Imm >> (TO + 16)) & 0xffff));
1235 getI32Imm((Imm >> TO) & 0xffff));
1237 getI32Imm(TO), getI32Imm(LZ));
1249 uint64_t ImmHi16 = (RotImm >> 16) & 0xffff;
1250 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
1251 Result = CurDAG->
getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
1253 getI32Imm(RotImm & 0xffff));
1255 getI32Imm(Shift), getI32Imm(0));
1273 unsigned Hi32 =
Hi_32(Imm);
1274 unsigned Lo32 =
Lo_32(Imm);
1276 auto getI32Imm = [CurDAG, dl](
unsigned Imm) {
1280 auto getI64Imm = [CurDAG, dl](
uint64_t Imm) {
1295 SDNode *Result =
nullptr;
1302 if ((LZ + FO + TZ) > 30) {
1303 APInt SignedInt34 =
APInt(34, (Imm >> TZ) & 0x3ffffffff);
1306 getI64Imm(Extended.getZExtValue()));
1308 getI32Imm(TZ), getI32Imm(LZ));
1324 if ((LZ + TO) > 30) {
1325 APInt SignedInt34 =
APInt(34, (Imm >> (30 - LZ)) & 0x3ffffffff);
1328 getI64Imm(Extended.getZExtValue()));
1330 getI32Imm(30 - LZ), getI32Imm(LZ));
1337 if ((LZ + FO + TO) > 30) {
1338 APInt SignedInt34 =
APInt(34, (Imm >> TO) & 0x3ffffffff);
1341 getI64Imm(Extended.getZExtValue()));
1343 getI32Imm(TO), getI32Imm(LZ));
1355 for (
unsigned Shift = 0; Shift < 63; ++Shift) {
1359 CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(RotImm));
1361 SDValue(Result, 0), getI32Imm(Shift),
1369 Result = CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(Hi32));
1379 CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(Hi32));
1381 CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(Lo32));
1388 unsigned *InstCnt =
nullptr) {
1389 unsigned InstCntDirect = 0;
1400 if (Subtarget.hasPrefixInstrs() && InstCntDirect != 1) {
1401 unsigned InstCntDirectP = 0;
1408 if (ResultP && (!Result || InstCntDirectP < InstCntDirect)) {
1410 *InstCnt = InstCntDirectP;
1417 *InstCnt = InstCntDirect;
1420 auto getI32Imm = [CurDAG, dl](
unsigned Imm) {
1429 if (Hi16OfLo32 && Lo16OfLo32) {
1432 bool IsSelected =
false;
1436 CurDAG->
getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(Hi16));
1438 SDValue(Result, 0), getI32Imm(Lo16));
1444 if (Hi16OfHi32 == Lo16OfHi32 && Lo16OfHi32 == Lo16OfLo32) {
1446 Result = getSplat(Hi16OfLo32, Lo16OfLo32);
1451 }
else if (Hi16OfHi32 == Hi16OfLo32 && Hi16OfLo32 == Lo16OfLo32) {
1453 Result = getSplat(Hi16OfHi32, Lo16OfHi32);
1456 getI32Imm(16), getI32Imm(31)};
1458 }
else if (Lo16OfHi32 == Lo16OfLo32 && Hi16OfLo32 == Lo16OfLo32) {
1460 Result = getSplat(Hi16OfHi32, Lo16OfHi32);
1463 getI32Imm(0), getI32Imm(15)};
1466 if (IsSelected ==
true) {
1479 SDValue(Result, 0), getI32Imm(Hi16OfLo32));
1484 getI32Imm(Lo16OfLo32));
1488 *InstCnt = InstCntDirect;
1497 int64_t Imm =
N->getAsZExtVal();
1509class BitPermutationSelector {
1524 VariableKnownToBeZero
1527 ValueBit(
SDValue V,
unsigned I, Kind K = Variable)
1528 :
V(
V), Idx(
I), K(K) {}
1529 ValueBit(Kind K = Variable) : Idx(UINT32_MAX), K(K) {}
1532 return K == ConstZero || K == VariableKnownToBeZero;
1535 bool hasValue()
const {
1536 return K == Variable || K == VariableKnownToBeZero;
1540 assert(hasValue() &&
"Cannot get the value of a constant bit");
1544 unsigned getValueBitIndex()
const {
1545 assert(hasValue() &&
"Cannot get the value bit index of a constant bit");
1554 unsigned StartIdx, EndIdx;
1564 bool Repl32Coalesced;
1566 BitGroup(
SDValue V,
unsigned R,
unsigned S,
unsigned E)
1567 :
V(
V), RLAmt(
R), StartIdx(S), EndIdx(
E), Repl32(
false), Repl32CR(
false),
1568 Repl32Coalesced(
false) {
1569 LLVM_DEBUG(
dbgs() <<
"\tbit group for " <<
V.getNode() <<
" RLAmt = " << R
1570 <<
" [" << S <<
", " <<
E <<
"]\n");
1576 struct ValueRotInfo {
1578 unsigned RLAmt = std::numeric_limits<unsigned>::max();
1579 unsigned NumGroups = 0;
1580 unsigned FirstGroupStartIdx = std::numeric_limits<unsigned>::max();
1581 bool Repl32 =
false;
1583 ValueRotInfo() =
default;
1591 if (Repl32 <
Other.Repl32)
1593 else if (Repl32 >
Other.Repl32)
1595 else if (NumGroups >
Other.NumGroups)
1597 else if (NumGroups <
Other.NumGroups)
1599 else if (RLAmt == 0 &&
Other.RLAmt != 0)
1601 else if (RLAmt != 0 &&
Other.RLAmt == 0)
1603 else if (FirstGroupStartIdx <
Other.FirstGroupStartIdx)
1609 using ValueBitsMemoizedValue = std::pair<bool, SmallVector<ValueBit, 64>>;
1610 using ValueBitsMemoizer =
1611 DenseMap<SDValue, std::unique_ptr<ValueBitsMemoizedValue>>;
1612 ValueBitsMemoizer Memoizer;
1618 std::pair<bool, SmallVector<ValueBit, 64> *> getValueBits(
SDValue V,
1620 auto &ValueEntry = Memoizer[
V];
1622 return std::make_pair(ValueEntry->first, &ValueEntry->second);
1623 ValueEntry.reset(
new ValueBitsMemoizedValue());
1624 bool &Interesting = ValueEntry->first;
1626 Bits.resize(NumBits);
1628 switch (
V.getOpcode()) {
1633 unsigned RotAmt =
V.getConstantOperandVal(1) & (NumBits - 1);
1635 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1637 for (
unsigned i = 0; i < NumBits; ++i)
1638 Bits[i] = LHSBits[i < RotAmt ? i + (NumBits - RotAmt) : i - RotAmt];
1640 return std::make_pair(Interesting =
true, &Bits);
1647 unsigned ShiftAmt =
V.getConstantOperandVal(1) & ((NumBits << 1) - 1);
1649 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1651 if (ShiftAmt >= NumBits) {
1652 for (
unsigned i = 0; i < NumBits; ++i)
1653 Bits[i] = ValueBit(ValueBit::ConstZero);
1655 for (
unsigned i = ShiftAmt; i < NumBits; ++i)
1656 Bits[i] = LHSBits[i - ShiftAmt];
1657 for (
unsigned i = 0; i < ShiftAmt; ++i)
1658 Bits[i] = ValueBit(ValueBit::ConstZero);
1661 return std::make_pair(Interesting =
true, &Bits);
1668 unsigned ShiftAmt =
V.getConstantOperandVal(1) & ((NumBits << 1) - 1);
1670 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1672 if (ShiftAmt >= NumBits) {
1673 for (
unsigned i = 0; i < NumBits; ++i)
1674 Bits[i] = ValueBit(ValueBit::ConstZero);
1676 for (
unsigned i = 0; i < NumBits - ShiftAmt; ++i)
1677 Bits[i] = LHSBits[i + ShiftAmt];
1678 for (
unsigned i = NumBits - ShiftAmt; i < NumBits; ++i)
1679 Bits[i] = ValueBit(ValueBit::ConstZero);
1682 return std::make_pair(Interesting =
true, &Bits);
1687 uint64_t
Mask =
V.getConstantOperandVal(1);
1694 std::tie(Interesting, LHSBits) = getValueBits(
V.getOperand(0), NumBits);
1696 for (
unsigned i = 0; i < NumBits; ++i)
1697 if (((Mask >> i) & 1) == 1)
1698 Bits[i] = (*LHSBits)[i];
1702 if ((*LHSBits)[i].
isZero())
1703 Bits[i] = (*LHSBits)[i];
1705 Bits[i] = ValueBit(ValueBit::ConstZero);
1708 return std::make_pair(Interesting, &Bits);
1712 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1713 const auto &RHSBits = *getValueBits(
V.getOperand(1), NumBits).second;
1715 bool AllDisjoint =
true;
1717 unsigned LastIdx = 0;
1718 for (
unsigned i = 0; i < NumBits; ++i) {
1726 if (LHSBits[i].hasValue() && LHSBits[i].getValue() == LastVal &&
1727 LHSBits[i].getValueBitIndex() == LastIdx + 1)
1728 Bits[i] = LHSBits[i];
1729 else if (RHSBits[i].hasValue() && RHSBits[i].getValue() == LastVal &&
1730 RHSBits[i].getValueBitIndex() == LastIdx + 1)
1731 Bits[i] = RHSBits[i];
1733 Bits[i] = ValueBit(ValueBit::ConstZero);
1735 else if (LHSBits[i].
isZero())
1736 Bits[i] = RHSBits[i];
1737 else if (RHSBits[i].
isZero())
1738 Bits[i] = LHSBits[i];
1740 AllDisjoint =
false;
1744 if (Bits[i].hasValue()) {
1745 LastVal =
Bits[i].getValue();
1746 LastIdx =
Bits[i].getValueBitIndex();
1749 if (LastVal) LastVal =
SDValue();
1757 return std::make_pair(Interesting =
true, &Bits);
1761 if (
V.getValueType() != MVT::i64 ||
1762 V.getOperand(0).getValueType() != MVT::i32)
1766 const unsigned NumOperandBits = 32;
1767 std::tie(Interesting, LHSBits) = getValueBits(
V.getOperand(0),
1770 for (
unsigned i = 0; i < NumOperandBits; ++i)
1771 Bits[i] = (*LHSBits)[i];
1773 for (
unsigned i = NumOperandBits; i < NumBits; ++i)
1774 Bits[i] = ValueBit(ValueBit::ConstZero);
1776 return std::make_pair(Interesting, &Bits);
1779 EVT
FromType =
V.getOperand(0).getValueType();
1780 EVT ToType =
V.getValueType();
1782 if (FromType != MVT::i64 || ToType != MVT::i32)
1784 const unsigned NumAllBits =
FromType.getSizeInBits();
1786 std::tie(Interesting, InBits) = getValueBits(
V.getOperand(0),
1792 bool UseUpper32bit =
false;
1793 for (
unsigned i = 0; i < NumValidBits; ++i)
1794 if ((*InBits)[i].hasValue() && (*InBits)[i].getValueBitIndex() >= 32) {
1795 UseUpper32bit =
true;
1801 for (
unsigned i = 0; i < NumValidBits; ++i)
1802 Bits[i] = (*InBits)[i];
1804 return std::make_pair(Interesting, &Bits);
1810 std::tie(Interesting, LHSBits) = getValueBits(
V.getOperand(0),
1814 const unsigned NumValidBits =
FromType.getSizeInBits();
1815 for (
unsigned i = 0; i < NumValidBits; ++i)
1816 Bits[i] = (*LHSBits)[i];
1820 for (
unsigned i = NumValidBits; i < NumBits; ++i)
1821 Bits[i] = (*LHSBits)[i].hasValue()
1822 ? ValueBit((*LHSBits)[i].getValue(),
1823 (*LHSBits)[i].getValueBitIndex(),
1824 ValueBit::VariableKnownToBeZero)
1825 : ValueBit(ValueBit::ConstZero);
1827 return std::make_pair(Interesting, &Bits);
1832 EVT VT =
LD->getMemoryVT();
1835 for (
unsigned i = 0; i < NumValidBits; ++i)
1836 Bits[i] = ValueBit(V, i);
1839 for (
unsigned i = NumValidBits; i < NumBits; ++i)
1840 Bits[i] = ValueBit(V, i, ValueBit::VariableKnownToBeZero);
1844 return std::make_pair(Interesting =
false, &Bits);
1849 for (
unsigned i = 0; i < NumBits; ++i)
1850 Bits[i] = ValueBit(V, i);
1852 return std::make_pair(Interesting =
false, &Bits);
1857 void computeRotationAmounts() {
1859 RLAmt.resize(
Bits.size());
1860 for (
unsigned i = 0; i <
Bits.size(); ++i)
1861 if (Bits[i].hasValue()) {
1862 unsigned VBI =
Bits[i].getValueBitIndex();
1866 RLAmt[i] =
Bits.size() - (VBI - i);
1867 }
else if (Bits[i].
isZero()) {
1869 RLAmt[i] = UINT32_MAX;
1878 void collectBitGroups(
bool LateMask) {
1881 unsigned LastRLAmt = RLAmt[0];
1883 unsigned LastGroupStartIdx = 0;
1884 bool IsGroupOfZeros = !
Bits[LastGroupStartIdx].hasValue();
1885 for (
unsigned i = 1; i <
Bits.size(); ++i) {
1886 unsigned ThisRLAmt = RLAmt[i];
1888 if (LateMask && !ThisValue) {
1889 ThisValue = LastValue;
1890 ThisRLAmt = LastRLAmt;
1893 if (BitGroups.empty())
1894 LastGroupStartIdx = 0;
1901 if (IsGroupOfZeros && Bits[i].
isZero())
1906 if (ThisRLAmt == LastRLAmt && ThisValue == LastValue)
1909 if (!(IsGroupOfZeros && ThisValue && !Bits[i].
isZero()))
1913 BitGroups.push_back(BitGroup(LastValue, LastRLAmt, LastGroupStartIdx,
1915 LastRLAmt = ThisRLAmt;
1916 LastValue = ThisValue;
1917 LastGroupStartIdx = i;
1918 IsGroupOfZeros = !
Bits[LastGroupStartIdx].hasValue();
1921 BitGroups.push_back(BitGroup(LastValue, LastRLAmt, LastGroupStartIdx,
1924 if (BitGroups.empty())
1928 if (BitGroups.size() > 1) {
1932 if (BitGroups[0].StartIdx == 0 &&
1933 BitGroups[BitGroups.size()-1].EndIdx ==
Bits.size()-1 &&
1934 BitGroups[0].V == BitGroups[BitGroups.size()-1].V &&
1935 BitGroups[0].RLAmt == BitGroups[BitGroups.size()-1].RLAmt) {
1936 LLVM_DEBUG(
dbgs() <<
"\tcombining final bit group with initial one\n");
1937 BitGroups[BitGroups.size()-1].EndIdx = BitGroups[0].EndIdx;
1938 BitGroups.erase(BitGroups.begin());
1948 void collectValueRotInfo() {
1951 for (
auto &BG : BitGroups) {
1952 unsigned RLAmtKey = BG.RLAmt + (BG.Repl32 ? 64 : 0);
1953 ValueRotInfo &VRI = ValueRots[std::make_pair(BG.V, RLAmtKey)];
1955 VRI.RLAmt = BG.RLAmt;
1956 VRI.Repl32 = BG.Repl32;
1958 VRI.FirstGroupStartIdx = std::min(VRI.FirstGroupStartIdx, BG.StartIdx);
1963 ValueRotsVec.clear();
1964 for (
auto &
I : ValueRots) {
1965 ValueRotsVec.push_back(
I.second);
1978 void assignRepl32BitGroups() {
1989 auto IsAllLow32 = [
this](BitGroup & BG) {
1990 if (BG.StartIdx <= BG.EndIdx) {
1991 for (
unsigned i = BG.StartIdx; i <= BG.EndIdx; ++i) {
1992 if (!Bits[i].hasValue())
1994 if (Bits[i].getValueBitIndex() >= 32)
1998 for (
unsigned i = BG.StartIdx; i <
Bits.size(); ++i) {
1999 if (!Bits[i].hasValue())
2001 if (Bits[i].getValueBitIndex() >= 32)
2004 for (
unsigned i = 0; i <= BG.EndIdx; ++i) {
2005 if (!Bits[i].hasValue())
2007 if (Bits[i].getValueBitIndex() >= 32)
2015 for (
auto &BG : BitGroups) {
2019 if (BG.RLAmt == 0) {
2020 auto PotentiallyMerged = [
this](BitGroup & BG) {
2021 for (
auto &BG2 : BitGroups)
2022 if (&BG != &BG2 && BG.V == BG2.V &&
2023 (BG2.RLAmt == 0 || BG2.RLAmt == 32))
2027 if (!PotentiallyMerged(BG))
2030 if (BG.StartIdx < 32 && BG.EndIdx < 32) {
2031 if (IsAllLow32(BG)) {
2032 if (BG.RLAmt >= 32) {
2040 << BG.V.getNode() <<
" RLAmt = " << BG.RLAmt <<
" ["
2041 << BG.StartIdx <<
", " << BG.EndIdx <<
"]\n");
2047 for (
auto I = BitGroups.begin();
I != BitGroups.end();) {
2050 auto IP = (
I == BitGroups.begin()) ?
2051 std::prev(BitGroups.end()) : std::prev(
I);
2052 if (
I->Repl32 && IP->Repl32 &&
I->V == IP->V &&
I->RLAmt == IP->RLAmt &&
2053 I->StartIdx == (IP->EndIdx + 1) % 64 &&
I != IP) {
2055 LLVM_DEBUG(dbgs() <<
"\tcombining 32-bit replicated bit group for "
2056 << I->V.getNode() <<
" RLAmt = " << I->RLAmt <<
" ["
2057 << I->StartIdx <<
", " << I->EndIdx
2058 <<
"] with group with range [" << IP->StartIdx <<
", "
2059 << IP->EndIdx <<
"]\n");
2061 IP->EndIdx = I->EndIdx;
2062 IP->Repl32CR = IP->Repl32CR || I->Repl32CR;
2063 IP->Repl32Coalesced = true;
2064 I = BitGroups.erase(I);
2073 if (I->StartIdx == 32 && I->EndIdx == 63) {
2074 assert(std::next(I) == BitGroups.end() &&
2075 "bit group ends at index 63 but there is another?");
2076 auto IN = BitGroups.begin();
2078 if (IP->Repl32 && IN->Repl32 && I->V == IP->V && I->V == IN->V &&
2079 (I->RLAmt % 32) == IP->RLAmt && (I->RLAmt % 32) == IN->RLAmt &&
2080 IP->EndIdx == 31 && IN->StartIdx == 0 && I != IP &&
2083 LLVM_DEBUG(dbgs() <<
"\tcombining bit group for " << I->V.getNode()
2084 <<
" RLAmt = " << I->RLAmt <<
" [" << I->StartIdx
2085 <<
", " << I->EndIdx
2086 <<
"] with 32-bit replicated groups with ranges ["
2087 << IP->StartIdx <<
", " << IP->EndIdx <<
"] and ["
2088 << IN->StartIdx <<
", " << IN->EndIdx <<
"]\n");
2096 IP->Repl32CR = IP->Repl32CR || I->RLAmt >= 32;
2097 IP->Repl32Coalesced = true;
2098 I = BitGroups.erase(I);
2103 IP->EndIdx = IN->EndIdx;
2104 IP->Repl32CR = IP->Repl32CR || IN->Repl32CR || I->RLAmt >= 32;
2105 IP->Repl32Coalesced = true;
2106 I = BitGroups.erase(I);
2107 BitGroups.erase(BitGroups.begin());
2121 SDValue getI32Imm(
unsigned Imm,
const SDLoc &dl) {
2122 return CurDAG->getTargetConstant(Imm, dl, MVT::i32);
2125 uint64_t getZerosMask() {
2127 for (
unsigned i = 0; i <
Bits.size(); ++i) {
2128 if (Bits[i].hasValue())
2130 Mask |= (UINT64_C(1) << i);
2141 if (
V.getValueSizeInBits() == 64)
2144 assert(
V.getValueSizeInBits() == 32);
2145 SDValue SubRegIdx = CurDAG->getTargetConstant(PPC::sub_32, dl, MVT::i32);
2146 SDValue ImDef =
SDValue(CurDAG->getMachineNode(PPC::IMPLICIT_DEF, dl,
2148 SDValue ExtVal =
SDValue(CurDAG->getMachineNode(PPC::INSERT_SUBREG, dl,
2155 if (
V.getValueSizeInBits() == 32)
2158 assert(
V.getValueSizeInBits() == 64);
2159 SDValue SubRegIdx = CurDAG->getTargetConstant(PPC::sub_32, dl, MVT::i32);
2160 SDValue SubVal =
SDValue(CurDAG->getMachineNode(PPC::EXTRACT_SUBREG, dl,
2161 MVT::i32, V, SubRegIdx), 0);
2168 void SelectAndParts32(
const SDLoc &dl,
SDValue &Res,
unsigned *InstCnt) {
2172 for (ValueRotInfo &VRI : ValueRotsVec) {
2174 for (
unsigned i = 0; i <
Bits.size(); ++i) {
2175 if (!Bits[i].hasValue() || Bits[i].getValue() != VRI.V)
2177 if (RLAmt[i] != VRI.RLAmt)
2183 unsigned ANDIMask = (
Mask & UINT16_MAX), ANDISMask = Mask >> 16;
2184 assert((ANDIMask != 0 || ANDISMask != 0) &&
2185 "No set bits in mask for value bit groups");
2186 bool NeedsRotate = VRI.RLAmt != 0;
2202 unsigned NumAndInsts = (unsigned) NeedsRotate +
2203 (
unsigned) (ANDIMask != 0) +
2204 (
unsigned) (ANDISMask != 0) +
2205 (
unsigned) (ANDIMask != 0 && ANDISMask != 0) +
2206 (
unsigned) (bool) Res;
2208 LLVM_DEBUG(
dbgs() <<
"\t\trotation groups for " << VRI.V.getNode()
2209 <<
" RL: " << VRI.RLAmt <<
":"
2210 <<
"\n\t\t\tisel using masking: " << NumAndInsts
2211 <<
" using rotates: " << VRI.NumGroups <<
"\n");
2213 if (NumAndInsts >= VRI.NumGroups)
2218 if (InstCnt) *InstCnt += NumAndInsts;
2223 { TruncateToInt32(VRI.V, dl), getI32Imm(VRI.RLAmt, dl),
2224 getI32Imm(0, dl), getI32Imm(31, dl) };
2225 VRot =
SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32,
2228 VRot = TruncateToInt32(VRI.V, dl);
2233 ANDIVal =
SDValue(CurDAG->getMachineNode(PPC::ANDI_rec, dl, MVT::i32,
2234 VRot, getI32Imm(ANDIMask, dl)),
2238 SDValue(CurDAG->getMachineNode(PPC::ANDIS_rec, dl, MVT::i32, VRot,
2239 getI32Imm(ANDISMask, dl)),
2244 TotalVal = ANDISVal;
2248 TotalVal =
SDValue(CurDAG->getMachineNode(PPC::OR, dl, MVT::i32,
2249 ANDIVal, ANDISVal), 0);
2254 Res =
SDValue(CurDAG->getMachineNode(PPC::OR, dl, MVT::i32,
2259 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
2260 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt;
2266 SDNode *Select32(SDNode *
N,
bool LateMask,
unsigned *InstCnt) {
2270 if (InstCnt) *InstCnt = 0;
2273 SelectAndParts32(dl, Res, InstCnt);
2278 if ((!NeedMask || LateMask) && !Res) {
2279 ValueRotInfo &VRI = ValueRotsVec[0];
2281 if (InstCnt) *InstCnt += 1;
2283 { TruncateToInt32(VRI.V, dl), getI32Imm(VRI.RLAmt, dl),
2284 getI32Imm(0, dl), getI32Imm(31, dl) };
2285 Res =
SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32,
Ops),
2288 Res = TruncateToInt32(VRI.V, dl);
2292 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
2293 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt;
2297 if (InstCnt) *InstCnt += BitGroups.size();
2300 for (
auto &BG : BitGroups) {
2303 { TruncateToInt32(BG.V, dl), getI32Imm(BG.RLAmt, dl),
2304 getI32Imm(
Bits.size() - BG.EndIdx - 1, dl),
2305 getI32Imm(
Bits.size() - BG.StartIdx - 1, dl) };
2306 Res =
SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32,
Ops), 0);
2309 { Res, TruncateToInt32(BG.V, dl), getI32Imm(BG.RLAmt, dl),
2310 getI32Imm(
Bits.size() - BG.EndIdx - 1, dl),
2311 getI32Imm(
Bits.size() - BG.StartIdx - 1, dl) };
2312 Res =
SDValue(CurDAG->getMachineNode(PPC::RLWIMI, dl, MVT::i32,
Ops), 0);
2317 unsigned Mask = (unsigned) getZerosMask();
2319 unsigned ANDIMask = (
Mask & UINT16_MAX), ANDISMask = Mask >> 16;
2320 assert((ANDIMask != 0 || ANDISMask != 0) &&
2321 "No set bits in zeros mask?");
2323 if (InstCnt) *InstCnt += (unsigned) (ANDIMask != 0) +
2324 (unsigned) (ANDISMask != 0) +
2325 (unsigned) (ANDIMask != 0 && ANDISMask != 0);
2329 ANDIVal =
SDValue(CurDAG->getMachineNode(PPC::ANDI_rec, dl, MVT::i32,
2330 Res, getI32Imm(ANDIMask, dl)),
2334 SDValue(CurDAG->getMachineNode(PPC::ANDIS_rec, dl, MVT::i32, Res,
2335 getI32Imm(ANDISMask, dl)),
2343 Res =
SDValue(CurDAG->getMachineNode(PPC::OR, dl, MVT::i32,
2344 ANDIVal, ANDISVal), 0);
2350 unsigned SelectRotMask64Count(
unsigned RLAmt,
bool Repl32,
2351 unsigned MaskStart,
unsigned MaskEnd,
2355 unsigned InstMaskStart = 64 - MaskEnd - 1,
2356 InstMaskEnd = 64 - MaskStart - 1;
2361 if ((!IsIns && (InstMaskEnd == 63 || InstMaskStart == 0)) ||
2362 InstMaskEnd == 63 - RLAmt)
2370 SDValue SelectRotMask64(
SDValue V,
const SDLoc &dl,
unsigned RLAmt,
2371 bool Repl32,
unsigned MaskStart,
unsigned MaskEnd,
2372 unsigned *InstCnt =
nullptr) {
2375 unsigned InstMaskStart = 64 - MaskEnd - 1,
2376 InstMaskEnd = 64 - MaskStart - 1;
2378 if (InstCnt) *InstCnt += 1;
2384 assert(InstMaskStart >= 32 &&
"Mask cannot start out of range");
2385 assert(InstMaskEnd >= 32 &&
"Mask cannot end out of range");
2387 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2388 getI32Imm(InstMaskStart - 32, dl), getI32Imm(InstMaskEnd - 32, dl) };
2389 return SDValue(CurDAG->getMachineNode(PPC::RLWINM8, dl, MVT::i64,
2393 if (InstMaskEnd == 63) {
2395 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2396 getI32Imm(InstMaskStart, dl) };
2397 return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64,
Ops), 0);
2400 if (InstMaskStart == 0) {
2402 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2403 getI32Imm(InstMaskEnd, dl) };
2404 return SDValue(CurDAG->getMachineNode(PPC::RLDICR, dl, MVT::i64,
Ops), 0);
2407 if (InstMaskEnd == 63 - RLAmt) {
2409 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2410 getI32Imm(InstMaskStart, dl) };
2411 return SDValue(CurDAG->getMachineNode(PPC::RLDIC, dl, MVT::i64,
Ops), 0);
2420 if (InstCnt) *InstCnt += 1;
2423 unsigned RLAmt2 = MaskStart;
2426 unsigned RLAmt1 = (64 + RLAmt - RLAmt2) % 64;
2428 V = SelectRotMask64(V, dl, RLAmt1,
false, 0, 63);
2429 return SelectRotMask64(V, dl, RLAmt2,
false, MaskStart, MaskEnd);
2435 unsigned RLAmt,
bool Repl32,
unsigned MaskStart,
2436 unsigned MaskEnd,
unsigned *InstCnt =
nullptr) {
2439 unsigned InstMaskStart = 64 - MaskEnd - 1,
2440 InstMaskEnd = 64 - MaskStart - 1;
2442 if (InstCnt) *InstCnt += 1;
2448 assert(InstMaskStart >= 32 &&
"Mask cannot start out of range");
2449 assert(InstMaskEnd >= 32 &&
"Mask cannot end out of range");
2451 { ExtendToInt64(
Base, dl), ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2452 getI32Imm(InstMaskStart - 32, dl), getI32Imm(InstMaskEnd - 32, dl) };
2453 return SDValue(CurDAG->getMachineNode(PPC::RLWIMI8, dl, MVT::i64,
2457 if (InstMaskEnd == 63 - RLAmt) {
2459 { ExtendToInt64(
Base, dl), ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2460 getI32Imm(InstMaskStart, dl) };
2461 return SDValue(CurDAG->getMachineNode(PPC::RLDIMI, dl, MVT::i64,
Ops), 0);
2470 if (InstCnt) *InstCnt += 1;
2473 unsigned RLAmt2 = MaskStart;
2476 unsigned RLAmt1 = (64 + RLAmt - RLAmt2) % 64;
2478 V = SelectRotMask64(V, dl, RLAmt1,
false, 0, 63);
2479 return SelectRotMaskIns64(
Base, V, dl, RLAmt2,
false, MaskStart, MaskEnd);
2482 void SelectAndParts64(
const SDLoc &dl,
SDValue &Res,
unsigned *InstCnt) {
2495 for (ValueRotInfo &VRI : ValueRotsVec) {
2503 auto MatchingBG = [VRI](
const BitGroup &BG) {
2507 unsigned EffRLAmt = BG.RLAmt;
2508 if (!VRI.Repl32 && BG.Repl32) {
2509 if (BG.StartIdx < 32 && BG.EndIdx < 32 && BG.StartIdx <= BG.EndIdx &&
2510 !BG.Repl32Coalesced) {
2516 }
else if (VRI.Repl32 != BG.Repl32) {
2520 return VRI.RLAmt == EffRLAmt;
2523 for (
auto &BG : BitGroups) {
2524 if (!MatchingBG(BG))
2527 if (BG.StartIdx <= BG.EndIdx) {
2528 for (
unsigned i = BG.StartIdx; i <= BG.EndIdx; ++i)
2529 Mask |= (UINT64_C(1) << i);
2531 for (
unsigned i = BG.StartIdx; i <
Bits.size(); ++i)
2532 Mask |= (UINT64_C(1) << i);
2533 for (
unsigned i = 0; i <= BG.EndIdx; ++i)
2534 Mask |= (UINT64_C(1) << i);
2543 unsigned ANDIMask = (
Mask & UINT16_MAX),
2544 ANDISMask = (Mask >> 16) & UINT16_MAX;
2546 bool NeedsRotate = VRI.RLAmt || (VRI.Repl32 && !
isUInt<32>(Mask));
2548 unsigned NumAndInsts = (unsigned) NeedsRotate +
2549 (
unsigned) (bool) Res;
2550 unsigned NumOfSelectInsts = 0;
2552 assert(NumOfSelectInsts > 0 &&
"Failed to select an i64 constant.");
2554 NumAndInsts += (unsigned) (ANDIMask != 0) + (unsigned) (ANDISMask != 0) +
2555 (unsigned) (ANDIMask != 0 && ANDISMask != 0);
2557 NumAndInsts += NumOfSelectInsts + 1;
2559 unsigned NumRLInsts = 0;
2560 bool FirstBG =
true;
2561 bool MoreBG =
false;
2562 for (
auto &BG : BitGroups) {
2563 if (!MatchingBG(BG)) {
2568 SelectRotMask64Count(BG.RLAmt, BG.Repl32, BG.StartIdx, BG.EndIdx,
2573 LLVM_DEBUG(
dbgs() <<
"\t\trotation groups for " << VRI.V.getNode()
2574 <<
" RL: " << VRI.RLAmt << (VRI.Repl32 ?
" (32):" :
":")
2575 <<
"\n\t\t\tisel using masking: " << NumAndInsts
2576 <<
" using rotates: " << NumRLInsts <<
"\n");
2582 if (NumAndInsts > NumRLInsts)
2587 if ((Use32BitInsts || MoreBG) && NumAndInsts == NumRLInsts)
2592 if (InstCnt) *InstCnt += NumAndInsts;
2599 if (VRI.RLAmt || (VRI.Repl32 && !
isUInt<32>(Mask)))
2600 VRot = SelectRotMask64(VRI.V, dl, VRI.RLAmt, VRI.Repl32,
2601 VRI.Repl32 ? 31 : 0, VRI.Repl32 ? 30 : 63);
2606 if (Use32BitInsts) {
2607 assert((ANDIMask != 0 || ANDISMask != 0) &&
2608 "No set bits in mask when using 32-bit ands for 64-bit value");
2612 ANDIVal =
SDValue(CurDAG->getMachineNode(PPC::ANDI8_rec, dl, MVT::i64,
2613 ExtendToInt64(VRot, dl),
2614 getI32Imm(ANDIMask, dl)),
2618 SDValue(CurDAG->getMachineNode(PPC::ANDIS8_rec, dl, MVT::i64,
2619 ExtendToInt64(VRot, dl),
2620 getI32Imm(ANDISMask, dl)),
2624 TotalVal = ANDISVal;
2628 TotalVal =
SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64,
2629 ExtendToInt64(ANDIVal, dl), ANDISVal), 0);
2633 SDValue(CurDAG->getMachineNode(PPC::AND8, dl, MVT::i64,
2634 ExtendToInt64(VRot, dl), TotalVal),
2641 Res =
SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64,
2642 ExtendToInt64(Res, dl), TotalVal),
2647 eraseMatchingBitGroups(MatchingBG);
2652 SDNode *Select64(SDNode *
N,
bool LateMask,
unsigned *InstCnt) {
2656 if (InstCnt) *InstCnt = 0;
2659 SelectAndParts64(dl, Res, InstCnt);
2664 if ((!NeedMask || LateMask) && !Res) {
2668 unsigned MaxGroupsIdx = 0;
2669 if (!ValueRotsVec[0].Repl32) {
2670 for (
unsigned i = 0, ie = ValueRotsVec.size(); i < ie; ++i)
2671 if (ValueRotsVec[i].Repl32) {
2672 if (ValueRotsVec[i].NumGroups > ValueRotsVec[0].NumGroups)
2678 ValueRotInfo &VRI = ValueRotsVec[MaxGroupsIdx];
2679 bool NeedsRotate =
false;
2682 }
else if (VRI.Repl32) {
2683 for (
auto &BG : BitGroups) {
2684 if (BG.V != VRI.V || BG.RLAmt != VRI.RLAmt ||
2685 BG.Repl32 != VRI.Repl32)
2690 if (BG.StartIdx < 32 && BG.EndIdx < 32 && BG.StartIdx < BG.EndIdx)
2699 Res = SelectRotMask64(VRI.V, dl, VRI.RLAmt, VRI.Repl32,
2700 VRI.Repl32 ? 31 : 0, VRI.Repl32 ? 30 : 63,
2707 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
2708 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt &&
2709 BG.Repl32 == VRI.Repl32;
2716 for (
auto I = BitGroups.begin(), IE = BitGroups.end();
I != IE; ++
I) {
2717 if (SelectRotMask64Count(
I->RLAmt,
I->Repl32,
I->StartIdx,
I->EndIdx,
2719 SelectRotMask64Count(
I->RLAmt,
I->Repl32,
I->StartIdx,
I->EndIdx,
2721 if (
I != BitGroups.begin()) {
2724 BitGroups.insert(BitGroups.begin(), BG);
2732 for (
auto &BG : BitGroups) {
2734 Res = SelectRotMask64(BG.V, dl, BG.RLAmt, BG.Repl32, BG.StartIdx,
2735 BG.EndIdx, InstCnt);
2737 Res = SelectRotMaskIns64(Res, BG.V, dl, BG.RLAmt, BG.Repl32,
2738 BG.StartIdx, BG.EndIdx, InstCnt);
2742 uint64_t
Mask = getZerosMask();
2749 unsigned ANDIMask = (
Mask & UINT16_MAX),
2750 ANDISMask = (Mask >> 16) & UINT16_MAX;
2752 if (Use32BitInsts) {
2753 assert((ANDIMask != 0 || ANDISMask != 0) &&
2754 "No set bits in mask when using 32-bit ands for 64-bit value");
2756 if (InstCnt) *InstCnt += (unsigned) (ANDIMask != 0) +
2757 (unsigned) (ANDISMask != 0) +
2758 (unsigned) (ANDIMask != 0 && ANDISMask != 0);
2762 ANDIVal =
SDValue(CurDAG->getMachineNode(PPC::ANDI8_rec, dl, MVT::i64,
2763 ExtendToInt64(Res, dl),
2764 getI32Imm(ANDIMask, dl)),
2768 SDValue(CurDAG->getMachineNode(PPC::ANDIS8_rec, dl, MVT::i64,
2769 ExtendToInt64(Res, dl),
2770 getI32Imm(ANDISMask, dl)),
2778 Res =
SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64,
2779 ExtendToInt64(ANDIVal, dl), ANDISVal), 0);
2781 unsigned NumOfSelectInsts = 0;
2784 Res =
SDValue(CurDAG->getMachineNode(PPC::AND8, dl, MVT::i64,
2785 ExtendToInt64(Res, dl), MaskVal),
2788 *InstCnt += NumOfSelectInsts + 1;
2795 SDNode *
Select(SDNode *
N,
bool LateMask,
unsigned *InstCnt =
nullptr) {
2797 collectBitGroups(LateMask);
2798 if (BitGroups.empty())
2802 if (
Bits.size() == 64)
2803 assignRepl32BitGroups();
2806 collectValueRotInfo();
2808 if (
Bits.size() == 32) {
2809 return Select32(
N, LateMask, InstCnt);
2811 assert(
Bits.size() == 64 &&
"Not 64 bits here?");
2812 return Select64(
N, LateMask, InstCnt);
2818 void eraseMatchingBitGroups(function_ref<
bool(
const BitGroup &)>
F) {
2824 bool NeedMask =
false;
2829 DenseMap<std::pair<SDValue, unsigned>, ValueRotInfo> ValueRots;
2832 SelectionDAG *CurDAG =
nullptr;
2835 BitPermutationSelector(SelectionDAG *DAG)
2844 getValueBits(
SDValue(
N, 0),
N->getValueType(0).getSizeInBits());
2849 LLVM_DEBUG(
dbgs() <<
"Considering bit-permutation-based instruction"
2850 " selection for: ");
2854 computeRotationAmounts();
2867 unsigned InstCnt = 0, InstCntLateMask = 0;
2869 SDNode *
RN =
Select(
N,
false, &InstCnt);
2870 LLVM_DEBUG(
dbgs() <<
"\t\tisel would use " << InstCnt <<
" instructions\n");
2873 SDNode *RNLM =
Select(
N,
true, &InstCntLateMask);
2875 <<
" instructions\n");
2877 if (InstCnt <= InstCntLateMask) {
2887class IntegerCompareEliminator {
2888 SelectionDAG *CurDAG;
2892 enum ExtOrTruncConversion { Ext, Trunc };
2900 enum SetccInGPROpts { ZExtOrig, ZExtInvert, SExtOrig, SExtInvert };
2910 enum ZeroCompare { GEZExt, GESExt, LEZExt, LESExt };
2912 SDNode *tryEXTEND(SDNode *
N);
2913 SDNode *tryLogicOpOfCompares(SDNode *
N);
2917 SDValue addExtOrTrunc(
SDValue NatWidthRes, ExtOrTruncConversion Conv);
2921 int64_t RHSValue, SDLoc dl);
2923 int64_t RHSValue, SDLoc dl);
2925 int64_t RHSValue, SDLoc dl);
2927 int64_t RHSValue, SDLoc dl);
2931 IntegerCompareEliminator(SelectionDAG *DAG,
2932 PPCDAGToDAGISel *Sel) : CurDAG(DAG), S(Sel) {
2935 "Only expecting to use this on 64 bit targets.");
2940 switch (
N->getOpcode()) {
2951 return tryEXTEND(
N);
2955 return tryLogicOpOfCompares(
N);
2963SDNode *IntegerCompareEliminator::tryEXTEND(SDNode *
N) {
2966 "Expecting a zero/sign extend node!");
2971 N->getOperand(0).getValueType() == MVT::i1 &&
2973 WideRes = computeLogicOpInGPR(
N->getOperand(0));
2974 else if (
N->getOperand(0).getOpcode() !=
ISD::SETCC)
2978 getSETCCInGPR(
N->getOperand(0),
2980 SetccInGPROpts::SExtOrig : SetccInGPROpts::ZExtOrig);
2986 bool Output32Bit =
N->getValueType(0) == MVT::i32;
2992 if (Input32Bit != Output32Bit)
2993 ConvOp = addExtOrTrunc(WideRes, Input32Bit ? ExtOrTruncConversion::Ext :
2994 ExtOrTruncConversion::Trunc);
3002SDNode *IntegerCompareEliminator::tryLogicOpOfCompares(SDNode *
N) {
3003 if (
N->getValueType(0) != MVT::i1)
3006 "Expected a logic operation on setcc results.");
3008 if (!LoweredLogical)
3013 unsigned SubRegToExtract = IsBitwiseNegate ? PPC::sub_eq : PPC::sub_gt;
3022 if (IsBitwiseNegate &&
3025 else if (IsBitwiseNegate)
3027 OpToConvToRecForm = LoweredLogical.
getOperand(0);
3031 OpToConvToRecForm = LoweredLogical;
3041 if (NewOpc != -1 && IsBitwiseNegate) {
3044 "Expected a PPC::XORI8 only for bitwise negation.");
3046 std::vector<SDValue>
Ops;
3047 for (
int i = 0, e = OpToConvToRecForm.
getNumOperands(); i < e; i++)
3053 MVT::Glue,
Ops), 0);
3055 assert((NewOpc != -1 || !IsBitwiseNegate) &&
3056 "No record form available for AND8/OR8/XOR8?");
3059 dl, MVT::i64, MVT::Glue,
LHS,
RHS),
3071 MVT::i1, CR0Reg, SRIdxVal,
3084SDValue IntegerCompareEliminator::computeLogicOpInGPR(
SDValue LogicOp) {
3086 "Can only handle logic operations here.");
3088 "Can only handle logic operations on i1 values here.");
3100 unsigned OperandOpcode = Operand.getOpcode();
3102 return getSETCCInGPR(Operand, SetccInGPROpts::ZExtOrig);
3104 SDValue InputOp = Operand.getOperand(0);
3107 PPC::RLDICL, dl, InVT, InputOp,
3108 S->getI64Imm(0, dl),
3109 S->getI64Imm(63, dl)), 0);
3111 return computeLogicOpInGPR(Operand);
3120 if (!
LHS || (!
RHS && !IsBitwiseNegation))
3123 NumLogicOpsOnComparison++;
3126 if (
LHS.getValueType() == MVT::i32)
3127 LHS = addExtOrTrunc(
LHS, ExtOrTruncConversion::Ext);
3128 if (!IsBitwiseNegation &&
RHS.getValueType() == MVT::i32)
3129 RHS = addExtOrTrunc(
RHS, ExtOrTruncConversion::Ext);
3134 case ISD::AND: NewOpc = PPC::AND8;
break;
3135 case ISD::OR: NewOpc = PPC::OR8;
break;
3136 case ISD::XOR: NewOpc = PPC::XOR8;
break;
3139 if (IsBitwiseNegation) {
3140 RHS = S->getI64Imm(1, dl);
3141 NewOpc = PPC::XORI8;
3152SDValue IntegerCompareEliminator::signExtendInputIfNeeded(
SDValue Input) {
3154 "Can only sign-extend 32-bit values here.");
3162 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3168 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3173 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3176 SignExtensionsAdded++;
3178 MVT::i64, Input), 0);
3185SDValue IntegerCompareEliminator::zeroExtendInputIfNeeded(
SDValue Input) {
3187 "Can only zero-extend 32-bit values here.");
3197 if (IsTruncateOfZExt)
3198 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3202 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3207 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3211 ZeroExtensionsAdded++;
3213 S->getI64Imm(0, dl),
3214 S->getI64Imm(32, dl)), 0);
3221SDValue IntegerCompareEliminator::addExtOrTrunc(
SDValue NatWidthRes,
3222 ExtOrTruncConversion Conv) {
3223 SDLoc dl(NatWidthRes);
3227 if (Conv == ExtOrTruncConversion::Ext) {
3232 ImDef, NatWidthRes, SubRegIdx), 0);
3235 assert(Conv == ExtOrTruncConversion::Trunc &&
3236 "Unknown convertion between 32 and 64 bit values.");
3242 NatWidthRes, SubRegIdx), 0);
3248IntegerCompareEliminator::getCompoundZeroComparisonInGPR(
SDValue LHS, SDLoc dl,
3249 ZeroCompare CmpTy) {
3250 EVT InVT =
LHS.getValueType();
3251 bool Is32Bit = InVT == MVT::i32;
3256 case ZeroCompare::GEZExt:
3257 case ZeroCompare::GESExt:
3261 case ZeroCompare::LEZExt:
3262 case ZeroCompare::LESExt: {
3265 LHS = signExtendInputIfNeeded(
LHS);
3270 Neg, S->getI64Imm(1, dl),
3271 S->getI64Imm(63, dl)), 0);
3275 S->getI64Imm(~0ULL, dl)), 0);
3285 (CmpTy == ZeroCompare::GEZExt || CmpTy == ZeroCompare::LEZExt))
3287 ToExtend, S->getI64Imm(1, dl),
3288 S->getI64Imm(63, dl)), 0);
3290 (CmpTy == ZeroCompare::GESExt || CmpTy == ZeroCompare::LESExt))
3292 S->getI64Imm(63, dl)), 0);
3294 assert(Is32Bit &&
"Should have handled the 32-bit sequences above.");
3297 case ZeroCompare::GEZExt: {
3298 SDValue ShiftOps[] = { ToExtend, S->getI32Imm(1, dl), S->getI32Imm(31, dl),
3299 S->getI32Imm(31, dl) };
3303 case ZeroCompare::GESExt:
3305 S->getI32Imm(31, dl)), 0);
3306 case ZeroCompare::LEZExt:
3308 S->getI32Imm(1, dl)), 0);
3309 case ZeroCompare::LESExt:
3311 S->getI32Imm(-1, dl)), 0);
3324 int64_t RHSValue, SDLoc dl) {
3328 bool IsRHSZero = RHSValue == 0;
3329 bool IsRHSOne = RHSValue == 1;
3330 bool IsRHSNegOne = RHSValue == -1LL;
3340 SDValue ShiftOps[] = { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl),
3341 S->getI32Imm(31, dl) };
3352 SDValue ShiftOps[] = { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl),
3353 S->getI32Imm(31, dl) };
3357 S->getI32Imm(1, dl)), 0);
3363 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GEZExt);
3369 IsRHSZero = RHSConst && RHSConst->
isZero();
3380 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LEZExt);
3384 LHS = signExtendInputIfNeeded(
LHS);
3385 RHS = signExtendInputIfNeeded(
RHS);
3390 S->getI64Imm(1, dl), S->getI64Imm(63, dl)),
3394 MVT::i64, Shift, S->getI32Imm(1, dl)), 0);
3402 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GEZExt);
3408 LHS = signExtendInputIfNeeded(
LHS);
3409 RHS = signExtendInputIfNeeded(
RHS);
3413 Neg, S->getI32Imm(1, dl), S->getI32Imm(63, dl)), 0);
3419 IsRHSZero = RHSConst && RHSConst->
isZero();
3431 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LEZExt);
3435 SDValue ShiftOps[] = {
LHS, S->getI32Imm(1, dl), S->getI32Imm(31, dl),
3436 S->getI32Imm(31, dl) };
3444 LHS = signExtendInputIfNeeded(
LHS);
3445 RHS = signExtendInputIfNeeded(
RHS);
3449 SUBFNode, S->getI64Imm(1, dl),
3450 S->getI64Imm(63, dl)), 0);
3461 LHS = zeroExtendInputIfNeeded(
LHS);
3462 RHS = zeroExtendInputIfNeeded(
RHS);
3467 Subtract, S->getI64Imm(1, dl),
3468 S->getI64Imm(63, dl)), 0);
3470 S->getI32Imm(1, dl)), 0);
3481 LHS = zeroExtendInputIfNeeded(
LHS);
3482 RHS = zeroExtendInputIfNeeded(
RHS);
3486 Subtract, S->getI64Imm(1, dl),
3487 S->getI64Imm(63, dl)), 0);
3497 int64_t RHSValue, SDLoc dl) {
3501 bool IsRHSZero = RHSValue == 0;
3502 bool IsRHSOne = RHSValue == 1;
3503 bool IsRHSNegOne = RHSValue == -1LL;
3516 SDValue SHLOps[] = { Cntlzw, S->getI32Imm(27, dl),
3517 S->getI32Imm(5, dl), S->getI32Imm(31, dl) };
3535 { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl), S->getI32Imm(31, dl) };
3540 S->getI32Imm(1, dl)), 0);
3547 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GESExt);
3553 IsRHSZero = RHSConst && RHSConst->
isZero();
3562 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LESExt);
3565 LHS = signExtendInputIfNeeded(
LHS);
3566 RHS = signExtendInputIfNeeded(
RHS);
3572 SUBFNode, S->getI64Imm(1, dl),
3573 S->getI64Imm(63, dl)), 0);
3575 S->getI32Imm(-1, dl)), 0);
3582 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GESExt);
3587 LHS = signExtendInputIfNeeded(
LHS);
3588 RHS = signExtendInputIfNeeded(
RHS);
3592 S->getI64Imm(63, dl)), 0);
3598 IsRHSZero = RHSConst && RHSConst->
isZero();
3609 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LESExt);
3613 S->getI32Imm(31, dl)), 0);
3618 LHS = signExtendInputIfNeeded(
LHS);
3619 RHS = signExtendInputIfNeeded(
RHS);
3623 SUBFNode, S->getI64Imm(63, dl)), 0);
3634 LHS = zeroExtendInputIfNeeded(
LHS);
3635 RHS = zeroExtendInputIfNeeded(
RHS);
3640 S->getI32Imm(1, dl), S->getI32Imm(63,dl)),
3643 S->getI32Imm(-1, dl)), 0);
3654 LHS = zeroExtendInputIfNeeded(
LHS);
3655 RHS = zeroExtendInputIfNeeded(
RHS);
3659 Subtract, S->getI64Imm(63, dl)), 0);
3669 int64_t RHSValue, SDLoc dl) {
3673 bool IsRHSZero = RHSValue == 0;
3674 bool IsRHSOne = RHSValue == 1;
3675 bool IsRHSNegOne = RHSValue == -1LL;
3686 S->getI64Imm(58, dl),
3687 S->getI64Imm(63, dl)), 0);
3698 Xor, S->getI32Imm(~0U, dl)), 0);
3708 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GEZExt);
3711 IsRHSZero = RHSConst && RHSConst->
isZero();
3720 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LEZExt);
3723 S->getI64Imm(1, dl),
3724 S->getI64Imm(63, dl)), 0);
3727 S->getI64Imm(63, dl)), 0);
3732 ShiftR, ShiftL, SubtractCarry), 0);
3740 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GEZExt);
3744 S->getI64Imm(~0ULL, dl)), 0);
3748 S->getI64Imm(1, dl),
3749 S->getI64Imm(63, dl)), 0);
3753 IsRHSZero = RHSConst && RHSConst->
isZero();
3763 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LEZExt);
3766 S->getI64Imm(1, dl),
3767 S->getI64Imm(63, dl)), 0);
3770 LHS, S->getI64Imm(63, dl)), 0);
3773 RHS, S->getI64Imm(1, dl),
3774 S->getI64Imm(63, dl)), 0);
3780 SRDINode, SRADINode, SUBFC8Carry), 0);
3782 ADDE8Node, S->getI64Imm(1, dl)), 0);
3797 LHS,
LHS, SUBFC8Carry), 0);
3799 SUBFE8Node, S->getI64Imm(1, dl)), 0);
3814 LHS,
LHS, SubtractCarry), 0);
3826 int64_t RHSValue, SDLoc dl) {
3830 bool IsRHSZero = RHSValue == 0;
3831 bool IsRHSOne = RHSValue == 1;
3832 bool IsRHSNegOne = RHSValue == -1LL;
3844 AddInput, S->getI32Imm(~0U, dl)), 0);
3857 Xor, S->getI32Imm(0, dl)), 0);
3867 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GESExt);
3870 IsRHSZero = RHSConst && RHSConst->
isZero();
3879 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LESExt);
3882 S->getI64Imm(63, dl)), 0);
3885 S->getI64Imm(1, dl),
3886 S->getI64Imm(63, dl)), 0);
3892 ShiftR, ShiftL, SubtractCarry), 0);
3901 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GESExt);
3905 S->getI64Imm(-1, dl)), 0);
3909 S->getI64Imm(63, dl)), 0);
3913 IsRHSZero = RHSConst && RHSConst->
isZero();
3923 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LESExt);
3926 S->getI64Imm(63, dl)), 0);
3930 LHS, S->getI64Imm(63, dl)), 0);
3933 RHS, S->getI64Imm(1, dl),
3934 S->getI64Imm(63, dl)), 0);
3940 SRDINode, SRADINode, SUBFC8Carry), 0);
3943 ADDE8Node, S->getI64Imm(1, dl)), 0);
3960 LHS, SubtractCarry), 0);
3962 ExtSub, ExtSub), 0);
3985static bool allUsesExtend(
SDValue Compare, SelectionDAG *CurDAG) {
3987 "An ISD::SETCC node required here.");
3995 for (
auto *CompareUse :
Compare.getNode()->users())
4000 OmittedForNonExtendUses++;
4010 SetccInGPROpts ConvOpts) {
4013 "An ISD::SETCC node required here.");
4027 EVT InputVT =
LHS.getValueType();
4028 if (InputVT != MVT::i32 && InputVT != MVT::i64)
4031 if (ConvOpts == SetccInGPROpts::ZExtInvert ||
4032 ConvOpts == SetccInGPROpts::SExtInvert)
4035 bool Inputs32Bit = InputVT == MVT::i32;
4040 bool IsSext = ConvOpts == SetccInGPROpts::SExtOrig ||
4041 ConvOpts == SetccInGPROpts::SExtInvert;
4043 if (IsSext && Inputs32Bit)
4044 return get32BitSExtCompare(
LHS,
RHS, CC, RHSValue, dl);
4045 else if (Inputs32Bit)
4046 return get32BitZExtCompare(
LHS,
RHS, CC, RHSValue, dl);
4048 return get64BitSExtCompare(
LHS,
RHS, CC, RHSValue, dl);
4049 return get64BitZExtCompare(
LHS,
RHS, CC, RHSValue, dl);
4054bool PPCDAGToDAGISel::tryIntCompareInGPR(SDNode *
N) {
4055 if (
N->getValueType(0) != MVT::i32 &&
4056 N->getValueType(0) != MVT::i64)
4068 if (!(
CmpInGPR.getNumOccurrences() > 0) && Subtarget->isISA3_1())
4071 switch (
N->getOpcode()) {
4078 IntegerCompareEliminator ICmpElim(CurDAG,
this);
4079 if (SDNode *New = ICmpElim.Select(
N)) {
4080 ReplaceNode(
N, New);
4088bool PPCDAGToDAGISel::tryBitPermutation(SDNode *
N) {
4089 if (
N->getValueType(0) != MVT::i32 &&
4090 N->getValueType(0) != MVT::i64)
4096 switch (
N->getOpcode()) {
4101 if (Subtarget->isISA3_1() &&
N->getValueType(0) == MVT::i32 &&
4103 auto &OpRight =
N->getOperand(1);
4113 BitPermutationSelector BPS(CurDAG);
4114 if (SDNode *New = BPS.Select(
N)) {
4115 ReplaceNode(
N, New);
4128 const SDLoc &dl,
SDValue Chain) {
4132 if (
LHS.getValueType() == MVT::i32) {
4139 getI32Imm(Imm & 0xFFFF, dl)),
4144 getI32Imm(Imm & 0xFFFF, dl)),
4157 getI32Imm(Imm >> 16, dl)), 0);
4159 getI32Imm(Imm & 0xFFFF, dl)), 0);
4165 getI32Imm(Imm & 0xFFFF, dl)), 0);
4171 getI32Imm((
int)SImm & 0xFFFF,
4176 }
else if (
LHS.getValueType() == MVT::i64) {
4183 getI32Imm(Imm & 0xFFFF, dl)),
4188 getI32Imm(Imm & 0xFFFF, dl)),
4202 getI64Imm(Imm >> 16, dl)), 0);
4204 getI64Imm(Imm & 0xFFFF, dl)),
4212 getI64Imm(Imm & 0xFFFF, dl)), 0);
4218 getI64Imm(SImm & 0xFFFF, dl)),
4222 }
else if (
LHS.getValueType() == MVT::f32) {
4223 if (Subtarget->hasSPE()) {
4228 Opc = PPC::EFSCMPEQ;
4236 Opc = PPC::EFSCMPLT;
4244 Opc = PPC::EFSCMPGT;
4249 }
else if (
LHS.getValueType() == MVT::f64) {
4250 if (Subtarget->hasSPE()) {
4255 Opc = PPC::EFDCMPEQ;
4263 Opc = PPC::EFDCMPLT;
4271 Opc = PPC::EFDCMPGT;
4275 Opc = Subtarget->hasVSX() ? PPC::XSCMPUDP : PPC::FCMPUD;
4277 assert(
LHS.getValueType() == MVT::f128 &&
"Unknown vt!");
4278 assert(Subtarget->hasP9Vector() &&
"XSCMPUQP requires Power9 Vector");
4279 Opc = PPC::XSCMPUQP;
4347 case ISD::SETO: Invert =
true;
return 3;
4364 bool HasVSX,
bool &Swap,
bool &Negate) {
4391 if (VecVT == MVT::v4f32)
4392 return HasVSX ? PPC::XVCMPEQSP : PPC::VCMPEQFP;
4393 else if (VecVT == MVT::v2f64)
4394 return PPC::XVCMPEQDP;
4398 if (VecVT == MVT::v4f32)
4399 return HasVSX ? PPC::XVCMPGTSP : PPC::VCMPGTFP;
4400 else if (VecVT == MVT::v2f64)
4401 return PPC::XVCMPGTDP;
4405 if (VecVT == MVT::v4f32)
4406 return HasVSX ? PPC::XVCMPGESP : PPC::VCMPGEFP;
4407 else if (VecVT == MVT::v2f64)
4408 return PPC::XVCMPGEDP;
4435 if (VecVT == MVT::v16i8)
4436 return PPC::VCMPEQUB;
4437 else if (VecVT == MVT::v8i16)
4438 return PPC::VCMPEQUH;
4439 else if (VecVT == MVT::v4i32)
4440 return PPC::VCMPEQUW;
4441 else if (VecVT == MVT::v2i64)
4442 return PPC::VCMPEQUD;
4443 else if (VecVT == MVT::v1i128)
4444 return PPC::VCMPEQUQ;
4447 if (VecVT == MVT::v16i8)
4448 return PPC::VCMPGTSB;
4449 else if (VecVT == MVT::v8i16)
4450 return PPC::VCMPGTSH;
4451 else if (VecVT == MVT::v4i32)
4452 return PPC::VCMPGTSW;
4453 else if (VecVT == MVT::v2i64)
4454 return PPC::VCMPGTSD;
4455 else if (VecVT == MVT::v1i128)
4456 return PPC::VCMPGTSQ;
4459 if (VecVT == MVT::v16i8)
4460 return PPC::VCMPGTUB;
4461 else if (VecVT == MVT::v8i16)
4462 return PPC::VCMPGTUH;
4463 else if (VecVT == MVT::v4i32)
4464 return PPC::VCMPGTUW;
4465 else if (VecVT == MVT::v2i64)
4466 return PPC::VCMPGTUD;
4467 else if (VecVT == MVT::v1i128)
4468 return PPC::VCMPGTUQ;
4477bool PPCDAGToDAGISel::trySETCC(SDNode *
N) {
4480 bool IsStrict =
N->isStrictFPOpcode();
4485 bool isPPC64 = (PtrVT == MVT::i64);
4501 SDValue Ops[] = {
Op, getI32Imm(27, dl), getI32Imm(5, dl),
4502 getI32Imm(31, dl) };
4510 Op, getI32Imm(~0U, dl)), 0);
4515 SDValue Ops[] = {
Op, getI32Imm(1, dl), getI32Imm(31, dl),
4516 getI32Imm(31, dl) };
4524 SDValue Ops[] = {
T, getI32Imm(1, dl), getI32Imm(31, dl),
4525 getI32Imm(31, dl) };
4530 }
else if (Imm == ~0U) {
4537 Op, getI32Imm(1, dl)), 0);
4542 0),
Op.getValue(1));
4547 SDNode *AD = CurDAG->
getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Glue,
4548 Op, getI32Imm(~0U, dl));
4555 getI32Imm(1, dl)), 0);
4558 SDValue Ops[] = { AN, getI32Imm(1, dl), getI32Imm(31, dl),
4559 getI32Imm(31, dl) };
4564 SDValue Ops[] = {
Op, getI32Imm(1, dl), getI32Imm(31, dl),
4565 getI32Imm(31, dl) };
4576 if (!IsStrict &&
LHS.getValueType().isVector()) {
4577 if (Subtarget->hasSPE())
4580 EVT VecVT =
LHS.getValueType();
4596 unsigned int VCmpInst =
4604 CurDAG->
SelectNodeTo(
N, Subtarget->hasVSX() ? PPC::XXLNOR : PPC::VNOR,
4613 if (Subtarget->useCRBits())
4625 if (Subtarget->hasSPE() &&
LHS.getValueType().isFloatingPoint()) {
4639 SDValue Ops[] = { IntCR, getI32Imm((32 - (3 - Idx)) & 31, dl),
4640 getI32Imm(31, dl), getI32Imm(31, dl) };
4649 CurDAG->
SelectNodeTo(
N, PPC::XORI, MVT::i32, Tmp, getI32Imm(1, dl));
4655bool PPCDAGToDAGISel::isOffsetMultipleOf(SDNode *
N,
unsigned Val)
const {
4660 if (LDN || (MIN &&
MIN->getOpcode() == PPCISD::LD_SPLAT))
4676 if ((SlotAlign % Val) != 0)
4691void PPCDAGToDAGISel::transferMemOperands(SDNode *
N, SDNode *Result) {
4698 bool &NeedSwapOps,
bool &IsUnCmp) {
4704 SDValue TrueRes =
N->getOperand(2);
4705 SDValue FalseRes =
N->getOperand(3);
4707 if (!TrueConst || (
N->getSimpleValueType(0) != MVT::i64 &&
4708 N->getSimpleValueType(0) != MVT::i32))
4717 if ((TrueResVal < -1 || TrueResVal > 1) ||
4754 if (!SelCCTrueConst || !SelCCFalseConst)
4759 if (SelCCTVal == -1 && SelCCFVal == 1) {
4761 }
else if (SelCCTVal != 1 || SelCCFVal != -1)
4771 bool InnerSwapped =
false;
4772 if (
LHS == InnerRHS &&
RHS == InnerLHS)
4773 InnerSwapped =
true;
4774 else if (
LHS != InnerLHS ||
RHS != InnerRHS)
4785 NeedSwapOps = (InnerCC ==
ISD::SETGT) ? InnerSwapped : !InnerSwapped;
4802 NeedSwapOps = (TrueResVal == 1);
4821 NeedSwapOps = (TrueResVal == -1);
4830 LLVM_DEBUG(
dbgs() <<
"Found a node that can be lowered to a SETB: ");
4838 if (
N.getOpcode() == PPCISD::FTSQRT)
4843 switch (
N.getConstantOperandVal(0)) {
4844 case Intrinsic::ppc_vsx_xvtdivdp:
4845 case Intrinsic::ppc_vsx_xvtdivsp:
4846 case Intrinsic::ppc_vsx_xvtsqrtdp:
4847 case Intrinsic::ppc_vsx_xvtsqrtsp:
4853bool PPCDAGToDAGISel::tryFoldSWTestBRCC(SDNode *
N) {
4911bool PPCDAGToDAGISel::trySelectLoopCountIntrinsic(SDNode *
N) {
4923 LHS.getOperand(0).getConstantOperandVal(1) != Intrinsic::loop_decrement)
4930 "Counter decrement comparison is not EQ or NE");
4933 assert(OldDecrement.
hasOneUse() &&
"loop decrement has more than one use!");
4935 SDLoc DecrementLoc(OldDecrement);
4937 SDValue DecrementOps[] = {Subtarget->isPPC64() ? getI64Imm(1, DecrementLoc)
4938 : getI32Imm(1, DecrementLoc)};
4939 unsigned DecrementOpcode =
4940 Subtarget->isPPC64() ? PPC::DecreaseCTR8loop : PPC::DecreaseCTRloop;
4941 SDNode *NewDecrement = CurDAG->
getMachineNode(DecrementOpcode, DecrementLoc,
4942 MVT::i1, DecrementOps);
4944 unsigned Val =
RHS->getAsZExtVal();
4946 unsigned Opcode = IsBranchOnTrue ? PPC::BC : PPC::BCn;
4948 ReplaceUses(
LHS.getValue(0),
LHS.getOperand(1));
4952 ReplaceUses(OldDecrement.
getValue(1), ChainInput);
4956 ChainInput,
N->getOperand(0));
4959 N->getOperand(4), Chain);
4963bool PPCDAGToDAGISel::tryAsSingleRLWINM(SDNode *
N) {
4971 unsigned SH, MB, ME;
4974 if (isRotateAndMask(Val.
getNode(), Imm,
false, SH, MB, ME)) {
4976 SDValue Ops[] = {Val, getI32Imm(SH, dl), getI32Imm(MB, dl),
4987 unsigned AlreadyCleared = 0;
4990 if (IntrinsicID == Intrinsic::ppc_lbarx)
4991 AlreadyCleared = 24;
4992 else if (IntrinsicID == Intrinsic::ppc_lharx)
4993 AlreadyCleared = 16;
4994 if (AlreadyCleared != 0 && AlreadyCleared == MB && ME == 31) {
4995 ReplaceUses(
SDValue(
N, 0),
N->getOperand(0));
5000 SDValue Ops[] = {Val, getI32Imm(0, dl), getI32Imm(MB, dl),
5008 ReplaceUses(
SDValue(
N, 0),
N->getOperand(1));
5015bool PPCDAGToDAGISel::tryAsSingleRLWINM8(SDNode *
N) {
5032 SDValue Ops[] = {
N->getOperand(0), getI64Imm(0, dl), getI64Imm(MB - 32, dl),
5033 getI64Imm(ME - 32, dl)};
5041bool PPCDAGToDAGISel::tryAsPairOfRLDICL(SDNode *
N) {
5061 if (NumOfLeadingZeros != 0)
5074 unsigned OnesOnLeft = ME + 1;
5075 unsigned ZerosInBetween = (MB - ME + 63) & 63;
5079 getI64Imm(OnesOnLeft, Loc),
5080 getI64Imm(ZerosInBetween, Loc)),
5089 SDValue Ops[] = {Val, getI64Imm(64 - OnesOnLeft, Loc),
5090 getI64Imm(NumOfLeadingZeros, Loc)};
5095bool PPCDAGToDAGISel::tryAsSingleRLWIMI(SDNode *
N) {
5122 if (
isRunOfOnes(~(Imm ^ Imm2), MB, ME) && !(~Imm & Imm2)) {
5125 getI32Imm(MB, dl), getI32Imm(ME, dl)};
5133bool PPCDAGToDAGISel::tryAsSingleRLDCL(SDNode *
N) {
5162bool PPCDAGToDAGISel::tryAsSingleRLDICL(SDNode *
N) {
5181 auto ImDef = CurDAG->
getMachineNode(PPC::IMPLICIT_DEF, dl, ResultType);
5199 assert(Imm < 64 &&
"Illegal shift amount");
5204 SDValue Ops[] = {Val, getI32Imm(SH, dl), getI32Imm(MB, dl)};
5209bool PPCDAGToDAGISel::tryAsSingleRLDICR(SDNode *
N) {
5222 SDValue Ops[] = {
N->getOperand(0), getI32Imm(SH, dl), getI32Imm(MB, dl)};
5227bool PPCDAGToDAGISel::tryAsSingleRLDIMI(SDNode *
N) {
5241 unsigned SH = 63 - ME;
5247 getI32Imm(SH, Dl), getI32Imm(MB, Dl)};
5254void PPCDAGToDAGISel::Select(SDNode *
N) {
5256 if (
N->isMachineOpcode()) {
5269 if (tryBitPermutation(
N))
5273 if (tryIntCompareInGPR(
N))
5276 switch (
N->getOpcode()) {
5280 if (
N->getValueType(0) == MVT::i64) {
5287 auto IntrinsicID =
N->getConstantOperandVal(1);
5288 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
5289 IntrinsicID != Intrinsic::ppc_trapd &&
5290 IntrinsicID != Intrinsic::ppc_trap)
5292 unsigned Opcode = (IntrinsicID == Intrinsic::ppc_tdw ||
5293 IntrinsicID == Intrinsic::ppc_trapd)
5298 if (IntrinsicID == Intrinsic::ppc_tdw ||
5299 IntrinsicID == Intrinsic::ppc_tw) {
5300 SDValue Ops[] = {
N->getOperand(4),
N->getOperand(2),
N->getOperand(3)};
5301 int16_t SImmOperand2;
5302 int16_t SImmOperand3;
5303 int16_t SImmOperand4;
5304 bool isOperand2IntS16Immediate =
5306 bool isOperand3IntS16Immediate =
5311 if (isOperand2IntS16Immediate == isOperand3IntS16Immediate)
5312 Opcode = IntrinsicID == Intrinsic::ppc_tdw ? PPC::TD : PPC::TW;
5313 else if (isOperand3IntS16Immediate)
5315 Ops[2] = getI32Imm(
int(SImmOperand3) & 0xFFFF, dl);
5318 bool isOperand4IntS16Immediate =
5320 (void)isOperand4IntS16Immediate;
5321 assert(isOperand4IntS16Immediate &&
5322 "The 4th operand is not an Immediate");
5324 int16_t TO = int(SImmOperand4) & 0x1F;
5326 if ((TO & 0x1) != ((TO & 0x2) >> 1))
5327 TO = (TO & 0x1) ? TO + 1 : TO - 1;
5329 if ((TO & 0x8) != ((TO & 0x10) >> 1))
5330 TO = (TO & 0x8) ? TO + 8 : TO - 8;
5331 Ops[0] = getI32Imm(TO, dl);
5332 Ops[1] =
N->getOperand(3);
5333 Ops[2] = getI32Imm(
int(SImmOperand2) & 0xFFFF, dl);
5338 OpsWithMD = {getI32Imm(24, dl),
N->getOperand(2), getI32Imm(0, dl)};
5342 if (
N->getNumOperands() > MDIndex) {
5343 SDValue MDV =
N->getOperand(MDIndex);
5348 "ppc-trap-reason") &&
5349 "Unsupported annotation data type!");
5352 "Invalid data type for annotation ppc-trap-reason!");
5355 MD->
getOperand(i))->getString().str()), dl));
5370 auto IntID =
N->getConstantOperandVal(0);
5371 if (IntID == Intrinsic::ppc_fsels) {
5372 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(2),
N->getOperand(3)};
5377 if (IntID == Intrinsic::ppc_bcdadd_p || IntID == Intrinsic::ppc_bcdsub_p) {
5378 auto Pred =
N->getConstantOperandVal(1);
5380 IntID == Intrinsic::ppc_bcdadd_p ? PPC::BCDADD_rec : PPC::BCDSUB_rec;
5381 unsigned SubReg = 0;
5382 unsigned ShiftVal = 0;
5386 SubReg = PPC::sub_eq;
5390 SubReg = PPC::sub_eq;
5395 SubReg = PPC::sub_lt;
5399 SubReg = PPC::sub_lt;
5404 SubReg = PPC::sub_gt;
5408 SubReg = PPC::sub_gt;
5413 SubReg = PPC::sub_un;
5416 SubReg = PPC::sub_un;
5421 EVT VTs[] = {MVT::v16i8, MVT::Glue};
5428 if (Subtarget->isISA3_1()) {
5431 CurDAG->
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
5432 CR6Reg, SubRegIdx, BCDOp.
getValue(1)),
5441 SDValue Ops[] = {Move, getI32Imm((32 - (4 + ShiftVal)) & 31, dl),
5442 getI32Imm(31, dl), getI32Imm(31, dl)};
5448 CurDAG->
SelectNodeTo(
N, PPC::XORI, MVT::i32, Shift, getI32Imm(1, dl));
5454 if (!Subtarget->isISA3_1())
5456 unsigned Opcode = 0;
5460 case Intrinsic::ppc_altivec_vstribr_p:
5461 Opcode = PPC::VSTRIBR_rec;
5463 case Intrinsic::ppc_altivec_vstribl_p:
5464 Opcode = PPC::VSTRIBL_rec;
5466 case Intrinsic::ppc_altivec_vstrihr_p:
5467 Opcode = PPC::VSTRIHR_rec;
5469 case Intrinsic::ppc_altivec_vstrihl_p:
5470 Opcode = PPC::VSTRIHL_rec;
5477 EVT VTs[] = {MVT::v16i8, MVT::Glue};
5485 CurDAG->
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
5486 CR6Reg, SubRegIdx, VecStrOp.
getValue(1)),
5500 case PPCISD::ADDI_TLSLD_L_ADDR:
5501 case PPCISD::ADDI_TLSGD_L_ADDR: {
5503 if (PPCLowering->getPointerTy(CurDAG->
getDataLayout()) != MVT::i32 ||
5504 !Subtarget->isSecurePlt() || !Subtarget->
isTargetELF() ||
5512 case PPCISD::CALL_RM: {
5514 !Subtarget->isSecurePlt() || !Subtarget->
isTargetELF())
5530 ReplaceNode(
N, getGlobalBaseReg());
5534 selectFrameIndex(
N,
N);
5540 N->getOperand(0), InGlue));
5545 ReplaceNode(
N, CurDAG->
getMachineNode(PPC::ReadTB, dl, MVT::i32, MVT::i32,
5546 MVT::Other,
N->getOperand(0)));
5553 getConstantIntValue(), dl,
5554 N->getValueType(0));
5555 if (
N->getValueType(0) == MVT::i64) {
5563 assert(
N->getValueType(0) == MVT::i32 &&
5564 "Expecting i64 or i32 in PPCISD::SRA_ADDZE");
5580 if (tryTLSXFormStore(ST))
5587 EVT LoadedVT =
LD->getMemoryVT();
5594 if (tryTLSXFormLoad(LD))
5605 if (
LD->getValueType(0) != MVT::i64) {
5607 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5610 case MVT::f64: Opcode = PPC::LFDU;
break;
5611 case MVT::f32: Opcode = PPC::LFSU;
break;
5612 case MVT::i32: Opcode = PPC::LWZU;
break;
5613 case MVT::i16: Opcode = isSExt ? PPC::LHAU : PPC::LHZU;
break;
5615 case MVT::i8: Opcode = PPC::LBZU;
break;
5618 assert(
LD->getValueType(0) == MVT::i64 &&
"Unknown load result type!");
5619 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5622 case MVT::i64: Opcode = PPC::LDU;
break;
5623 case MVT::i32: Opcode = PPC::LWZU8;
break;
5624 case MVT::i16: Opcode = isSExt ? PPC::LHAU8 : PPC::LHZU8;
break;
5626 case MVT::i8: Opcode = PPC::LBZU8;
break;
5634 Opcode, dl,
LD->getValueType(0),
5636 transferMemOperands(
N, MN);
5642 if (
LD->getValueType(0) != MVT::i64) {
5644 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5647 case MVT::f64: Opcode = PPC::LFDUX;
break;
5648 case MVT::f32: Opcode = PPC::LFSUX;
break;
5649 case MVT::i32: Opcode = PPC::LWZUX;
break;
5650 case MVT::i16: Opcode = isSExt ? PPC::LHAUX : PPC::LHZUX;
break;
5652 case MVT::i8: Opcode = PPC::LBZUX;
break;
5655 assert(
LD->getValueType(0) == MVT::i64 &&
"Unknown load result type!");
5656 assert((!isSExt || LoadedVT == MVT::i16 || LoadedVT == MVT::i32) &&
5657 "Invalid sext update load");
5660 case MVT::i64: Opcode = PPC::LDUX;
break;
5661 case MVT::i32: Opcode = isSExt ? PPC::LWAUX : PPC::LWZUX8;
break;
5662 case MVT::i16: Opcode = isSExt ? PPC::LHAUX8 : PPC::LHZUX8;
break;
5664 case MVT::i8: Opcode = PPC::LBZUX8;
break;
5672 Opcode, dl,
LD->getValueType(0),
5674 transferMemOperands(
N, MN);
5682 if (tryAsSingleRLWINM(
N) || tryAsSingleRLWIMI(
N) || tryAsSingleRLDCL(
N) ||
5683 tryAsSingleRLDICL(
N) || tryAsSingleRLDICR(
N) || tryAsSingleRLWINM8(
N) ||
5684 tryAsPairOfRLDICL(
N))
5690 if (
N->getValueType(0) == MVT::i32)
5691 if (tryBitfieldInsert(
N))
5702 selectFrameIndex(
N,
N->getOperand(0).getNode(), (int64_t)Imm);
5709 if (tryAsSingleRLDIMI(
N))
5715 bool IsPPC64 = Subtarget->isPPC64();
5717 (Imm64 & ~0xFFFFFFFFuLL) == 0) {
5719 uint64_t ImmHi =
Imm64 >> 16;
5720 uint64_t ImmLo =
Imm64 & 0xFFFF;
5721 if (ImmHi != 0 && ImmLo != 0) {
5724 getI16Imm(ImmLo, dl));
5738 bool IsPPC64 = Subtarget->isPPC64();
5740 (Imm64 & ~0xFFFFFFFFuLL) == 0) {
5742 uint64_t ImmHi =
Imm64 >> 16;
5743 uint64_t ImmLo =
Imm64 & 0xFFFF;
5744 if (ImmHi != 0 && ImmLo != 0) {
5747 getI16Imm(ImmLo, dl));
5760 selectFrameIndex(
N,
N->getOperand(0).getNode(), (int64_t)Imm);
5767 unsigned Imm, SH, MB, ME;
5769 isRotateAndMask(
N, Imm,
true, SH, MB, ME)) {
5771 getI32Imm(SH, dl), getI32Imm(MB, dl),
5772 getI32Imm(ME, dl) };
5781 unsigned Imm, SH, MB, ME;
5783 isRotateAndMask(
N, Imm,
true, SH, MB, ME)) {
5785 getI32Imm(SH, dl), getI32Imm(MB, dl),
5786 getI32Imm(ME, dl) };
5809 uint64_t ImmSh =
Imm >> Shift;
5816 SDNode *MulNode = CurDAG->
getMachineNode(PPC::MULLI8, dl, MVT::i64,
5817 N->getOperand(0), SDImm);
5820 getI32Imm(63 - Shift, dl)};
5825 SDNode *MulNode = CurDAG->
getMachineNode(PPC::MULLI, dl, MVT::i32,
5826 N->getOperand(0), SDImm);
5829 getI32Imm(0, dl), getI32Imm(31 - Shift, dl)};
5841 EVT InVT =
N->getOperand(0).getValueType();
5842 assert((InVT == MVT::i64 || InVT == MVT::i32) &&
5843 "Invalid input type for ANDI_rec_1_EQ_BIT");
5845 unsigned Opcode = (InVT == MVT::i64) ? PPC::ANDI8_rec : PPC::ANDI_rec;
5855 CurDAG->
SelectNodeTo(
N, TargetOpcode::EXTRACT_SUBREG, MVT::i1, CR0Reg,
5856 SRIdxVal,
SDValue(AndI.getNode(), 1) );
5863 bool isPPC64 = (PtrVT == MVT::i64);
5866 if (Subtarget->useCRBits() &&
N->getOperand(0).getValueType() == MVT::i1)
5869 if (Subtarget->isISA3_0() && Subtarget->isPPC64()) {
5870 bool NeedSwapOps =
false;
5871 bool IsUnCmp =
false;
5887 N,
N->getSimpleValueType(0) == MVT::i64 ? PPC::SETB8 : PPC::SETB,
5888 N->getValueType(0), GenCC);
5899 N->getValueType(0) == MVT::i32) {
5902 N->getOperand(0), getI32Imm(~0U, dl));
5904 N->getOperand(0),
SDValue(Tmp, 1));
5908 SDValue CCReg = SelectCC(
N->getOperand(0),
N->getOperand(1), CC, dl);
5910 if (
N->getValueType(0) == MVT::i1) {
5918 case 0: SRI = PPC::sub_lt;
break;
5919 case 1: SRI = PPC::sub_gt;
break;
5920 case 2: SRI = PPC::sub_eq;
break;
5921 case 3: SRI = PPC::sub_un;
break;
5928 SDValue C = Inv ? NotCCBit : CCBit,
5929 NotC = Inv ? CCBit : NotCCBit;
5932 C,
N->getOperand(2)), 0);
5934 NotC,
N->getOperand(3)), 0);
5936 CurDAG->
SelectNodeTo(
N, PPC::CROR, MVT::i1, CAndT, NotCAndF);
5943 unsigned SelectCCOp;
5944 if (
N->getValueType(0) == MVT::i32)
5945 SelectCCOp = PPC::SELECT_CC_I4;
5946 else if (
N->getValueType(0) == MVT::i64)
5947 SelectCCOp = PPC::SELECT_CC_I8;
5948 else if (
N->getValueType(0) == MVT::f32) {
5949 if (Subtarget->hasP8Vector())
5950 SelectCCOp = PPC::SELECT_CC_VSSRC;
5951 else if (Subtarget->hasSPE())
5952 SelectCCOp = PPC::SELECT_CC_SPE4;
5954 SelectCCOp = PPC::SELECT_CC_F4;
5955 }
else if (
N->getValueType(0) == MVT::f64) {
5956 if (Subtarget->hasVSX())
5957 SelectCCOp = PPC::SELECT_CC_VSFRC;
5958 else if (Subtarget->hasSPE())
5959 SelectCCOp = PPC::SELECT_CC_SPE;
5961 SelectCCOp = PPC::SELECT_CC_F8;
5962 }
else if (
N->getValueType(0) == MVT::f128)
5963 SelectCCOp = PPC::SELECT_CC_F16;
5964 else if (Subtarget->hasSPE())
5965 SelectCCOp = PPC::SELECT_CC_SPE;
5966 else if (
N->getValueType(0) == MVT::v2f64 ||
5967 N->getValueType(0) == MVT::v2i64)
5968 SelectCCOp = PPC::SELECT_CC_VSRC;
5970 SelectCCOp = PPC::SELECT_CC_VRRC;
5973 getI32Imm(BROpc, dl) };
5978 if (Subtarget->hasVSX() && (
N->getValueType(0) == MVT::v2f64 ||
5979 N->getValueType(0) == MVT::v2i64)) {
5986 for (
int i = 0; i < 2; ++i)
5992 if (Op1 == Op2 &&
DM[0] == 0 &&
DM[1] == 0 &&
5998 if (
LD->isUnindexed() &&
LD->hasOneUse() && Op1.
hasOneUse() &&
5999 (
LD->getMemoryVT() == MVT::f64 ||
6000 LD->getMemoryVT() == MVT::i64) &&
6004 MachineMemOperand *MemOp =
LD->getMemOperand();
6006 N->getValueType(0),
Ops);
6016 unsigned tmp =
DM[0];
6031 bool IsPPC64 = Subtarget->isPPC64();
6032 SDValue Ops[] = {
N->getOperand(1),
N->getOperand(0) };
6034 ? (IsPPC64 ? PPC::BDNZ8 : PPC::BDNZ)
6035 : (IsPPC64 ? PPC::BDZ8 : PPC::BDZ),
6039 case PPCISD::COND_BRANCH: {
6046 unsigned PCC =
N->getConstantOperandVal(1);
6050 SDValue Pred = getI32Imm(PCC, dl);
6057 if (tryFoldSWTestBRCC(
N))
6059 if (trySelectLoopCountIntrinsic(
N))
6065 if (
N->getOperand(2).getValueType() == MVT::i1) {
6088 N->getOperand(Swap ? 3 : 2),
6089 N->getOperand(Swap ? 2 : 3)), 0);
6090 CurDAG->
SelectNodeTo(
N, PPC::BC, MVT::Other, BitComp,
N->getOperand(4),
6100 N->getOperand(4),
N->getOperand(0) };
6108 unsigned Opc =
Target.getValueType() == MVT::i32 ? PPC::MTCTR : PPC::MTCTR8;
6109 unsigned Reg =
Target.getValueType() == MVT::i32 ? PPC::BCTR : PPC::BCTR8;
6115 case PPCISD::TOC_ENTRY: {
6116 const bool isPPC64 = Subtarget->isPPC64();
6117 const bool isELFABI = Subtarget->
isSVR4ABI();
6118 const bool isAIXABI = Subtarget->
isAIXABI();
6124 "PowerPC doesn't support tiny or kernel code models.");
6135 auto replaceWith = [
this, &dl](
unsigned OpCode, SDNode *TocEntry,
6137 SDValue GA = TocEntry->getOperand(0);
6138 SDValue TocBase = TocEntry->getOperand(1);
6139 SDNode *MN =
nullptr;
6140 if (OpCode == PPC::ADDItoc || OpCode == PPC::ADDItoc8)
6146 transferMemOperands(TocEntry, MN);
6148 ReplaceNode(TocEntry, MN);
6157 "32-bit ELF can only have TOC entries in position independent"
6160 replaceWith(PPC::LWZtoc,
N, MVT::i32);
6164 assert(isAIXABI &&
"ELF ABI already handled");
6167 replaceWith(PPC::ADDItoc,
N, MVT::i32);
6171 replaceWith(PPC::LWZtoc,
N, MVT::i32);
6176 assert(isAIXABI &&
"ELF ABI handled in common SelectCode");
6179 replaceWith(PPC::ADDItoc8,
N, MVT::i64);
6189 assert((isPPC64 || (isAIXABI && !isPPC64)) &&
"We are dealing with 64-bit"
6190 " ELF/AIX or 32-bit AIX in the following.");
6215 isPPC64 ? PPC::ADDIStocHA8 : PPC::ADDIStocHA, dl, VT, TOCbase, GA);
6222 dl, VT,
SDValue(Tmp, 0), GA));
6226 if (PPCLowering->isAccessedAsGotIndirect(GA)) {
6230 isPPC64 ? PPC::LDtocL : PPC::LWZtocL, dl, VT, GA,
SDValue(Tmp, 0));
6232 transferMemOperands(
N, MN);
6237 assert(isPPC64 &&
"TOC_ENTRY already handled for 32-bit.");
6246 "PPCISD::PPC32_PICGOT is only supported for 32-bit SVR4");
6257 "Invalid operand on VADD_SPLAT!");
6259 int Elt =
N->getConstantOperandVal(0);
6260 int EltSize =
N->getConstantOperandVal(1);
6261 unsigned Opc1, Opc2, Opc3;
6265 Opc1 = PPC::VSPLTISB;
6266 Opc2 = PPC::VADDUBM;
6267 Opc3 = PPC::VSUBUBM;
6269 }
else if (EltSize == 2) {
6270 Opc1 = PPC::VSPLTISH;
6271 Opc2 = PPC::VADDUHM;
6272 Opc3 = PPC::VSUBUHM;
6275 assert(EltSize == 4 &&
"Invalid element size on VADD_SPLAT!");
6276 Opc1 = PPC::VSPLTISW;
6277 Opc2 = PPC::VADDUWM;
6278 Opc3 = PPC::VSUBUWM;
6282 if ((Elt & 1) == 0) {
6289 SDValue EltVal = getI32Imm(Elt >> 1, dl);
6294 }
else if (Elt > 0) {
6301 SDValue EltVal = getI32Imm(Elt - 16, dl);
6303 EltVal = getI32Imm(-16, dl);
6315 SDValue EltVal = getI32Imm(Elt + 16, dl);
6317 EltVal = getI32Imm(-16, dl);
6324 case PPCISD::LD_SPLAT: {
6328 if (!Subtarget->hasAltivec() || Subtarget->hasDirectMove())
6331 EVT
Type =
N->getValueType(0);
6332 if (
Type != MVT::v16i8 &&
Type != MVT::v8i16)
6341 isOffsetMultipleOf(
N, 16))
6345 CurDAG->
getRegister(Subtarget->isPPC64() ? PPC::ZERO8 : PPC::ZERO,
6347 unsigned LIOpcode = Subtarget->isPPC64() ? PPC::LI8 : PPC::LI;
6362 unsigned SplatOp = (
Type == MVT::v16i8) ? PPC::VSPLTB : PPC::VSPLTH;
6363 unsigned SplatElemIndex =
6374 SDNode *LoadHigh = LoadLow;
6375 if (
Type == MVT::v8i16) {
6377 PPC::LVX, dl, MVT::v16i8, MVT::Other,
6379 LIOpcode, dl, MVT::i32,
6382 N->getOperand(1),
SDValue(LoadLow, 1)});
6386 transferMemOperands(
N, LoadHigh);
6407SDValue PPCDAGToDAGISel::combineToCMPB(SDNode *
N) {
6411 "Only OR nodes are supported for CMPB");
6414 if (!Subtarget->hasCMPB())
6417 if (
N->getValueType(0) != MVT::i32 &&
6418 N->getValueType(0) != MVT::i64)
6421 EVT VT =
N->getValueType(0);
6424 bool BytesFound[8] = {
false,
false,
false,
false,
false,
false,
false,
false};
6425 uint64_t
Mask = 0, Alt = 0;
6427 auto IsByteSelectCC = [
this](
SDValue O,
unsigned &
b,
6428 uint64_t &
Mask, uint64_t &Alt,
6438 uint64_t PM =
O.getConstantOperandVal(2);
6439 uint64_t PAlt =
O.getConstantOperandVal(3);
6440 for (b = 0;
b < 8; ++
b) {
6441 uint64_t
Mask = UINT64_C(0xFF) << (8*
b);
6442 if (PM && (PM & Mask) == PM && (PAlt & Mask) == PAlt)
6452 O.getConstantOperandVal(1) != 0) {
6453 SDValue Op0 =
O.getOperand(0), Op1 =
O.getOperand(1);
6485 uint64_t ULim =
O.getConstantOperandVal(1);
6486 if (ULim != (UINT64_C(1) << b*8))
6511 if (
Op.getConstantOperandVal(1) != (UINT64_C(0xFF) << (8*b)))
6526 unsigned Bits =
Op.getValueSizeInBits();
6529 if (
Op.getConstantOperandVal(1) != Bits-8)
6547 while (!
Queue.empty()) {
6550 for (
const SDValue &O :
V.getNode()->ops()) {
6552 uint64_t
M = 0,
A = 0;
6556 }
else if (IsByteSelectCC(O, b, M,
A, OLHS, ORHS)) {
6560 BytesFound[
b] =
true;
6563 }
else if ((
LHS == ORHS &&
RHS == OLHS) ||
6564 (
RHS == ORHS &&
LHS == OLHS)) {
6565 BytesFound[
b] =
true;
6577 unsigned LastB = 0, BCnt = 0;
6578 for (
unsigned i = 0; i < 8; ++i)
6579 if (BytesFound[LastB]) {
6584 if (!LastB || BCnt < 2)
6589 if (
LHS.getValueType() != VT) {
6596 bool NonTrivialMask = ((int64_t)
Mask) != INT64_C(-1);
6597 if (NonTrivialMask && !Alt) {
6624void PPCDAGToDAGISel::foldBoolExts(
SDValue &Res, SDNode *&
N) {
6625 if (!Subtarget->useCRBits())
6633 if (
N->getOperand(0).getValueType() != MVT::i1)
6636 if (!
N->hasOneUse())
6640 EVT VT =
N->getValueType(0);
6647 SDNode *
User = *
N->user_begin();
6648 if (
User->getNumOperands() != 2)
6657 User->getValueType(0), {O0, O1});
6662 SDValue TrueRes = TryFold(ConstTrue);
6663 if (!TrueRes || TrueRes.
isUndef())
6665 SDValue FalseRes = TryFold(ConstFalse);
6666 if (!FalseRes || FalseRes.
isUndef())
6679 ConstTrue = TrueRes;
6680 ConstFalse = FalseRes;
6681 }
while (
N->hasOneUse());
6684void PPCDAGToDAGISel::PreprocessISelDAG() {
6687 bool MadeChange =
false;
6689 SDNode *
N = &*--Position;
6694 switch (
N->getOpcode()) {
6697 Res = combineToCMPB(
N);
6702 foldBoolExts(Res,
N);
6722void PPCDAGToDAGISel::PostprocessISelDAG() {
6729 PeepholePPC64ZExt();
6737bool PPCDAGToDAGISel::AllUsersSelectZero(SDNode *
N) {
6738 for (
const SDNode *User :
N->users()) {
6739 if (!
User->isMachineOpcode())
6741 if (
User->getMachineOpcode() != PPC::SELECT_I4 &&
6742 User->getMachineOpcode() != PPC::SELECT_I8)
6745 SDNode *Op1 =
User->getOperand(1).getNode();
6746 SDNode *Op2 =
User->getOperand(2).getNode();
6766void PPCDAGToDAGISel::SwapAllSelectUsers(SDNode *
N) {
6768 for (SDNode *User :
N->users()) {
6769 assert((
User->getMachineOpcode() == PPC::SELECT_I4 ||
6770 User->getMachineOpcode() == PPC::SELECT_I8) &&
6771 "Must have all select users");
6775 for (SDNode *User : ToReplace) {
6778 User->getValueType(0),
User->getOperand(0),
6779 User->getOperand(2),
6780 User->getOperand(1));
6788 ReplaceUses(User, ResNode);
6792void PPCDAGToDAGISel::PeepholeCROps() {
6796 for (SDNode &Node : CurDAG->
allnodes()) {
6798 if (!MachineNode || MachineNode->
use_empty())
6800 SDNode *ResNode = MachineNode;
6802 bool Op1Set =
false, Op1Unset =
false,
6804 Op2Set =
false, Op2Unset =
false,
6819 if (
Op.isMachineOpcode()) {
6820 if (
Op.getMachineOpcode() == PPC::CRSET)
6822 else if (
Op.getMachineOpcode() == PPC::CRUNSET)
6824 else if ((
Op.getMachineOpcode() == PPC::CRNOR &&
6825 Op.getOperand(0) ==
Op.getOperand(1)) ||
6826 Op.getMachineOpcode() == PPC::CRNOT)
6833 case PPC::SELECT_I4:
6834 case PPC::SELECT_I8:
6835 case PPC::SELECT_F4:
6836 case PPC::SELECT_F8:
6837 case PPC::SELECT_SPE:
6838 case PPC::SELECT_SPE4:
6839 case PPC::SELECT_VRRC:
6840 case PPC::SELECT_VSFRC:
6841 case PPC::SELECT_VSSRC:
6842 case PPC::SELECT_VSRC: {
6844 if (
Op.isMachineOpcode()) {
6845 if (
Op.getMachineOpcode() == PPC::CRSET)
6847 else if (
Op.getMachineOpcode() == PPC::CRUNSET)
6849 else if ((
Op.getMachineOpcode() == PPC::CRNOR &&
6850 Op.getOperand(0) ==
Op.getOperand(1)) ||
6851 Op.getMachineOpcode() == PPC::CRNOT)
6858 bool SelectSwap =
false;
6871 else if (Op1Unset || Op2Unset)
6873 ResNode = CurDAG->
getMachineNode(PPC::CRUNSET, SDLoc(MachineNode),
6877 ResNode = CurDAG->
getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
6883 ResNode = CurDAG->
getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
6887 else if (AllUsersSelectZero(MachineNode)) {
6888 ResNode = CurDAG->
getMachineNode(PPC::CRNAND, SDLoc(MachineNode),
6910 else if (Op1Unset || Op2Unset)
6926 else if (AllUsersSelectZero(MachineNode)) {
6937 else if (Op1Set || Op2Set)
6959 else if (AllUsersSelectZero(MachineNode)) {
6969 ResNode = CurDAG->
getMachineNode(PPC::CRUNSET, SDLoc(MachineNode),
6999 else if (AllUsersSelectZero(MachineNode)) {
7007 if (Op1Set || Op2Set)
7009 ResNode = CurDAG->
getMachineNode(PPC::CRUNSET, SDLoc(MachineNode),
7023 ResNode = CurDAG->
getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
7029 ResNode = CurDAG->
getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
7033 else if (AllUsersSelectZero(MachineNode)) {
7073 else if (AllUsersSelectZero(MachineNode)) {
7083 ResNode = CurDAG->
getMachineNode(PPC::CRUNSET, SDLoc(MachineNode),
7090 else if (Op1Unset || Op2Set)
7092 ResNode = CurDAG->
getMachineNode(PPC::CRUNSET, SDLoc(MachineNode),
7109 else if (AllUsersSelectZero(MachineNode)) {
7121 else if (Op1Set || Op2Unset)
7135 ResNode = CurDAG->
getMachineNode(PPC::CRNAND, SDLoc(MachineNode),
7145 else if (AllUsersSelectZero(MachineNode)) {
7146 ResNode = CurDAG->
getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
7152 case PPC::SELECT_I4:
7153 case PPC::SELECT_I8:
7154 case PPC::SELECT_F4:
7155 case PPC::SELECT_F8:
7156 case PPC::SELECT_SPE:
7157 case PPC::SELECT_SPE4:
7158 case PPC::SELECT_VRRC:
7159 case PPC::SELECT_VSFRC:
7160 case PPC::SELECT_VSSRC:
7161 case PPC::SELECT_VSRC:
7193 SwapAllSelectUsers(MachineNode);
7195 if (ResNode != MachineNode) {
7202 ReplaceUses(MachineNode, ResNode);
7208 }
while (IsModified);
7319 if (!Op0OK && !Op1OK)
7342 if (!Op0OK && !Op1OK)
7356void PPCDAGToDAGISel::PeepholePPC64ZExt() {
7357 if (!Subtarget->isPPC64())
7371 bool MadeChange =
false;
7373 SDNode *
N = &*--Position;
7375 if (
N->use_empty() || !
N->isMachineOpcode())
7378 if (
N->getMachineOpcode() != PPC::RLDICL)
7381 if (
N->getConstantOperandVal(1) != 0 ||
7382 N->getConstantOperandVal(2) != 32)
7411 SmallPtrSet<SDNode *, 16> ToPromote;
7417 bool OutsideUse =
false;
7418 for (SDNode *PN : ToPromote) {
7419 for (SDNode *UN : PN->users()) {
7420 if (!ToPromote.count(UN) && UN != ISR.
getNode()) {
7438 for (SDNode *PN : ToPromote) {
7440 switch (PN->getMachineOpcode()) {
7443 case PPC::RLWINM: NewOpcode = PPC::RLWINM8;
break;
7444 case PPC::RLWNM: NewOpcode = PPC::RLWNM8;
break;
7445 case PPC::SLW: NewOpcode = PPC::SLW8;
break;
7446 case PPC::SRW: NewOpcode = PPC::SRW8;
break;
7447 case PPC::LI: NewOpcode = PPC::LI8;
break;
7448 case PPC::LIS: NewOpcode = PPC::LIS8;
break;
7449 case PPC::LHBRX: NewOpcode = PPC::LHBRX8;
break;
7450 case PPC::LWBRX: NewOpcode = PPC::LWBRX8;
break;
7451 case PPC::CNTLZW: NewOpcode = PPC::CNTLZW8;
break;
7452 case PPC::CNTTZW: NewOpcode = PPC::CNTTZW8;
break;
7453 case PPC::RLWIMI: NewOpcode = PPC::RLWIMI8;
break;
7454 case PPC::OR: NewOpcode = PPC::OR8;
break;
7455 case PPC::SELECT_I4: NewOpcode = PPC::SELECT_I8;
break;
7456 case PPC::ORI: NewOpcode = PPC::ORI8;
break;
7457 case PPC::ORIS: NewOpcode = PPC::ORIS8;
break;
7458 case PPC::AND: NewOpcode = PPC::AND8;
break;
7460 NewOpcode = PPC::ANDI8_rec;
7462 case PPC::ANDIS_rec:
7463 NewOpcode = PPC::ANDIS8_rec;
7473 for (
const SDValue &V : PN->ops()) {
7474 if (!ToPromote.count(
V.getNode()) &&
V.getValueType() == MVT::i32 &&
7491 SDVTList VTs = PN->getVTList();
7492 for (
unsigned i = 0, ie = VTs.
NumVTs; i != ie; ++i)
7493 if (VTs.
VTs[i] == MVT::i32)
7526 if (!
N->isMachineOpcode())
7528 unsigned Opc =
N->getMachineOpcode();
7532 if (
Opc == PPC::XXPERMDIs) {
7534 N->getConstantOperandVal(1) == 2;
7535 }
else if (
Opc == PPC::XXPERMDI ||
Opc == PPC::XXSLDWI) {
7536 return N->getOperand(0) ==
N->getOperand(1) &&
7538 N->getConstantOperandVal(2) == 2;
7546 if (!
N->isMachineOpcode())
7548 unsigned Opc =
N->getMachineOpcode();
7597 auto SkipRCCopy = [](
SDValue V) {
7598 while (V->isMachineOpcode() &&
7599 V->getMachineOpcode() == TargetOpcode::COPY_TO_REGCLASS) {
7601 if (V->use_empty() || !V->user_begin()->isOnlyUserOf(V.getNode()))
7603 V = V->getOperand(0);
7605 return V.hasOneUse() ? V :
SDValue();
7608 SDValue VecOp = SkipRCCopy(
N->getOperand(0));
7628 if (GV->hasAttribute(
"aix-small-tls"))
7649 if (!(Subtarget.hasAIXSmallLocalDynamicTLS() ||
7690 if (
N->getMachineOpcode() != PPC::ADDI8)
7695 SDValue InitialADDI =
N->getOperand(0);
7706 assert(GA &&
"Expecting a valid GlobalAddressSDNode when folding addi into "
7707 "local-[exec|dynamic] accesses!");
7715 int Offset =
N->getConstantOperandVal(1);
7724void PPCDAGToDAGISel::PeepholePPC64() {
7728 SDNode *
N = &*--Position;
7730 if (
N->use_empty() || !
N->isMachineOpcode())
7741 unsigned StorageOpcode =
N->getMachineOpcode();
7742 bool RequiresMod4Offset =
false;
7744 switch (StorageOpcode) {
7749 case PPC::DFLOADf64:
7750 case PPC::DFLOADf32:
7751 RequiresMod4Offset =
true;
7767 case PPC::DFSTOREf64:
7768 case PPC::DFSTOREf32:
7769 RequiresMod4Offset =
true;
7791 if (!
Base.isMachineOpcode())
7795 bool ReplaceFlags =
true;
7807 switch (
Base.getMachineOpcode()) {
7815 ReplaceFlags =
false;
7817 case PPC::ADDIdtprelL:
7820 case PPC::ADDItlsldL:
7823 case PPC::ADDItocL8:
7838 int MaxDisplacement = 7;
7840 const GlobalValue *GV = GA->getGlobal();
7842 MaxDisplacement = std::min((
int)Alignment.
value() - 1, MaxDisplacement);
7845 bool UpdateHBase =
false;
7848 int Offset =
N->getConstantOperandVal(FirstOp);
7854 if (
Base.getMachineOpcode() != PPC::ADDItocL8)
7865 if (HImmOpnd != ImmOpnd)
7873 if (RequiresMod4Offset) {
7874 if (GlobalAddressSDNode *GA =
7876 const GlobalValue *GV = GA->getGlobal();
7891 if (RequiresMod4Offset && (
Offset % 4) != 0)
7899 }
else if (
Offset != 0) {
7907 assert(GA &&
"Expecting a valid GlobalAddressSDNode when folding "
7908 "addi into local-[exec|dynamic] accesses!");
7921 LLVM_DEBUG(
dbgs() <<
"Folding add-immediate into mem-op:\nBase: ");
7932 const GlobalValue *GV = GA->getGlobal();
7936 if (Alignment < 4 && (RequiresMod4Offset || (
Offset % 4) != 0)) {
7937 LLVM_DEBUG(
dbgs() <<
"Rejected this candidate for alignment.\n\n");
7941 }
else if (ConstantPoolSDNode *CP =
7951 Base.getOperand(0),
N->getOperand(3));
7961 if (
Base.getNode()->use_empty())
7971 return new PPCDAGToDAGISelLegacy(TM, OptLevel);
static bool isOpcWithIntImmediate(const SDNode *N, unsigned Opc, uint64_t &Imm)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
AMDGPU Register Bank Select
This file implements a class to represent arbitrary precision integral constant values and operations...
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
static bool isInt32Immediate(SDNode *N, unsigned &Imm)
isInt32Immediate - This method tests to see if the node is a 32-bit constant operand.
MachineBasicBlock MachineBasicBlock::iterator MBBI
Function Alias Analysis false
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
const HexagonInstrInfo * TII
static MaybeAlign getAlign(Value *Ptr)
Module.h This file contains the declarations for the Module class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
Machine Check Debug Module
Register const TargetRegisterInfo * TRI
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
cl::opt< bool > ANDIGlueBug("expose-ppc-andi-glue-bug", cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden)
static cl::opt< bool > UseBitPermRewriter("ppc-use-bit-perm-rewriter", cl::init(true), cl::desc("use aggressive ppc isel for bit permutations"), cl::Hidden)
static bool isEligibleToFoldADDIForFasterLocalAccesses(SelectionDAG *DAG, SDValue ADDIToFold)
static bool canOptimizeTLSDFormToXForm(SelectionDAG *CurDAG, SDValue Base)
static cl::opt< bool > EnableBranchHint("ppc-use-branch-hint", cl::init(true), cl::desc("Enable static hinting of branches on ppc"), cl::Hidden)
static bool hasTocDataAttr(SDValue Val)
static void foldADDIForFasterLocalAccesses(SDNode *N, SelectionDAG *DAG)
static bool isThreadPointerAcquisitionNode(SDValue Base, SelectionDAG *CurDAG)
static bool PeepholePPC64ZExtGather(SDValue Op32, SmallPtrSetImpl< SDNode * > &ToPromote)
static bool isLaneInsensitive(SDValue N)
static unsigned allUsesTruncate(SelectionDAG *CurDAG, SDNode *N)
static CodeModel::Model getCodeModel(const PPCSubtarget &Subtarget, const TargetMachine &TM, const SDNode *Node)
static void reduceVSXSwap(SDNode *N, SelectionDAG *DAG)
static bool isOpcWithIntImmediate(SDNode *N, unsigned Opc, unsigned &Imm)
static PPC::Predicate getPredicateForSetCC(ISD::CondCode CC, const EVT &VT, const PPCSubtarget *Subtarget)
static unsigned getCRIdxForSetCC(ISD::CondCode CC, bool &Invert)
getCRIdxForSetCC - Return the index of the condition register field associated with the SetCC conditi...
static bool isInt64Immediate(SDNode *N, uint64_t &Imm)
isInt64Immediate - This method tests to see if the node is a 64-bit constant operand.
static bool isInt32Immediate(SDNode *N, unsigned &Imm)
isInt32Immediate - This method tests to see if the node is a 32-bit constant operand.
static unsigned getBranchHint(unsigned PCC, const FunctionLoweringInfo &FuncInfo, const SDValue &DestMBB)
static bool mayUseP9Setb(SDNode *N, const ISD::CondCode &CC, SelectionDAG *DAG, bool &NeedSwapOps, bool &IsUnCmp)
static cl::opt< bool > EnableTLSOpt("ppc-tls-opt", cl::init(true), cl::desc("Enable tls optimization peephole"), cl::Hidden)
static unsigned int getVCmpInst(MVT VecVT, ISD::CondCode CC, bool HasVSX, bool &Swap, bool &Negate)
static cl::opt< ICmpInGPRType > CmpInGPR("ppc-gpr-icmps", cl::Hidden, cl::init(ICGPR_All), cl::desc("Specify the types of comparisons to emit GPR-only code for."), cl::values(clEnumValN(ICGPR_None, "none", "Do not modify integer comparisons."), clEnumValN(ICGPR_All, "all", "All possible int comparisons in GPRs."), clEnumValN(ICGPR_I32, "i32", "Only i32 comparisons in GPRs."), clEnumValN(ICGPR_I64, "i64", "Only i64 comparisons in GPRs."), clEnumValN(ICGPR_NonExtIn, "nonextin", "Only comparisons where inputs don't need [sz]ext."), clEnumValN(ICGPR_Zext, "zext", "Only comparisons with zext result."), clEnumValN(ICGPR_ZextI32, "zexti32", "Only i32 comparisons with zext result."), clEnumValN(ICGPR_ZextI64, "zexti64", "Only i64 comparisons with zext result."), clEnumValN(ICGPR_Sext, "sext", "Only comparisons with sext result."), clEnumValN(ICGPR_SextI32, "sexti32", "Only i32 comparisons with sext result."), clEnumValN(ICGPR_SextI64, "sexti64", "Only i64 comparisons with sext result.")))
static SDNode * selectI64ImmDirectPrefix(SelectionDAG *CurDAG, const SDLoc &dl, uint64_t Imm, unsigned &InstCnt)
static SDNode * selectI64ImmDirect(SelectionDAG *CurDAG, const SDLoc &dl, uint64_t Imm, unsigned &InstCnt)
static bool hasAIXSmallTLSAttr(SDValue Val)
static cl::opt< bool > BPermRewriterNoMasking("ppc-bit-perm-rewriter-stress-rotates", cl::desc("stress rotate selection in aggressive ppc isel for " "bit permutations"), cl::Hidden)
static bool isSWTestOp(SDValue N)
static SDNode * selectI64Imm(SelectionDAG *CurDAG, const SDLoc &dl, uint64_t Imm, unsigned *InstCnt=nullptr)
static bool isVSXSwap(SDValue N)
static uint32_t findContiguousZerosAtLeast(uint64_t Imm, unsigned Num)
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
LLVM_ABI APInt rotr(unsigned rotateAmt) const
Rotate right by rotateAmt.
LLVM_ABI APInt sext(unsigned width) const
Sign extend to a new width.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
MachineBasicBlock * getBasicBlock() const
LLVM Basic Block Representation.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
LLVM_ABI BranchProbability getEdgeProbability(const BasicBlock *Src, unsigned IndexInSuccessors) const
Get an edge's probability, relative to other out-edges of the Src.
int64_t getSExtValue() const
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
BranchProbabilityInfo * BPI
MachineBasicBlock * MBB
MBB - The current block.
FunctionPass class - This class is used to implement most global optimizations.
unsigned getTargetFlags() const
const GlobalValue * getGlobal() const
Module * getParent()
Get the module that this global value is contained inside of...
bool hasAttribute(Attribute::AttrKind Kind) const
Return true if the attribute exists.
static StringRef getMemConstraintName(ConstraintCode C)
LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
This class is used to represent ISD::LOAD nodes.
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
const MDOperand & getOperand(unsigned I) const
unsigned getNumOperands() const
Return number of MDNode operands.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
void setROPProtectionHashSaveIndex(int Idx)
static int getRecordFormOpcode(unsigned Opcode)
bool is32BitELFABI() const
MVT getScalarIntVT() const
const PPCInstrInfo * getInstrInfo() const override
MCRegister getThreadPointerRegister() const
bool isLittleEndian() const
CodeModel::Model getCodeModel(const TargetMachine &TM, const GlobalValue *GV) const
Calculates the effective code model for argument GV.
Common code between 32-bit and 64-bit PowerPC targets.
Wrapper class representing virtual and physical registers.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.
LLVM_ABI void dump() const
Dump this node, for debugging.
bool hasOneUse() const
Return true if there is exactly one use of this node.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
bool use_empty() const
Return true if there are no uses of this node.
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
SDVTList getVTList() const
const SDValue & getOperand(unsigned Num) const
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
bool isMachineOpcode() const
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
unsigned getMachineOpcode() const
unsigned getOpcode() const
unsigned getNumOperands() const
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
virtual bool runOnMachineFunction(MachineFunction &mf)
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDNode * SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT)
These are used for target selectors to mutate the specified node to have the specified return type,...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
const TargetLowering & getTargetLoweringInfo() const
allnodes_const_iterator allnodes_begin() const
allnodes_const_iterator allnodes_end() const
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
LLVM_ABI void setNodeMemRefs(MachineSDNode *N, ArrayRef< MachineMemOperand * > NewMemRefs)
Mutate the specified machine node's memory references to the provided list.
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
LLVM_ABI void RemoveDeadNodes()
This method deletes all unreachable nodes in the SelectionDAG.
LLVM_ABI void RemoveDeadNode(SDNode *N)
Remove the specified node from the system.
LLVM_ABI SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
LLVM_ABI SDValue FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDValue > Ops, SDNodeFlags Flags=SDNodeFlags())
const TargetMachine & getTarget() const
LLVM_ABI SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
iterator_range< allnodes_iterator > allnodes()
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
LLVM_ABI SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
ilist< SDNode >::iterator allnodes_iterator
int getMaskElt(unsigned Idx) const
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This class is used to represent ISD::STORE nodes.
TargetInstrInfo - Interface to description of machine instruction set.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
Primary interface to the complete machine description for the target machine.
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
bool isPositionIndependent() const
CodeModel::Model getCodeModel() const
Returns the code model.
unsigned getID() const
Return the register class ID number.
virtual const TargetLowering * getTargetLowering() const
A Use represents the edge between a Value definition and its users.
LLVM_ABI unsigned getOperandNo() const
Return the operand # of this use in its User.
User * getUser() const
Returns the User that contains this Use.
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ BSWAP
Byte Swap and Counting operators.
@ ADD
Simple integer binary arithmetic operators.
@ 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.
LLVM_ABI bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
bool isUnsignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs an unsigned comparison when used with intege...
@ MO_TLSLD_FLAG
MO_TLSLD_FLAG - If this bit is set the symbol reference is relative to TLS Local Dynamic model.
@ MO_PLT
On PPC, the 12 bits are not enough for all target operand flags.
@ MO_DTPREL_LO
These values identify relocations on immediates folded into memory operations.
@ MO_TPREL_FLAG
MO_TPREL_FLAG - If this bit is set, the symbol reference is relative to the thread pointer and the sy...
@ BDNZ
CHAIN = BDNZ CHAIN, DESTBB - These are used to create counter-based loops.
@ ANDI_rec_1_EQ_BIT
i1 = ANDI_rec_1_[EQ|GT]_BIT(i32 or i64 x) - Represents the result of the eq or gt bit of CR0 after ex...
@ MFOCRF
R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
@ VADD_SPLAT
VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded during instruction selection to optimi...
@ PPC32_PICGOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
@ SRA_ADDZE
The combination of sra[wd]i and addze used to implemented signed integer division by a power of 2.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
@ User
could "use" a pointer
This is an optimization pass for GlobalISel generic memory operations.
bool operator<(int64_t V1, const APSInt &V2)
FunctionAddr VTableAddr Value
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
@ Define
Register definition.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
bool isIntS16Immediate(SDNode *N, int16_t &Imm)
isIntS16Immediate - This method tests to see if the node is either a 32-bit or 64-bit immediate,...
constexpr T maskLeadingOnes(unsigned N)
Create a bitmask with the N left-most bits set to 1, and all other bits set to 0.
static bool isRunOfOnes64(uint64_t Val, unsigned &MB, unsigned &ME)
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
auto dyn_cast_or_null(const Y &Val)
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
LLVM_ABI bool isBitwiseNot(SDValue V, bool AllowUndefs=false)
Returns true if V is a bitwise not operation.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
void sort(IteratorTy Start, IteratorTy End)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isMask_64(uint64_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
int countl_one(T Value)
Count the number of ones from the most significant bit to the first zero bit.
CodeGenOptLevel
Code generation optimization level.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
FunctionPass * createPPCISelDag(PPCTargetMachine &TM, CodeGenOptLevel OL)
createPPCISelDag - This pass converts a legalized DAG into a PowerPC-specific DAG,...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Xor
Bitwise or logical XOR of integers.
@ Sub
Subtraction of integers.
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool isOneConstant(SDValue V)
Returns true if V is a constant integer one.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME)
Returns true iff Val consists of one contiguous run of 1s with any number of 0s on either side.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isInteger() const
Return true if this is an integer or a vector integer type.