49#include "llvm/IR/IntrinsicsPowerPC.h"
72#define DEBUG_TYPE "ppc-isel"
73#define PASS_NAME "PowerPC DAG->DAG Pattern Instruction Selection"
76 "Number of (sext(setcc)) nodes expanded into GPR sequence.");
78 "Number of (zext(setcc)) nodes expanded into GPR sequence.");
80 "Number of sign extensions for compare inputs added.");
82 "Number of zero extensions for compare inputs added.");
84 "Number of logical ops on i1 values calculated in GPR.");
86 "Number of compares not eliminated as they have non-extending uses.");
88 "Number of compares lowered to setb.");
92 cl::desc(
"expose the ANDI glue bug on PPC"),
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;
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);
232 const SDLoc &dl, SDValue Chain = SDValue());
237 bool SelectAddrImmOffs(SDValue
N, SDValue &Out)
const {
250 bool SelectDSForm(SDNode *Parent, SDValue
N, SDValue &Disp, SDValue &
Base) {
251 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
258 bool SelectDQForm(SDNode *Parent, SDValue
N, SDValue &Disp, SDValue &
Base) {
259 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
266 bool SelectDForm(SDNode *Parent, SDValue
N, SDValue &Disp, SDValue &
Base) {
267 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
273 bool SelectPCRelForm(SDNode *Parent, SDValue
N, SDValue &Disp,
275 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
281 bool SelectPDForm(SDNode *Parent, SDValue
N, SDValue &Disp, SDValue &
Base) {
282 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
289 bool SelectXForm(SDNode *Parent, SDValue
N, SDValue &Disp, SDValue &
Base) {
290 return PPCLowering->SelectOptimalAddrMode(Parent,
N, Disp,
Base, *CurDAG,
296 bool SelectForceXForm(SDNode *Parent, SDValue
N, SDValue &Disp,
298 return PPCLowering->SelectForceXFormMode(
N, Disp,
Base, *CurDAG) ==
308 bool SelectAddrIdx(SDValue
N, SDValue &
Base, SDValue &Index) {
309 return PPCLowering->SelectAddressRegReg(
N,
Base, Index, *CurDAG,
319 bool SelectAddrIdxX4(SDValue
N, SDValue &
Base, SDValue &Index) {
320 return PPCLowering->SelectAddressRegReg(
N,
Base, Index, *CurDAG,
330 bool SelectAddrIdxX16(SDValue
N, SDValue &
Base, SDValue &Index) {
331 return PPCLowering->SelectAddressRegReg(
N,
Base, Index, *CurDAG,
337 bool SelectAddrIdxOnly(SDValue
N, SDValue &
Base, SDValue &Index) {
338 return PPCLowering->SelectAddressRegRegOnly(
N,
Base, Index, *CurDAG);
345 bool SelectAddrImm(SDValue
N, SDValue &Disp,
347 return PPCLowering->SelectAddressRegImm(
N, Disp,
Base, *CurDAG,
354 bool SelectAddrImmX4(SDValue
N, SDValue &Disp, SDValue &
Base) {
355 return PPCLowering->SelectAddressRegImm(
N, Disp,
Base, *CurDAG,
Align(4));
361 bool SelectAddrImmX16(SDValue
N, SDValue &Disp, SDValue &
Base) {
362 return PPCLowering->SelectAddressRegImm(
N, Disp,
Base, *CurDAG,
369 bool SelectAddrImmX34(SDValue
N, SDValue &Disp, SDValue &
Base) {
370 return PPCLowering->SelectAddressRegImm34(
N, Disp,
Base, *CurDAG);
374 bool SelectAddr(SDValue
N, SDValue &
Base) {
379 bool SelectAddrPCRel(SDValue
N, SDValue &
Base) {
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 TargetInstrInfo *
TII = Subtarget->getInstrInfo();
408 SDValue RC = CurDAG->getTargetConstant(TRC->
getID(), dl, MVT::i32);
410 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
411 dl,
Op.getValueType(),
414 OutOps.push_back(NewOp);
421#include "PPCGenDAGISel.inc"
424 bool trySETCC(SDNode *
N);
425 bool tryFoldSWTestBRCC(SDNode *
N);
426 bool trySelectLoopCountIntrinsic(SDNode *
N);
427 bool tryAsSingleRLDICL(SDNode *
N);
428 bool tryAsSingleRLDCL(SDNode *
N);
429 bool tryAsSingleRLDICR(SDNode *
N);
430 bool tryAsSingleRLWINM(SDNode *
N);
431 bool tryAsSingleRLWINM8(SDNode *
N);
432 bool tryAsSingleRLWIMI(SDNode *
N);
433 bool tryAsPairOfRLDICL(SDNode *
N);
434 bool tryAsSingleRLDIMI(SDNode *
N);
436 void PeepholePPC64();
437 void PeepholePPC64ZExt();
438 void PeepholeCROps();
440 SDValue combineToCMPB(SDNode *
N);
441 void foldBoolExts(SDValue &Res, SDNode *&
N);
443 bool AllUsersSelectZero(SDNode *
N);
444 void SwapAllSelectUsers(SDNode *
N);
446 bool isOffsetMultipleOf(SDNode *
N,
unsigned Val)
const;
447 void transferMemOperands(SDNode *
N, SDNode *Result);
453 explicit PPCDAGToDAGISelLegacy(PPCTargetMachine &tm,
455 : SelectionDAGISelLegacy(
456 ID, std::make_unique<PPCDAGToDAGISel>(tm, OptLevel)) {}
460char PPCDAGToDAGISelLegacy::ID = 0;
467SDNode *PPCDAGToDAGISel::getGlobalBaseReg() {
468 if (!GlobalBaseReg) {
476 if (PPCLowering->getPointerTy(CurDAG->getDataLayout()) == MVT::i32) {
479 if (!Subtarget->isSecurePlt() &&
489 TII.get(PPC::UpdateGBR), GlobalBaseReg)
495 RegInfo->createVirtualRegister(&PPC::GPRC_and_GPRC_NOR0RegClass);
515 return CurDAG->getRegister(GlobalBaseReg,
516 PPCLowering->getPointerTy(CurDAG->getDataLayout()))
556 if (
N->getOpcode() ==
ISD::Constant &&
N->getValueType(0) == MVT::i32) {
557 Imm =
N->getAsZExtVal();
566 if (
N->getOpcode() ==
ISD::Constant &&
N->getValueType(0) == MVT::i64) {
567 Imm =
N->getAsZExtVal();
618 if (std::max(TProb, FProb) / Threshold < std::min(TProb, FProb))
622 <<
"::" << BB->
getName() <<
"'\n"
623 <<
" -> " <<
TBB->getName() <<
": " << TProb <<
"\n"
624 <<
" -> " << FBB->
getName() <<
": " << FProb <<
"\n");
640 return N->getOpcode() ==
Opc
647 SDValue TFI = CurDAG->getTargetFrameIndex(FI,
N->getValueType(0));
648 unsigned Opc =
N->getValueType(0) == MVT::i32 ? PPC::ADDI : PPC::ADDI8;
650 CurDAG->SelectNodeTo(SN,
Opc,
N->getValueType(0), TFI,
651 getSmallIPtrImm(
Offset, dl));
653 ReplaceNode(SN, CurDAG->getMachineNode(
Opc, dl,
N->getValueType(0), TFI,
654 getSmallIPtrImm(
Offset, dl)));
657bool PPCDAGToDAGISel::isRotateAndMask(SDNode *
N,
unsigned Mask,
658 bool isShiftMask,
unsigned &SH,
659 unsigned &MB,
unsigned &ME) {
662 if (
N->getValueType(0) != MVT::i32)
666 unsigned Indeterminant = ~0;
667 unsigned Opcode =
N->getOpcode();
668 if (
N->getNumOperands() != 2 ||
674 if (isShiftMask)
Mask =
Mask << Shift;
676 Indeterminant = ~(0xFFFFFFFFu << Shift);
679 if (isShiftMask)
Mask =
Mask >> Shift;
681 Indeterminant = ~(0xFFFFFFFFu >> Shift);
691 if (Mask && !(Mask & Indeterminant)) {
703 Base.getOpcode() == PPCISD::ADD_TLS &&
704 "Only expecting the ADD_TLS instruction to acquire the thread pointer!");
708 unsigned ADDTLSOp1Opcode = ADDTLSOp1.getOpcode();
717 if (ADDTLSOp1Opcode == PPCISD::LD_GOT_TPREL_L)
722 if (LD && LD->getBasePtr().getOpcode() == PPCISD::MAT_PCREL_ADDR)
728 if (ADDTLSOp1Opcode == PPCISD::GET_TPOINTER)
753 if (
Base.getOpcode() != PPCISD::ADD_TLS)
755 for (
auto *ADDTLSUse :
Base.getNode()->users()) {
760 if (LD->getSrcValueOffset() != 0 || !LD->getOffset().isUndef())
763 if (ST->getSrcValueOffset() != 0 || !ST->getOffset().isUndef())
769 if (
Base.getOperand(1).getOpcode() == PPCISD::TLS_LOCAL_EXEC_MAT_ADDR)
778bool PPCDAGToDAGISel::tryTLSXFormStore(StoreSDNode *ST) {
779 SDValue
Base =
ST->getBasePtr();
784 EVT MemVT =
ST->getMemoryVT();
785 EVT RegVT =
ST->getValue().getValueType();
792 Opcode = (RegVT == MVT::i32) ? PPC::STBXTLS_32 : PPC::STBXTLS;
796 Opcode = (RegVT == MVT::i32) ? PPC::STHXTLS_32 : PPC::STHXTLS;
800 Opcode = (RegVT == MVT::i32) ? PPC::STWXTLS_32 : PPC::STWXTLS;
804 Opcode = PPC::STDXTLS;
808 Opcode = PPC::STFSXTLS;
812 Opcode = PPC::STFDXTLS;
816 SDValue Chain =
ST->getChain();
817 SDVTList VTs =
ST->getVTList();
818 SDValue
Ops[] = {
ST->getValue(),
Base.getOperand(0),
Base.getOperand(1),
820 SDNode *MN = CurDAG->getMachineNode(Opcode, dl, VTs,
Ops);
821 transferMemOperands(ST, MN);
826bool PPCDAGToDAGISel::tryTLSXFormLoad(LoadSDNode *LD) {
827 SDValue
Base =
LD->getBasePtr();
832 EVT MemVT =
LD->getMemoryVT();
833 EVT RegVT =
LD->getValueType(0);
840 Opcode = (RegVT == MVT::i32) ? PPC::LBZXTLS_32 : PPC::LBZXTLS;
844 if (RegVT == MVT::i32)
845 Opcode = isSExt ? PPC::LHAXTLS_32 : PPC::LHZXTLS_32;
847 Opcode = isSExt ? PPC::LHAXTLS : PPC::LHZXTLS;
851 if (RegVT == MVT::i32)
852 Opcode = isSExt ? PPC::LWAXTLS_32 : PPC::LWZXTLS_32;
854 Opcode = isSExt ? PPC::LWAXTLS : PPC::LWZXTLS;
858 Opcode = PPC::LDXTLS;
862 Opcode = PPC::LFSXTLS;
866 Opcode = PPC::LFDXTLS;
870 SDValue Chain =
LD->getChain();
871 SDVTList VTs =
LD->getVTList();
872 SDValue
Ops[] = {
Base.getOperand(0),
Base.getOperand(1), Chain};
873 SDNode *MN = CurDAG->getMachineNode(Opcode, dl, VTs,
Ops);
874 transferMemOperands(LD, MN);
881bool PPCDAGToDAGISel::tryBitfieldInsert(SDNode *
N) {
882 SDValue Op0 =
N->getOperand(0);
883 SDValue Op1 =
N->getOperand(1);
892 KnownBits LKnown = CurDAG->computeKnownBits(Op0);
893 KnownBits RKnown = CurDAG->computeKnownBits(Op1);
898 if ((TargetMask | InsertMask) == 0xFFFFFFFF) {
901 unsigned Value, SH = 0;
902 TargetMask = ~TargetMask;
903 InsertMask = ~InsertMask;
937 KnownBits MKnown = CurDAG->computeKnownBits(Op1.
getOperand(1));
951 SDValue
Ops[] = { Op0, Op1, getI32Imm(SH, dl), getI32Imm(MB, dl),
953 ReplaceNode(
N, CurDAG->getMachineNode(PPC::RLWIMI, dl, MVT::i32,
Ops));
961 unsigned MaxTruncation = 0;
968 User->isMachineOpcode() ?
User->getMachineOpcode() :
User->getOpcode();
972 if (
User->isMachineOpcode())
974 MaxTruncation = std::max(MaxTruncation,
975 (
unsigned)
User->getValueType(0).getSizeInBits());
978 if (
User->isMachineOpcode())
984 MaxTruncation = std::max(MaxTruncation, MemVTSize);
993 MaxTruncation = std::max(MaxTruncation, 32u);
1001 MaxTruncation = std::max(MaxTruncation, 16u);
1009 MaxTruncation = std::max(MaxTruncation, 8u);
1013 return MaxTruncation;
1021 if ((HiTZ + LoLZ) >= Num)
1035 SDNode *Result =
nullptr;
1038 auto getI32Imm = [CurDAG, dl](
unsigned Imm) {
1052 if (TZ > 15 && (LZ > 32 || LO > 32))
1054 getI32Imm((
Imm >> 16) & 0xffff));
1058 assert(LZ < 64 &&
"Unexpected leading zeros here.");
1065 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
1066 Result = CurDAG->
getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
1068 getI32Imm(
Imm & 0xffff));
1076 if ((LZ + FO + TZ) > 48) {
1078 getI32Imm((
Imm >> TZ) & 0xffff));
1080 getI32Imm(TZ), getI32Imm(LZ));
1097 if ((LZ + TO) > 48) {
1101 assert(LZ <= 32 &&
"Unexpected shift value.");
1103 getI32Imm((
Imm >> (48 - LZ) & 0xffff)));
1105 getI32Imm(48 - LZ), getI32Imm(LZ));
1123 if ((LZ + FO + TO) > 48) {
1125 getI32Imm((
Imm >> TO) & 0xffff));
1127 getI32Imm(TO), getI32Imm(LZ));
1133 if (LZ == 32 && ((Lo32 & 0x8000) == 0)) {
1135 getI32Imm(Lo32 & 0xffff));
1137 getI32Imm(Lo32 >> 16));
1161 getI32Imm(RotImm & 0xffff));
1163 getI32Imm(Shift), getI32Imm(0));
1170 uint64_t ImmHi16 = (Lo32 >> 16) & 0xffff;
1174 CurDAG->
getMachineNode(PPC::LI8, dl, MVT::i64, getI32Imm(ImmLo16));
1177 CurDAG->
getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(ImmHi16));
1181 CurDAG->
getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(ImmHi16));
1183 SDValue(Result, 0), getI32Imm(ImmLo16));
1200 if ((LZ + FO + TZ) > 32) {
1202 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
1203 Result = CurDAG->
getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
1205 getI32Imm((
Imm >> TZ) & 0xffff));
1207 getI32Imm(TZ), getI32Imm(LZ));
1214 if ((LZ + TO) > 32) {
1218 assert(LZ <= 32 &&
"Unexpected shift value.");
1220 getI32Imm((
Imm >> (48 - LZ)) & 0xffff));
1222 getI32Imm((
Imm >> (32 - LZ)) & 0xffff));
1224 getI32Imm(32 - LZ), getI32Imm(LZ));
1232 if ((LZ + FO + TO) > 32) {
1234 getI32Imm((
Imm >> (TO + 16)) & 0xffff));
1236 getI32Imm((
Imm >> TO) & 0xffff));
1238 getI32Imm(TO), getI32Imm(LZ));
1250 uint64_t ImmHi16 = (RotImm >> 16) & 0xffff;
1251 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
1252 Result = CurDAG->
getMachineNode(Opcode, dl, MVT::i64, getI32Imm(ImmHi16));
1254 getI32Imm(RotImm & 0xffff));
1256 getI32Imm(Shift), getI32Imm(0));
1277 auto getI32Imm = [CurDAG, dl](
unsigned Imm) {
1296 SDNode *Result =
nullptr;
1303 if ((LZ + FO + TZ) > 30) {
1307 getI64Imm(Extended.getZExtValue()));
1309 getI32Imm(TZ), getI32Imm(LZ));
1325 if ((LZ + TO) > 30) {
1326 APInt SignedInt34 =
APInt(34, (
Imm >> (30 - LZ)) & 0x3ffffffff);
1329 getI64Imm(Extended.getZExtValue()));
1331 getI32Imm(30 - LZ), getI32Imm(LZ));
1338 if ((LZ + FO + TO) > 30) {
1342 getI64Imm(Extended.getZExtValue()));
1344 getI32Imm(TO), getI32Imm(LZ));
1356 for (
unsigned Shift = 0; Shift < 63; ++Shift) {
1360 CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(RotImm));
1362 SDValue(Result, 0), getI32Imm(Shift),
1370 Result = CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(Hi32));
1380 CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(Hi32));
1382 CurDAG->
getMachineNode(PPC::PLI8, dl, MVT::i64, getI64Imm(Lo32));
1389 unsigned *InstCnt =
nullptr) {
1390 unsigned InstCntDirect = 0;
1401 if (Subtarget.hasPrefixInstrs() && InstCntDirect != 1) {
1402 unsigned InstCntDirectP = 0;
1409 if (ResultP && (!Result || InstCntDirectP < InstCntDirect)) {
1411 *InstCnt = InstCntDirectP;
1418 *InstCnt = InstCntDirect;
1421 auto getI32Imm = [CurDAG, dl](
unsigned Imm) {
1430 if (Hi16OfLo32 && Lo16OfLo32) {
1433 bool IsSelected =
false;
1437 CurDAG->
getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(Hi16));
1439 SDValue(Result, 0), getI32Imm(Lo16));
1445 if (Hi16OfHi32 == Lo16OfHi32 && Lo16OfHi32 == Lo16OfLo32) {
1447 Result = getSplat(Hi16OfLo32, Lo16OfLo32);
1452 }
else if (Hi16OfHi32 == Hi16OfLo32 && Hi16OfLo32 == Lo16OfLo32) {
1454 Result = getSplat(Hi16OfHi32, Lo16OfHi32);
1457 getI32Imm(16), getI32Imm(31)};
1459 }
else if (Lo16OfHi32 == Lo16OfLo32 && Hi16OfLo32 == Lo16OfLo32) {
1461 Result = getSplat(Hi16OfHi32, Lo16OfHi32);
1464 getI32Imm(0), getI32Imm(15)};
1467 if (IsSelected ==
true) {
1480 SDValue(Result, 0), getI32Imm(Hi16OfLo32));
1485 getI32Imm(Lo16OfLo32));
1489 *InstCnt = InstCntDirect;
1498 int64_t
Imm =
N->getAsZExtVal();
1510class BitPermutationSelector {
1525 VariableKnownToBeZero
1528 ValueBit(SDValue V,
unsigned I, Kind K = Variable)
1530 ValueBit(Kind K = Variable) :
Idx(UINT32_MAX), K(K) {}
1533 return K == ConstZero || K == VariableKnownToBeZero;
1536 bool hasValue()
const {
1537 return K == Variable || K == VariableKnownToBeZero;
1541 assert(hasValue() &&
"Cannot get the value of a constant bit");
1545 unsigned getValueBitIndex()
const {
1546 assert(hasValue() &&
"Cannot get the value bit index of a constant bit");
1555 unsigned StartIdx, EndIdx;
1565 bool Repl32Coalesced;
1567 BitGroup(SDValue V,
unsigned R,
unsigned S,
unsigned E)
1568 :
V(
V), RLAmt(
R), StartIdx(S), EndIdx(
E), Repl32(
false), Repl32CR(
false),
1569 Repl32Coalesced(
false) {
1570 LLVM_DEBUG(
dbgs() <<
"\tbit group for " <<
V.getNode() <<
" RLAmt = " << R
1571 <<
" [" << S <<
", " <<
E <<
"]\n");
1577 struct ValueRotInfo {
1579 unsigned RLAmt = std::numeric_limits<unsigned>::max();
1580 unsigned NumGroups = 0;
1581 unsigned FirstGroupStartIdx = std::numeric_limits<unsigned>::max();
1582 bool Repl32 =
false;
1584 ValueRotInfo() =
default;
1592 if (Repl32 <
Other.Repl32)
1594 else if (Repl32 >
Other.Repl32)
1596 else if (NumGroups >
Other.NumGroups)
1598 else if (NumGroups <
Other.NumGroups)
1600 else if (RLAmt == 0 &&
Other.RLAmt != 0)
1602 else if (RLAmt != 0 &&
Other.RLAmt == 0)
1604 else if (FirstGroupStartIdx <
Other.FirstGroupStartIdx)
1610 using ValueBitsMemoizedValue = std::pair<bool, SmallVector<ValueBit, 64>>;
1611 using ValueBitsMemoizer =
1612 DenseMap<SDValue, std::unique_ptr<ValueBitsMemoizedValue>>;
1613 ValueBitsMemoizer Memoizer;
1619 std::pair<bool, SmallVector<ValueBit, 64> *> getValueBits(SDValue V,
1621 auto &ValueEntry = Memoizer[
V];
1623 return std::make_pair(ValueEntry->first, &ValueEntry->second);
1624 ValueEntry.reset(
new ValueBitsMemoizedValue());
1625 bool &Interesting = ValueEntry->first;
1627 Bits.resize(NumBits);
1629 switch (
V.getOpcode()) {
1634 unsigned RotAmt =
V.getConstantOperandVal(1) & (NumBits - 1);
1636 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1638 for (
unsigned i = 0; i < NumBits; ++i)
1639 Bits[i] = LHSBits[i < RotAmt ? i + (NumBits - RotAmt) : i - RotAmt];
1641 return std::make_pair(Interesting =
true, &Bits);
1648 unsigned ShiftAmt =
V.getConstantOperandVal(1) & ((NumBits << 1) - 1);
1650 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1652 if (ShiftAmt >= NumBits) {
1653 for (
unsigned i = 0; i < NumBits; ++i)
1654 Bits[i] = ValueBit(ValueBit::ConstZero);
1656 for (
unsigned i = ShiftAmt; i < NumBits; ++i)
1657 Bits[i] = LHSBits[i - ShiftAmt];
1658 for (
unsigned i = 0; i < ShiftAmt; ++i)
1659 Bits[i] = ValueBit(ValueBit::ConstZero);
1662 return std::make_pair(Interesting =
true, &Bits);
1669 unsigned ShiftAmt =
V.getConstantOperandVal(1) & ((NumBits << 1) - 1);
1671 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1673 if (ShiftAmt >= NumBits) {
1674 for (
unsigned i = 0; i < NumBits; ++i)
1675 Bits[i] = ValueBit(ValueBit::ConstZero);
1677 for (
unsigned i = 0; i < NumBits - ShiftAmt; ++i)
1678 Bits[i] = LHSBits[i + ShiftAmt];
1679 for (
unsigned i = NumBits - ShiftAmt; i < NumBits; ++i)
1680 Bits[i] = ValueBit(ValueBit::ConstZero);
1683 return std::make_pair(Interesting =
true, &Bits);
1695 std::tie(Interesting, LHSBits) = getValueBits(
V.getOperand(0), NumBits);
1697 for (
unsigned i = 0; i < NumBits; ++i)
1698 if (((Mask >> i) & 1) == 1)
1699 Bits[i] = (*LHSBits)[i];
1703 if ((*LHSBits)[i].
isZero())
1704 Bits[i] = (*LHSBits)[i];
1706 Bits[i] = ValueBit(ValueBit::ConstZero);
1709 return std::make_pair(Interesting, &Bits);
1713 const auto &LHSBits = *getValueBits(
V.getOperand(0), NumBits).second;
1714 const auto &RHSBits = *getValueBits(
V.getOperand(1), NumBits).second;
1716 bool AllDisjoint =
true;
1717 SDValue LastVal = SDValue();
1718 unsigned LastIdx = 0;
1719 for (
unsigned i = 0; i < NumBits; ++i) {
1727 if (LHSBits[i].hasValue() && LHSBits[i].
getValue() == LastVal &&
1728 LHSBits[i].getValueBitIndex() == LastIdx + 1)
1729 Bits[i] = LHSBits[i];
1730 else if (RHSBits[i].hasValue() && RHSBits[i].
getValue() == LastVal &&
1731 RHSBits[i].getValueBitIndex() == LastIdx + 1)
1732 Bits[i] = RHSBits[i];
1734 Bits[i] = ValueBit(ValueBit::ConstZero);
1736 else if (LHSBits[i].
isZero())
1737 Bits[i] = RHSBits[i];
1738 else if (RHSBits[i].
isZero())
1739 Bits[i] = LHSBits[i];
1741 AllDisjoint =
false;
1745 if (Bits[i].hasValue()) {
1746 LastVal =
Bits[i].getValue();
1747 LastIdx =
Bits[i].getValueBitIndex();
1750 if (LastVal) LastVal = SDValue();
1758 return std::make_pair(Interesting =
true, &Bits);
1762 if (
V.getValueType() != MVT::i64 ||
1763 V.getOperand(0).getValueType() != MVT::i32)
1767 const unsigned NumOperandBits = 32;
1768 std::tie(Interesting, LHSBits) = getValueBits(
V.getOperand(0),
1771 for (
unsigned i = 0; i < NumOperandBits; ++i)
1772 Bits[i] = (*LHSBits)[i];
1774 for (
unsigned i = NumOperandBits; i < NumBits; ++i)
1775 Bits[i] = ValueBit(ValueBit::ConstZero);
1777 return std::make_pair(Interesting, &Bits);
1780 EVT
FromType =
V.getOperand(0).getValueType();
1781 EVT ToType =
V.getValueType();
1783 if (FromType != MVT::i64 || ToType != MVT::i32)
1785 const unsigned NumAllBits =
FromType.getSizeInBits();
1787 std::tie(Interesting, InBits) = getValueBits(
V.getOperand(0),
1793 bool UseUpper32bit =
false;
1794 for (
unsigned i = 0; i < NumValidBits; ++i)
1795 if ((*InBits)[i].hasValue() && (*InBits)[i].getValueBitIndex() >= 32) {
1796 UseUpper32bit =
true;
1802 for (
unsigned i = 0; i < NumValidBits; ++i)
1803 Bits[i] = (*InBits)[i];
1805 return std::make_pair(Interesting, &Bits);
1811 std::tie(Interesting, LHSBits) = getValueBits(
V.getOperand(0),
1815 const unsigned NumValidBits =
FromType.getSizeInBits();
1816 for (
unsigned i = 0; i < NumValidBits; ++i)
1817 Bits[i] = (*LHSBits)[i];
1821 for (
unsigned i = NumValidBits; i < NumBits; ++i)
1822 Bits[i] = (*LHSBits)[i].hasValue()
1823 ? ValueBit((*LHSBits)[i].
getValue(),
1824 (*LHSBits)[i].getValueBitIndex(),
1825 ValueBit::VariableKnownToBeZero)
1826 : ValueBit(ValueBit::ConstZero);
1828 return std::make_pair(Interesting, &Bits);
1833 EVT VT =
LD->getMemoryVT();
1836 for (
unsigned i = 0; i < NumValidBits; ++i)
1837 Bits[i] = ValueBit(V, i);
1840 for (
unsigned i = NumValidBits; i < NumBits; ++i)
1841 Bits[i] = ValueBit(V, i, ValueBit::VariableKnownToBeZero);
1845 return std::make_pair(Interesting =
false, &Bits);
1850 for (
unsigned i = 0; i < NumBits; ++i)
1851 Bits[i] = ValueBit(V, i);
1853 return std::make_pair(Interesting =
false, &Bits);
1858 void computeRotationAmounts() {
1860 RLAmt.resize(
Bits.size());
1861 for (
unsigned i = 0; i <
Bits.size(); ++i)
1862 if (Bits[i].hasValue()) {
1863 unsigned VBI =
Bits[i].getValueBitIndex();
1867 RLAmt[i] =
Bits.size() - (VBI - i);
1868 }
else if (Bits[i].
isZero()) {
1870 RLAmt[i] = UINT32_MAX;
1879 void collectBitGroups(
bool LateMask) {
1882 unsigned LastRLAmt = RLAmt[0];
1883 SDValue LastValue =
Bits[0].hasValue() ?
Bits[0].getValue() : SDValue();
1884 unsigned LastGroupStartIdx = 0;
1885 bool IsGroupOfZeros = !
Bits[LastGroupStartIdx].hasValue();
1886 for (
unsigned i = 1; i <
Bits.size(); ++i) {
1887 unsigned ThisRLAmt = RLAmt[i];
1888 SDValue ThisValue =
Bits[i].hasValue() ?
Bits[i].getValue() : SDValue();
1889 if (LateMask && !ThisValue) {
1890 ThisValue = LastValue;
1891 ThisRLAmt = LastRLAmt;
1894 if (BitGroups.empty())
1895 LastGroupStartIdx = 0;
1902 if (IsGroupOfZeros && Bits[i].
isZero())
1907 if (ThisRLAmt == LastRLAmt && ThisValue == LastValue)
1910 if (!(IsGroupOfZeros && ThisValue && !Bits[i].
isZero()))
1914 BitGroups.push_back(BitGroup(LastValue, LastRLAmt, LastGroupStartIdx,
1916 LastRLAmt = ThisRLAmt;
1917 LastValue = ThisValue;
1918 LastGroupStartIdx = i;
1919 IsGroupOfZeros = !
Bits[LastGroupStartIdx].hasValue();
1922 BitGroups.push_back(BitGroup(LastValue, LastRLAmt, LastGroupStartIdx,
1925 if (BitGroups.empty())
1929 if (BitGroups.size() > 1) {
1933 if (BitGroups[0].StartIdx == 0 &&
1934 BitGroups[BitGroups.size()-1].EndIdx ==
Bits.size()-1 &&
1935 BitGroups[0].V == BitGroups[BitGroups.size()-1].V &&
1936 BitGroups[0].RLAmt == BitGroups[BitGroups.size()-1].RLAmt) {
1937 LLVM_DEBUG(
dbgs() <<
"\tcombining final bit group with initial one\n");
1938 BitGroups[BitGroups.size()-1].EndIdx = BitGroups[0].EndIdx;
1939 BitGroups.erase(BitGroups.begin());
1949 void collectValueRotInfo() {
1952 for (
auto &BG : BitGroups) {
1953 unsigned RLAmtKey = BG.RLAmt + (BG.Repl32 ? 64 : 0);
1954 ValueRotInfo &VRI = ValueRots[std::make_pair(BG.V, RLAmtKey)];
1956 VRI.RLAmt = BG.RLAmt;
1957 VRI.Repl32 = BG.Repl32;
1959 VRI.FirstGroupStartIdx = std::min(VRI.FirstGroupStartIdx, BG.StartIdx);
1964 ValueRotsVec.clear();
1965 for (
auto &
I : ValueRots) {
1966 ValueRotsVec.push_back(
I.second);
1979 void assignRepl32BitGroups() {
1990 auto IsAllLow32 = [
this](BitGroup & BG) {
1991 if (BG.StartIdx <= BG.EndIdx) {
1992 for (
unsigned i = BG.StartIdx; i <= BG.EndIdx; ++i) {
1993 if (!Bits[i].hasValue())
1995 if (Bits[i].getValueBitIndex() >= 32)
1999 for (
unsigned i = BG.StartIdx; i <
Bits.size(); ++i) {
2000 if (!Bits[i].hasValue())
2002 if (Bits[i].getValueBitIndex() >= 32)
2005 for (
unsigned i = 0; i <= BG.EndIdx; ++i) {
2006 if (!Bits[i].hasValue())
2008 if (Bits[i].getValueBitIndex() >= 32)
2016 for (
auto &BG : BitGroups) {
2020 if (BG.RLAmt == 0) {
2021 auto PotentiallyMerged = [
this](BitGroup & BG) {
2022 for (
auto &BG2 : BitGroups)
2023 if (&BG != &BG2 && BG.V == BG2.V &&
2024 (BG2.RLAmt == 0 || BG2.RLAmt == 32))
2028 if (!PotentiallyMerged(BG))
2031 if (BG.StartIdx < 32 && BG.EndIdx < 32) {
2032 if (IsAllLow32(BG)) {
2033 if (BG.RLAmt >= 32) {
2041 << BG.V.getNode() <<
" RLAmt = " << BG.RLAmt <<
" ["
2042 << BG.StartIdx <<
", " << BG.EndIdx <<
"]\n");
2048 for (
auto I = BitGroups.begin();
I != BitGroups.end();) {
2051 auto IP = (
I == BitGroups.begin()) ?
2052 std::prev(BitGroups.end()) : std::prev(
I);
2053 if (
I->Repl32 && IP->Repl32 &&
I->V == IP->V &&
I->RLAmt == IP->RLAmt &&
2054 I->StartIdx == (IP->EndIdx + 1) % 64 &&
I != IP) {
2056 LLVM_DEBUG(dbgs() <<
"\tcombining 32-bit replicated bit group for "
2057 << I->V.getNode() <<
" RLAmt = " << I->RLAmt <<
" ["
2058 << I->StartIdx <<
", " << I->EndIdx
2059 <<
"] with group with range [" << IP->StartIdx <<
", "
2060 << IP->EndIdx <<
"]\n");
2062 IP->EndIdx = I->EndIdx;
2063 IP->Repl32CR = IP->Repl32CR || I->Repl32CR;
2064 IP->Repl32Coalesced = true;
2065 I = BitGroups.erase(I);
2074 if (I->StartIdx == 32 && I->EndIdx == 63) {
2075 assert(std::next(I) == BitGroups.end() &&
2076 "bit group ends at index 63 but there is another?");
2077 auto IN = BitGroups.begin();
2079 if (IP->Repl32 && IN->Repl32 && I->V == IP->V && I->V == IN->V &&
2080 (I->RLAmt % 32) == IP->RLAmt && (I->RLAmt % 32) == IN->RLAmt &&
2081 IP->EndIdx == 31 && IN->StartIdx == 0 && I != IP &&
2084 LLVM_DEBUG(dbgs() <<
"\tcombining bit group for " << I->V.getNode()
2085 <<
" RLAmt = " << I->RLAmt <<
" [" << I->StartIdx
2086 <<
", " << I->EndIdx
2087 <<
"] with 32-bit replicated groups with ranges ["
2088 << IP->StartIdx <<
", " << IP->EndIdx <<
"] and ["
2089 << IN->StartIdx <<
", " << IN->EndIdx <<
"]\n");
2097 IP->Repl32CR = IP->Repl32CR || I->RLAmt >= 32;
2098 IP->Repl32Coalesced = true;
2099 I = BitGroups.erase(I);
2104 IP->EndIdx = IN->EndIdx;
2105 IP->Repl32CR = IP->Repl32CR || IN->Repl32CR || I->RLAmt >= 32;
2106 IP->Repl32Coalesced = true;
2107 I = BitGroups.erase(I);
2108 BitGroups.erase(BitGroups.begin());
2122 SDValue getI32Imm(
unsigned Imm,
const SDLoc &dl) {
2123 return CurDAG->getTargetConstant(
Imm, dl, MVT::i32);
2128 for (
unsigned i = 0; i <
Bits.size(); ++i) {
2129 if (Bits[i].hasValue())
2131 Mask |= (UINT64_C(1) << i);
2141 SDValue ExtendToInt64(SDValue V,
const SDLoc &dl) {
2142 if (
V.getValueSizeInBits() == 64)
2145 assert(
V.getValueSizeInBits() == 32);
2146 SDValue SubRegIdx = CurDAG->getTargetConstant(PPC::sub_32, dl, MVT::i32);
2147 SDValue ImDef = SDValue(CurDAG->getMachineNode(PPC::IMPLICIT_DEF, dl,
2149 SDValue ExtVal = SDValue(CurDAG->getMachineNode(PPC::INSERT_SUBREG, dl,
2155 SDValue TruncateToInt32(SDValue V,
const SDLoc &dl) {
2156 if (
V.getValueSizeInBits() == 32)
2159 assert(
V.getValueSizeInBits() == 64);
2160 SDValue SubRegIdx = CurDAG->getTargetConstant(PPC::sub_32, dl, MVT::i32);
2161 SDValue SubVal = SDValue(CurDAG->getMachineNode(PPC::EXTRACT_SUBREG, dl,
2162 MVT::i32, V, SubRegIdx), 0);
2169 void SelectAndParts32(
const SDLoc &dl, SDValue &Res,
unsigned *InstCnt) {
2173 for (ValueRotInfo &VRI : ValueRotsVec) {
2175 for (
unsigned i = 0; i <
Bits.size(); ++i) {
2176 if (!Bits[i].hasValue() || Bits[i].
getValue() != VRI.V)
2178 if (RLAmt[i] != VRI.RLAmt)
2184 unsigned ANDIMask = (
Mask & UINT16_MAX), ANDISMask = Mask >> 16;
2185 assert((ANDIMask != 0 || ANDISMask != 0) &&
2186 "No set bits in mask for value bit groups");
2187 bool NeedsRotate = VRI.RLAmt != 0;
2203 unsigned NumAndInsts = (unsigned) NeedsRotate +
2204 (
unsigned) (ANDIMask != 0) +
2205 (
unsigned) (ANDISMask != 0) +
2206 (
unsigned) (ANDIMask != 0 && ANDISMask != 0) +
2207 (
unsigned) (bool) Res;
2209 LLVM_DEBUG(
dbgs() <<
"\t\trotation groups for " << VRI.V.getNode()
2210 <<
" RL: " << VRI.RLAmt <<
":"
2211 <<
"\n\t\t\tisel using masking: " << NumAndInsts
2212 <<
" using rotates: " << VRI.NumGroups <<
"\n");
2214 if (NumAndInsts >= VRI.NumGroups)
2219 if (InstCnt) *InstCnt += NumAndInsts;
2224 { TruncateToInt32(VRI.V, dl), getI32Imm(VRI.RLAmt, dl),
2225 getI32Imm(0, dl), getI32Imm(31, dl) };
2226 VRot = SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32,
2229 VRot = TruncateToInt32(VRI.V, dl);
2232 SDValue ANDIVal, ANDISVal;
2234 ANDIVal = SDValue(CurDAG->getMachineNode(PPC::ANDI_rec, dl, MVT::i32,
2235 VRot, getI32Imm(ANDIMask, dl)),
2239 SDValue(CurDAG->getMachineNode(PPC::ANDIS_rec, dl, MVT::i32, VRot,
2240 getI32Imm(ANDISMask, dl)),
2245 TotalVal = ANDISVal;
2249 TotalVal = SDValue(CurDAG->getMachineNode(PPC::OR, dl, MVT::i32,
2250 ANDIVal, ANDISVal), 0);
2255 Res = SDValue(CurDAG->getMachineNode(PPC::OR, dl, MVT::i32,
2260 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
2261 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt;
2267 SDNode *Select32(SDNode *
N,
bool LateMask,
unsigned *InstCnt) {
2271 if (InstCnt) *InstCnt = 0;
2274 SelectAndParts32(dl, Res, InstCnt);
2279 if ((!NeedMask || LateMask) && !Res) {
2280 ValueRotInfo &VRI = ValueRotsVec[0];
2282 if (InstCnt) *InstCnt += 1;
2284 { TruncateToInt32(VRI.V, dl), getI32Imm(VRI.RLAmt, dl),
2285 getI32Imm(0, dl), getI32Imm(31, dl) };
2286 Res = SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32,
Ops),
2289 Res = TruncateToInt32(VRI.V, dl);
2293 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
2294 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt;
2298 if (InstCnt) *InstCnt += BitGroups.size();
2301 for (
auto &BG : BitGroups) {
2304 { TruncateToInt32(BG.V, dl), getI32Imm(BG.RLAmt, dl),
2305 getI32Imm(
Bits.size() - BG.EndIdx - 1, dl),
2306 getI32Imm(
Bits.size() - BG.StartIdx - 1, dl) };
2307 Res = SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32,
Ops), 0);
2310 { Res, TruncateToInt32(BG.V, dl), getI32Imm(BG.RLAmt, dl),
2311 getI32Imm(
Bits.size() - BG.EndIdx - 1, dl),
2312 getI32Imm(
Bits.size() - BG.StartIdx - 1, dl) };
2313 Res = SDValue(CurDAG->getMachineNode(PPC::RLWIMI, dl, MVT::i32,
Ops), 0);
2318 unsigned Mask = (unsigned) getZerosMask();
2320 unsigned ANDIMask = (
Mask & UINT16_MAX), ANDISMask = Mask >> 16;
2321 assert((ANDIMask != 0 || ANDISMask != 0) &&
2322 "No set bits in zeros mask?");
2324 if (InstCnt) *InstCnt += (unsigned) (ANDIMask != 0) +
2325 (unsigned) (ANDISMask != 0) +
2326 (unsigned) (ANDIMask != 0 && ANDISMask != 0);
2328 SDValue ANDIVal, ANDISVal;
2330 ANDIVal = SDValue(CurDAG->getMachineNode(PPC::ANDI_rec, dl, MVT::i32,
2331 Res, getI32Imm(ANDIMask, dl)),
2335 SDValue(CurDAG->getMachineNode(PPC::ANDIS_rec, dl, MVT::i32, Res,
2336 getI32Imm(ANDISMask, dl)),
2344 Res = SDValue(CurDAG->getMachineNode(PPC::OR, dl, MVT::i32,
2345 ANDIVal, ANDISVal), 0);
2351 unsigned SelectRotMask64Count(
unsigned RLAmt,
bool Repl32,
2352 unsigned MaskStart,
unsigned MaskEnd,
2356 unsigned InstMaskStart = 64 - MaskEnd - 1,
2357 InstMaskEnd = 64 - MaskStart - 1;
2362 if ((!IsIns && (InstMaskEnd == 63 || InstMaskStart == 0)) ||
2363 InstMaskEnd == 63 - RLAmt)
2371 SDValue SelectRotMask64(SDValue V,
const SDLoc &dl,
unsigned RLAmt,
2372 bool Repl32,
unsigned MaskStart,
unsigned MaskEnd,
2373 unsigned *InstCnt =
nullptr) {
2376 unsigned InstMaskStart = 64 - MaskEnd - 1,
2377 InstMaskEnd = 64 - MaskStart - 1;
2379 if (InstCnt) *InstCnt += 1;
2385 assert(InstMaskStart >= 32 &&
"Mask cannot start out of range");
2386 assert(InstMaskEnd >= 32 &&
"Mask cannot end out of range");
2388 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2389 getI32Imm(InstMaskStart - 32, dl), getI32Imm(InstMaskEnd - 32, dl) };
2390 return SDValue(CurDAG->getMachineNode(PPC::RLWINM8, dl, MVT::i64,
2394 if (InstMaskEnd == 63) {
2396 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2397 getI32Imm(InstMaskStart, dl) };
2398 return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl, MVT::i64,
Ops), 0);
2401 if (InstMaskStart == 0) {
2403 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2404 getI32Imm(InstMaskEnd, dl) };
2405 return SDValue(CurDAG->getMachineNode(PPC::RLDICR, dl, MVT::i64,
Ops), 0);
2408 if (InstMaskEnd == 63 - RLAmt) {
2410 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2411 getI32Imm(InstMaskStart, dl) };
2412 return SDValue(CurDAG->getMachineNode(PPC::RLDIC, dl, MVT::i64,
Ops), 0);
2421 if (InstCnt) *InstCnt += 1;
2424 unsigned RLAmt2 = MaskStart;
2427 unsigned RLAmt1 = (64 + RLAmt - RLAmt2) % 64;
2429 V = SelectRotMask64(V, dl, RLAmt1,
false, 0, 63);
2430 return SelectRotMask64(V, dl, RLAmt2,
false, MaskStart, MaskEnd);
2435 SDValue SelectRotMaskIns64(SDValue
Base, SDValue V,
const SDLoc &dl,
2436 unsigned RLAmt,
bool Repl32,
unsigned MaskStart,
2437 unsigned MaskEnd,
unsigned *InstCnt =
nullptr) {
2440 unsigned InstMaskStart = 64 - MaskEnd - 1,
2441 InstMaskEnd = 64 - MaskStart - 1;
2443 if (InstCnt) *InstCnt += 1;
2449 assert(InstMaskStart >= 32 &&
"Mask cannot start out of range");
2450 assert(InstMaskEnd >= 32 &&
"Mask cannot end out of range");
2452 { ExtendToInt64(
Base, dl), ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2453 getI32Imm(InstMaskStart - 32, dl), getI32Imm(InstMaskEnd - 32, dl) };
2454 return SDValue(CurDAG->getMachineNode(PPC::RLWIMI8, dl, MVT::i64,
2458 if (InstMaskEnd == 63 - RLAmt) {
2460 { ExtendToInt64(
Base, dl), ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2461 getI32Imm(InstMaskStart, dl) };
2462 return SDValue(CurDAG->getMachineNode(PPC::RLDIMI, dl, MVT::i64,
Ops), 0);
2471 if (InstCnt) *InstCnt += 1;
2474 unsigned RLAmt2 = MaskStart;
2477 unsigned RLAmt1 = (64 + RLAmt - RLAmt2) % 64;
2479 V = SelectRotMask64(V, dl, RLAmt1,
false, 0, 63);
2480 return SelectRotMaskIns64(
Base, V, dl, RLAmt2,
false, MaskStart, MaskEnd);
2483 void SelectAndParts64(
const SDLoc &dl, SDValue &Res,
unsigned *InstCnt) {
2496 for (ValueRotInfo &VRI : ValueRotsVec) {
2504 auto MatchingBG = [VRI](
const BitGroup &BG) {
2508 unsigned EffRLAmt = BG.RLAmt;
2509 if (!VRI.Repl32 && BG.Repl32) {
2510 if (BG.StartIdx < 32 && BG.EndIdx < 32 && BG.StartIdx <= BG.EndIdx &&
2511 !BG.Repl32Coalesced) {
2517 }
else if (VRI.Repl32 != BG.Repl32) {
2521 return VRI.RLAmt == EffRLAmt;
2524 for (
auto &BG : BitGroups) {
2525 if (!MatchingBG(BG))
2528 if (BG.StartIdx <= BG.EndIdx) {
2529 for (
unsigned i = BG.StartIdx; i <= BG.EndIdx; ++i)
2530 Mask |= (UINT64_C(1) << i);
2532 for (
unsigned i = BG.StartIdx; i <
Bits.size(); ++i)
2533 Mask |= (UINT64_C(1) << i);
2534 for (
unsigned i = 0; i <= BG.EndIdx; ++i)
2535 Mask |= (UINT64_C(1) << i);
2544 unsigned ANDIMask = (
Mask & UINT16_MAX),
2545 ANDISMask = (Mask >> 16) & UINT16_MAX;
2547 bool NeedsRotate = VRI.RLAmt || (VRI.Repl32 && !
isUInt<32>(Mask));
2549 unsigned NumAndInsts = (unsigned) NeedsRotate +
2550 (
unsigned) (bool) Res;
2551 unsigned NumOfSelectInsts = 0;
2553 assert(NumOfSelectInsts > 0 &&
"Failed to select an i64 constant.");
2555 NumAndInsts += (unsigned) (ANDIMask != 0) + (unsigned) (ANDISMask != 0) +
2556 (unsigned) (ANDIMask != 0 && ANDISMask != 0);
2558 NumAndInsts += NumOfSelectInsts + 1;
2560 unsigned NumRLInsts = 0;
2561 bool FirstBG =
true;
2562 bool MoreBG =
false;
2563 for (
auto &BG : BitGroups) {
2564 if (!MatchingBG(BG)) {
2569 SelectRotMask64Count(BG.RLAmt, BG.Repl32, BG.StartIdx, BG.EndIdx,
2574 LLVM_DEBUG(
dbgs() <<
"\t\trotation groups for " << VRI.V.getNode()
2575 <<
" RL: " << VRI.RLAmt << (VRI.Repl32 ?
" (32):" :
":")
2576 <<
"\n\t\t\tisel using masking: " << NumAndInsts
2577 <<
" using rotates: " << NumRLInsts <<
"\n");
2583 if (NumAndInsts > NumRLInsts)
2588 if ((Use32BitInsts || MoreBG) && NumAndInsts == NumRLInsts)
2593 if (InstCnt) *InstCnt += NumAndInsts;
2600 if (VRI.RLAmt || (VRI.Repl32 && !
isUInt<32>(Mask)))
2601 VRot = SelectRotMask64(VRI.V, dl, VRI.RLAmt, VRI.Repl32,
2602 VRI.Repl32 ? 31 : 0, VRI.Repl32 ? 30 : 63);
2607 if (Use32BitInsts) {
2608 assert((ANDIMask != 0 || ANDISMask != 0) &&
2609 "No set bits in mask when using 32-bit ands for 64-bit value");
2611 SDValue ANDIVal, ANDISVal;
2613 ANDIVal = SDValue(CurDAG->getMachineNode(PPC::ANDI8_rec, dl, MVT::i64,
2614 ExtendToInt64(VRot, dl),
2615 getI32Imm(ANDIMask, dl)),
2619 SDValue(CurDAG->getMachineNode(PPC::ANDIS8_rec, dl, MVT::i64,
2620 ExtendToInt64(VRot, dl),
2621 getI32Imm(ANDISMask, dl)),
2625 TotalVal = ANDISVal;
2629 TotalVal = SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64,
2630 ExtendToInt64(ANDIVal, dl), ANDISVal), 0);
2634 SDValue(CurDAG->getMachineNode(PPC::AND8, dl, MVT::i64,
2635 ExtendToInt64(VRot, dl), TotalVal),
2642 Res = SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64,
2643 ExtendToInt64(Res, dl), TotalVal),
2648 eraseMatchingBitGroups(MatchingBG);
2653 SDNode *Select64(SDNode *
N,
bool LateMask,
unsigned *InstCnt) {
2657 if (InstCnt) *InstCnt = 0;
2660 SelectAndParts64(dl, Res, InstCnt);
2665 if ((!NeedMask || LateMask) && !Res) {
2669 unsigned MaxGroupsIdx = 0;
2670 if (!ValueRotsVec[0].Repl32) {
2671 for (
unsigned i = 0, ie = ValueRotsVec.size(); i < ie; ++i)
2672 if (ValueRotsVec[i].Repl32) {
2673 if (ValueRotsVec[i].NumGroups > ValueRotsVec[0].NumGroups)
2679 ValueRotInfo &VRI = ValueRotsVec[MaxGroupsIdx];
2680 bool NeedsRotate =
false;
2683 }
else if (VRI.Repl32) {
2684 for (
auto &BG : BitGroups) {
2685 if (BG.V != VRI.V || BG.RLAmt != VRI.RLAmt ||
2686 BG.Repl32 != VRI.Repl32)
2691 if (BG.StartIdx < 32 && BG.EndIdx < 32 && BG.StartIdx < BG.EndIdx)
2700 Res = SelectRotMask64(VRI.V, dl, VRI.RLAmt, VRI.Repl32,
2701 VRI.Repl32 ? 31 : 0, VRI.Repl32 ? 30 : 63,
2708 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
2709 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt &&
2710 BG.Repl32 == VRI.Repl32;
2717 for (
auto I = BitGroups.begin(), IE = BitGroups.end();
I != IE; ++
I) {
2718 if (SelectRotMask64Count(
I->RLAmt,
I->Repl32,
I->StartIdx,
I->EndIdx,
2720 SelectRotMask64Count(
I->RLAmt,
I->Repl32,
I->StartIdx,
I->EndIdx,
2722 if (
I != BitGroups.begin()) {
2725 BitGroups.insert(BitGroups.begin(), BG);
2733 for (
auto &BG : BitGroups) {
2735 Res = SelectRotMask64(BG.V, dl, BG.RLAmt, BG.Repl32, BG.StartIdx,
2736 BG.EndIdx, InstCnt);
2738 Res = SelectRotMaskIns64(Res, BG.V, dl, BG.RLAmt, BG.Repl32,
2739 BG.StartIdx, BG.EndIdx, InstCnt);
2750 unsigned ANDIMask = (
Mask & UINT16_MAX),
2751 ANDISMask = (Mask >> 16) & UINT16_MAX;
2753 if (Use32BitInsts) {
2754 assert((ANDIMask != 0 || ANDISMask != 0) &&
2755 "No set bits in mask when using 32-bit ands for 64-bit value");
2757 if (InstCnt) *InstCnt += (unsigned) (ANDIMask != 0) +
2758 (unsigned) (ANDISMask != 0) +
2759 (unsigned) (ANDIMask != 0 && ANDISMask != 0);
2761 SDValue ANDIVal, ANDISVal;
2763 ANDIVal = SDValue(CurDAG->getMachineNode(PPC::ANDI8_rec, dl, MVT::i64,
2764 ExtendToInt64(Res, dl),
2765 getI32Imm(ANDIMask, dl)),
2769 SDValue(CurDAG->getMachineNode(PPC::ANDIS8_rec, dl, MVT::i64,
2770 ExtendToInt64(Res, dl),
2771 getI32Imm(ANDISMask, dl)),
2779 Res = SDValue(CurDAG->getMachineNode(PPC::OR8, dl, MVT::i64,
2780 ExtendToInt64(ANDIVal, dl), ANDISVal), 0);
2782 unsigned NumOfSelectInsts = 0;
2784 SDValue(
selectI64Imm(CurDAG, dl, Mask, &NumOfSelectInsts), 0);
2785 Res = SDValue(CurDAG->getMachineNode(PPC::AND8, dl, MVT::i64,
2786 ExtendToInt64(Res, dl), MaskVal),
2789 *InstCnt += NumOfSelectInsts + 1;
2796 SDNode *
Select(SDNode *
N,
bool LateMask,
unsigned *InstCnt =
nullptr) {
2798 collectBitGroups(LateMask);
2799 if (BitGroups.empty())
2803 if (
Bits.size() == 64)
2804 assignRepl32BitGroups();
2807 collectValueRotInfo();
2809 if (
Bits.size() == 32) {
2810 return Select32(
N, LateMask, InstCnt);
2812 assert(
Bits.size() == 64 &&
"Not 64 bits here?");
2813 return Select64(
N, LateMask, InstCnt);
2819 void eraseMatchingBitGroups(function_ref<
bool(
const BitGroup &)>
F) {
2830 DenseMap<std::pair<SDValue, unsigned>, ValueRotInfo> ValueRots;
2833 SelectionDAG *CurDAG =
nullptr;
2836 BitPermutationSelector(SelectionDAG *DAG)
2845 getValueBits(SDValue(
N, 0),
N->getValueType(0).getSizeInBits());
2850 LLVM_DEBUG(
dbgs() <<
"Considering bit-permutation-based instruction"
2851 " selection for: ");
2855 computeRotationAmounts();
2868 unsigned InstCnt = 0, InstCntLateMask = 0;
2870 SDNode *
RN =
Select(
N,
false, &InstCnt);
2871 LLVM_DEBUG(
dbgs() <<
"\t\tisel would use " << InstCnt <<
" instructions\n");
2874 SDNode *RNLM =
Select(
N,
true, &InstCntLateMask);
2876 <<
" instructions\n");
2878 if (InstCnt <= InstCntLateMask) {
2888class IntegerCompareEliminator {
2889 SelectionDAG *CurDAG;
2893 enum ExtOrTruncConversion { Ext, Trunc };
2901 enum SetccInGPROpts { ZExtOrig, ZExtInvert, SExtOrig, SExtInvert };
2911 enum ZeroCompare { GEZExt, GESExt, LEZExt, LESExt };
2913 SDNode *tryEXTEND(SDNode *
N);
2914 SDNode *tryLogicOpOfCompares(SDNode *
N);
2915 SDValue computeLogicOpInGPR(SDValue LogicOp);
2916 SDValue signExtendInputIfNeeded(SDValue Input);
2917 SDValue zeroExtendInputIfNeeded(SDValue Input);
2918 SDValue addExtOrTrunc(SDValue NatWidthRes, ExtOrTruncConversion Conv);
2919 SDValue getCompoundZeroComparisonInGPR(SDValue
LHS, SDLoc dl,
2922 int64_t RHSValue, SDLoc dl);
2924 int64_t RHSValue, SDLoc dl);
2926 int64_t RHSValue, SDLoc dl);
2928 int64_t RHSValue, SDLoc dl);
2929 SDValue getSETCCInGPR(SDValue Compare, SetccInGPROpts ConvOpts);
2932 IntegerCompareEliminator(SelectionDAG *DAG,
2933 PPCDAGToDAGISel *Sel) : CurDAG(DAG), S(Sel) {
2936 "Only expecting to use this on 64 bit targets.");
2941 switch (
N->getOpcode()) {
2952 return tryEXTEND(
N);
2956 return tryLogicOpOfCompares(
N);
2964SDNode *IntegerCompareEliminator::tryEXTEND(SDNode *
N) {
2967 "Expecting a zero/sign extend node!");
2972 N->getOperand(0).getValueType() == MVT::i1 &&
2974 WideRes = computeLogicOpInGPR(
N->getOperand(0));
2975 else if (
N->getOperand(0).getOpcode() !=
ISD::SETCC)
2979 getSETCCInGPR(
N->getOperand(0),
2981 SetccInGPROpts::SExtOrig : SetccInGPROpts::ZExtOrig);
2987 bool Output32Bit =
N->getValueType(0) == MVT::i32;
2992 SDValue ConvOp = WideRes;
2993 if (Input32Bit != Output32Bit)
2994 ConvOp = addExtOrTrunc(WideRes, Input32Bit ? ExtOrTruncConversion::Ext :
2995 ExtOrTruncConversion::Trunc);
3003SDNode *IntegerCompareEliminator::tryLogicOpOfCompares(SDNode *
N) {
3004 if (
N->getValueType(0) != MVT::i1)
3007 "Expected a logic operation on setcc results.");
3008 SDValue LoweredLogical = computeLogicOpInGPR(SDValue(
N, 0));
3009 if (!LoweredLogical)
3014 unsigned SubRegToExtract = IsBitwiseNegate ? PPC::sub_eq : PPC::sub_gt;
3015 SDValue CR0Reg = CurDAG->
getRegister(PPC::CR0, MVT::i32);
3019 SDValue OpToConvToRecForm;
3023 if (IsBitwiseNegate &&
3026 else if (IsBitwiseNegate)
3028 OpToConvToRecForm = LoweredLogical.
getOperand(0);
3032 OpToConvToRecForm = LoweredLogical;
3042 if (NewOpc != -1 && IsBitwiseNegate) {
3045 "Expected a PPC::XORI8 only for bitwise negation.");
3047 std::vector<SDValue>
Ops;
3048 for (
int i = 0, e = OpToConvToRecForm.
getNumOperands(); i < e; i++)
3054 MVT::Glue,
Ops), 0);
3056 assert((NewOpc != -1 || !IsBitwiseNegate) &&
3057 "No record form available for AND8/OR8/XOR8?");
3059 SDValue(CurDAG->
getMachineNode(NewOpc == -1 ? PPC::ANDI8_rec : NewOpc,
3060 dl, MVT::i64, MVT::Glue,
LHS,
RHS),
3072 MVT::i1, CR0Reg, SRIdxVal,
3085SDValue IntegerCompareEliminator::computeLogicOpInGPR(SDValue LogicOp) {
3087 "Can only handle logic operations here.");
3089 "Can only handle logic operations on i1 values here.");
3100 auto getLogicOperand = [&] (SDValue Operand) -> SDValue {
3101 unsigned OperandOpcode = Operand.getOpcode();
3103 return getSETCCInGPR(Operand, SetccInGPROpts::ZExtOrig);
3105 SDValue InputOp = Operand.getOperand(0);
3107 return SDValue(CurDAG->
getMachineNode(InVT == MVT::i32 ? PPC::RLDICL_32 :
3108 PPC::RLDICL, dl, InVT, InputOp,
3109 S->getI64Imm(0, dl),
3110 S->getI64Imm(63, dl)), 0);
3112 return computeLogicOpInGPR(Operand);
3121 if (!
LHS || (!
RHS && !IsBitwiseNegation))
3124 NumLogicOpsOnComparison++;
3127 if (
LHS.getValueType() == MVT::i32)
3128 LHS = addExtOrTrunc(
LHS, ExtOrTruncConversion::Ext);
3129 if (!IsBitwiseNegation &&
RHS.getValueType() == MVT::i32)
3130 RHS = addExtOrTrunc(
RHS, ExtOrTruncConversion::Ext);
3135 case ISD::AND: NewOpc = PPC::AND8;
break;
3136 case ISD::OR: NewOpc = PPC::OR8;
break;
3137 case ISD::XOR: NewOpc = PPC::XOR8;
break;
3140 if (IsBitwiseNegation) {
3141 RHS = S->getI64Imm(1, dl);
3142 NewOpc = PPC::XORI8;
3153SDValue IntegerCompareEliminator::signExtendInputIfNeeded(SDValue Input) {
3155 "Can only sign-extend 32-bit values here.");
3163 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3169 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3174 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3177 SignExtensionsAdded++;
3179 MVT::i64, Input), 0);
3186SDValue IntegerCompareEliminator::zeroExtendInputIfNeeded(SDValue Input) {
3188 "Can only zero-extend 32-bit values here.");
3198 if (IsTruncateOfZExt)
3199 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3203 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3208 return addExtOrTrunc(Input, ExtOrTruncConversion::Ext);
3212 ZeroExtensionsAdded++;
3213 return SDValue(CurDAG->
getMachineNode(PPC::RLDICL_32_64, dl, MVT::i64, Input,
3214 S->getI64Imm(0, dl),
3215 S->getI64Imm(32, dl)), 0);
3222SDValue IntegerCompareEliminator::addExtOrTrunc(SDValue NatWidthRes,
3223 ExtOrTruncConversion Conv) {
3224 SDLoc dl(NatWidthRes);
3228 if (Conv == ExtOrTruncConversion::Ext) {
3229 SDValue ImDef(CurDAG->
getMachineNode(PPC::IMPLICIT_DEF, dl, MVT::i64), 0);
3232 return SDValue(CurDAG->
getMachineNode(PPC::INSERT_SUBREG, dl, MVT::i64,
3233 ImDef, NatWidthRes, SubRegIdx), 0);
3236 assert(Conv == ExtOrTruncConversion::Trunc &&
3237 "Unknown convertion between 32 and 64 bit values.");
3242 return SDValue(CurDAG->
getMachineNode(PPC::EXTRACT_SUBREG, dl, MVT::i32,
3243 NatWidthRes, SubRegIdx), 0);
3249IntegerCompareEliminator::getCompoundZeroComparisonInGPR(SDValue
LHS, SDLoc dl,
3250 ZeroCompare CmpTy) {
3251 EVT InVT =
LHS.getValueType();
3252 bool Is32Bit = InVT == MVT::i32;
3257 case ZeroCompare::GEZExt:
3258 case ZeroCompare::GESExt:
3259 ToExtend = SDValue(CurDAG->
getMachineNode(Is32Bit ? PPC::NOR : PPC::NOR8,
3262 case ZeroCompare::LEZExt:
3263 case ZeroCompare::LESExt: {
3266 LHS = signExtendInputIfNeeded(
LHS);
3271 Neg, S->getI64Imm(1, dl),
3272 S->getI64Imm(63, dl)), 0);
3276 S->getI64Imm(~0ULL, dl)), 0);
3277 ToExtend = SDValue(CurDAG->
getMachineNode(PPC::OR8, dl, MVT::i64,
3286 (CmpTy == ZeroCompare::GEZExt || CmpTy == ZeroCompare::LEZExt))
3288 ToExtend, S->getI64Imm(1, dl),
3289 S->getI64Imm(63, dl)), 0);
3291 (CmpTy == ZeroCompare::GESExt || CmpTy == ZeroCompare::LESExt))
3292 return SDValue(CurDAG->
getMachineNode(PPC::SRADI, dl, MVT::i64, ToExtend,
3293 S->getI64Imm(63, dl)), 0);
3295 assert(Is32Bit &&
"Should have handled the 32-bit sequences above.");
3298 case ZeroCompare::GEZExt: {
3299 SDValue ShiftOps[] = { ToExtend, S->getI32Imm(1, dl), S->getI32Imm(31, dl),
3300 S->getI32Imm(31, dl) };
3304 case ZeroCompare::GESExt:
3305 return SDValue(CurDAG->
getMachineNode(PPC::SRAWI, dl, MVT::i32, ToExtend,
3306 S->getI32Imm(31, dl)), 0);
3307 case ZeroCompare::LEZExt:
3308 return SDValue(CurDAG->
getMachineNode(PPC::XORI8, dl, MVT::i64, ToExtend,
3309 S->getI32Imm(1, dl)), 0);
3310 case ZeroCompare::LESExt:
3311 return SDValue(CurDAG->
getMachineNode(PPC::ADDI8, dl, MVT::i64, ToExtend,
3312 S->getI32Imm(-1, dl)), 0);
3323IntegerCompareEliminator::get32BitZExtCompare(SDValue
LHS, SDValue
RHS,
3325 int64_t RHSValue, SDLoc dl) {
3329 bool IsRHSZero = RHSValue == 0;
3330 bool IsRHSOne = RHSValue == 1;
3331 bool IsRHSNegOne = RHSValue == -1LL;
3333 default:
return SDValue();
3337 SDValue
Xor = IsRHSZero ?
LHS :
3341 SDValue ShiftOps[] = { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl),
3342 S->getI32Imm(31, dl) };
3349 SDValue
Xor = IsRHSZero ?
LHS :
3353 SDValue ShiftOps[] = { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl),
3354 S->getI32Imm(31, dl) };
3356 SDValue(CurDAG->
getMachineNode(PPC::RLWINM, dl, MVT::i32, ShiftOps), 0);
3357 return SDValue(CurDAG->
getMachineNode(PPC::XORI, dl, MVT::i32, Shift,
3358 S->getI32Imm(1, dl)), 0);
3364 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GEZExt);
3370 IsRHSZero = RHSConst && RHSConst->
isZero();
3381 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LEZExt);
3385 LHS = signExtendInputIfNeeded(
LHS);
3386 RHS = signExtendInputIfNeeded(
RHS);
3391 S->getI64Imm(1, dl), S->getI64Imm(63, dl)),
3395 MVT::i64, Shift, S->getI32Imm(1, dl)), 0);
3403 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GEZExt);
3409 LHS = signExtendInputIfNeeded(
LHS);
3410 RHS = signExtendInputIfNeeded(
RHS);
3414 Neg, S->getI32Imm(1, dl), S->getI32Imm(63, dl)), 0);
3420 IsRHSZero = RHSConst && RHSConst->
isZero();
3432 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LEZExt);
3436 SDValue ShiftOps[] = {
LHS, S->getI32Imm(1, dl), S->getI32Imm(31, dl),
3437 S->getI32Imm(31, dl) };
3445 LHS = signExtendInputIfNeeded(
LHS);
3446 RHS = signExtendInputIfNeeded(
RHS);
3450 SUBFNode, S->getI64Imm(1, dl),
3451 S->getI64Imm(63, dl)), 0);
3462 LHS = zeroExtendInputIfNeeded(
LHS);
3463 RHS = zeroExtendInputIfNeeded(
RHS);
3468 Subtract, S->getI64Imm(1, dl),
3469 S->getI64Imm(63, dl)), 0);
3470 return SDValue(CurDAG->
getMachineNode(PPC::XORI8, dl, MVT::i64, SrdiNode,
3471 S->getI32Imm(1, dl)), 0);
3482 LHS = zeroExtendInputIfNeeded(
LHS);
3483 RHS = zeroExtendInputIfNeeded(
RHS);
3487 Subtract, S->getI64Imm(1, dl),
3488 S->getI64Imm(63, dl)), 0);
3496IntegerCompareEliminator::get32BitSExtCompare(SDValue
LHS, SDValue
RHS,
3498 int64_t RHSValue, SDLoc dl) {
3502 bool IsRHSZero = RHSValue == 0;
3503 bool IsRHSOne = RHSValue == 1;
3504 bool IsRHSNegOne = RHSValue == -1LL;
3507 default:
return SDValue();
3513 SDValue CountInput = IsRHSZero ?
LHS :
3516 SDValue(CurDAG->
getMachineNode(PPC::CNTLZW, dl, MVT::i32, CountInput), 0);
3517 SDValue SHLOps[] = { Cntlzw, S->getI32Imm(27, dl),
3518 S->getI32Imm(5, dl), S->getI32Imm(31, dl) };
3520 SDValue(CurDAG->
getMachineNode(PPC::RLWINM, dl, MVT::i32, SHLOps), 0);
3521 return SDValue(CurDAG->
getMachineNode(PPC::NEG, dl, MVT::i32, Slwi), 0);
3531 SDValue
Xor = IsRHSZero ?
LHS :
3535 SDValue ShiftOps[] =
3536 { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl), S->getI32Imm(31, dl) };
3538 SDValue(CurDAG->
getMachineNode(PPC::RLWINM, dl, MVT::i32, ShiftOps), 0);
3541 S->getI32Imm(1, dl)), 0);
3542 return SDValue(CurDAG->
getMachineNode(PPC::NEG, dl, MVT::i32, Xori), 0);
3548 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GESExt);
3554 IsRHSZero = RHSConst && RHSConst->
isZero();
3563 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LESExt);
3566 LHS = signExtendInputIfNeeded(
LHS);
3567 RHS = signExtendInputIfNeeded(
RHS);
3569 SDValue(CurDAG->
getMachineNode(PPC::SUBF8, dl, MVT::i64, MVT::Glue,
3573 SUBFNode, S->getI64Imm(1, dl),
3574 S->getI64Imm(63, dl)), 0);
3575 return SDValue(CurDAG->
getMachineNode(PPC::ADDI8, dl, MVT::i64, Srdi,
3576 S->getI32Imm(-1, dl)), 0);
3583 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GESExt);
3588 LHS = signExtendInputIfNeeded(
LHS);
3589 RHS = signExtendInputIfNeeded(
RHS);
3592 return SDValue(CurDAG->
getMachineNode(PPC::SRADI, dl, MVT::i64, Neg,
3593 S->getI64Imm(63, dl)), 0);
3599 IsRHSZero = RHSConst && RHSConst->
isZero();
3610 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LESExt);
3614 S->getI32Imm(31, dl)), 0);
3619 LHS = signExtendInputIfNeeded(
LHS);
3620 RHS = signExtendInputIfNeeded(
RHS);
3624 SUBFNode, S->getI64Imm(63, dl)), 0);
3635 LHS = zeroExtendInputIfNeeded(
LHS);
3636 RHS = zeroExtendInputIfNeeded(
RHS);
3640 SDValue(CurDAG->
getMachineNode(PPC::RLDICL, dl, MVT::i64, Subtract,
3641 S->getI32Imm(1, dl), S->getI32Imm(63,dl)),
3643 return SDValue(CurDAG->
getMachineNode(PPC::ADDI8, dl, MVT::i64, Shift,
3644 S->getI32Imm(-1, dl)), 0);
3655 LHS = zeroExtendInputIfNeeded(
LHS);
3656 RHS = zeroExtendInputIfNeeded(
RHS);
3660 Subtract, S->getI64Imm(63, dl)), 0);
3668IntegerCompareEliminator::get64BitZExtCompare(SDValue
LHS, SDValue
RHS,
3670 int64_t RHSValue, SDLoc dl) {
3674 bool IsRHSZero = RHSValue == 0;
3675 bool IsRHSOne = RHSValue == 1;
3676 bool IsRHSNegOne = RHSValue == -1LL;
3678 default:
return SDValue();
3682 SDValue
Xor = IsRHSZero ?
LHS :
3686 return SDValue(CurDAG->
getMachineNode(PPC::RLDICL, dl, MVT::i64, Clz,
3687 S->getI64Imm(58, dl),
3688 S->getI64Imm(63, dl)), 0);
3695 SDValue
Xor = IsRHSZero ?
LHS :
3698 SDValue(CurDAG->
getMachineNode(PPC::ADDIC8, dl, MVT::i64, MVT::Glue,
3699 Xor, S->getI32Imm(~0U, dl)), 0);
3700 return SDValue(CurDAG->
getMachineNode(PPC::SUBFE8, dl, MVT::i64, AC,
3709 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GEZExt);
3712 IsRHSZero = RHSConst && RHSConst->
isZero();
3721 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LEZExt);
3724 S->getI64Imm(1, dl),
3725 S->getI64Imm(63, dl)), 0);
3728 S->getI64Imm(63, dl)), 0);
3729 SDValue SubtractCarry =
3730 SDValue(CurDAG->
getMachineNode(PPC::SUBFC8, dl, MVT::i64, MVT::Glue,
3732 return SDValue(CurDAG->
getMachineNode(PPC::ADDE8, dl, MVT::i64, MVT::Glue,
3733 ShiftR, ShiftL, SubtractCarry), 0);
3741 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GEZExt);
3745 S->getI64Imm(~0ULL, dl)), 0);
3748 return SDValue(CurDAG->
getMachineNode(PPC::RLDICL, dl, MVT::i64, Nor,
3749 S->getI64Imm(1, dl),
3750 S->getI64Imm(63, dl)), 0);
3754 IsRHSZero = RHSConst && RHSConst->
isZero();
3764 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LEZExt);
3767 S->getI64Imm(1, dl),
3768 S->getI64Imm(63, dl)), 0);
3771 LHS, S->getI64Imm(63, dl)), 0);
3774 RHS, S->getI64Imm(1, dl),
3775 S->getI64Imm(63, dl)), 0);
3776 SDValue SUBFC8Carry =
3777 SDValue(CurDAG->
getMachineNode(PPC::SUBFC8, dl, MVT::i64, MVT::Glue,
3780 SDValue(CurDAG->
getMachineNode(PPC::ADDE8, dl, MVT::i64, MVT::Glue,
3781 SRDINode, SRADINode, SUBFC8Carry), 0);
3783 ADDE8Node, S->getI64Imm(1, dl)), 0);
3793 SDValue SUBFC8Carry =
3794 SDValue(CurDAG->
getMachineNode(PPC::SUBFC8, dl, MVT::i64, MVT::Glue,
3796 SDValue SUBFE8Node =
3797 SDValue(CurDAG->
getMachineNode(PPC::SUBFE8, dl, MVT::i64, MVT::Glue,
3798 LHS,
LHS, SUBFC8Carry), 0);
3800 SUBFE8Node, S->getI64Imm(1, dl)), 0);
3810 SDValue SubtractCarry =
3811 SDValue(CurDAG->
getMachineNode(PPC::SUBFC8, dl, MVT::i64, MVT::Glue,
3815 LHS,
LHS, SubtractCarry), 0);
3825IntegerCompareEliminator::get64BitSExtCompare(SDValue
LHS, SDValue
RHS,
3827 int64_t RHSValue, SDLoc dl) {
3831 bool IsRHSZero = RHSValue == 0;
3832 bool IsRHSOne = RHSValue == 1;
3833 bool IsRHSNegOne = RHSValue == -1LL;
3835 default:
return SDValue();
3841 SDValue AddInput = IsRHSZero ?
LHS :
3844 SDValue(CurDAG->
getMachineNode(PPC::ADDIC8, dl, MVT::i64, MVT::Glue,
3845 AddInput, S->getI32Imm(~0U, dl)), 0);
3846 return SDValue(CurDAG->
getMachineNode(PPC::SUBFE8, dl, MVT::i64, Addic,
3854 SDValue
Xor = IsRHSZero ?
LHS :
3857 SDValue(CurDAG->
getMachineNode(PPC::SUBFIC8, dl, MVT::i64, MVT::Glue,
3858 Xor, S->getI32Imm(0, dl)), 0);
3859 return SDValue(CurDAG->
getMachineNode(PPC::SUBFE8, dl, MVT::i64, SC,
3868 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GESExt);
3871 IsRHSZero = RHSConst && RHSConst->
isZero();
3880 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LESExt);
3883 S->getI64Imm(63, dl)), 0);
3886 S->getI64Imm(1, dl),
3887 S->getI64Imm(63, dl)), 0);
3888 SDValue SubtractCarry =
3889 SDValue(CurDAG->
getMachineNode(PPC::SUBFC8, dl, MVT::i64, MVT::Glue,
3892 SDValue(CurDAG->
getMachineNode(PPC::ADDE8, dl, MVT::i64, MVT::Glue,
3893 ShiftR, ShiftL, SubtractCarry), 0);
3894 return SDValue(CurDAG->
getMachineNode(PPC::NEG8, dl, MVT::i64, Adde), 0);
3902 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::GESExt);
3906 S->getI64Imm(-1, dl)), 0);
3909 return SDValue(CurDAG->
getMachineNode(PPC::SRADI, dl, MVT::i64, Nor,
3910 S->getI64Imm(63, dl)), 0);
3914 IsRHSZero = RHSConst && RHSConst->
isZero();
3924 return getCompoundZeroComparisonInGPR(
LHS, dl, ZeroCompare::LESExt);
3927 S->getI64Imm(63, dl)), 0);
3931 LHS, S->getI64Imm(63, dl)), 0);
3934 RHS, S->getI64Imm(1, dl),
3935 S->getI64Imm(63, dl)), 0);
3936 SDValue SUBFC8Carry =
3937 SDValue(CurDAG->
getMachineNode(PPC::SUBFC8, dl, MVT::i64, MVT::Glue,
3941 SRDINode, SRADINode, SUBFC8Carry), 0);
3944 ADDE8Node, S->getI64Imm(1, dl)), 0);
3956 SDValue SubtractCarry =
3957 SDValue(CurDAG->
getMachineNode(PPC::SUBFC8, dl, MVT::i64, MVT::Glue,
3961 LHS, SubtractCarry), 0);
3963 ExtSub, ExtSub), 0);
3974 SDValue(CurDAG->
getMachineNode(PPC::SUBFC8, dl, MVT::i64, MVT::Glue,
3986static bool allUsesExtend(SDValue Compare, SelectionDAG *CurDAG) {
3988 "An ISD::SETCC node required here.");
3996 for (
auto *CompareUse :
Compare.getNode()->users())
4001 OmittedForNonExtendUses++;
4010SDValue IntegerCompareEliminator::getSETCCInGPR(SDValue Compare,
4011 SetccInGPROpts ConvOpts) {
4014 "An ISD::SETCC node required here.");
4028 EVT InputVT =
LHS.getValueType();
4029 if (InputVT != MVT::i32 && InputVT != MVT::i64)
4032 if (ConvOpts == SetccInGPROpts::ZExtInvert ||
4033 ConvOpts == SetccInGPROpts::SExtInvert)
4036 bool Inputs32Bit = InputVT == MVT::i32;
4041 bool IsSext = ConvOpts == SetccInGPROpts::SExtOrig ||
4042 ConvOpts == SetccInGPROpts::SExtInvert;
4044 if (IsSext && Inputs32Bit)
4045 return get32BitSExtCompare(
LHS,
RHS, CC, RHSValue, dl);
4046 else if (Inputs32Bit)
4047 return get32BitZExtCompare(
LHS,
RHS, CC, RHSValue, dl);
4049 return get64BitSExtCompare(
LHS,
RHS, CC, RHSValue, dl);
4050 return get64BitZExtCompare(
LHS,
RHS, CC, RHSValue, dl);
4055bool PPCDAGToDAGISel::tryIntCompareInGPR(SDNode *
N) {
4056 if (
N->getValueType(0) != MVT::i32 &&
4057 N->getValueType(0) != MVT::i64)
4069 if (!(
CmpInGPR.getNumOccurrences() > 0) && Subtarget->isISA3_1())
4072 switch (
N->getOpcode()) {
4079 IntegerCompareEliminator ICmpElim(CurDAG,
this);
4080 if (SDNode *New = ICmpElim.Select(
N)) {
4081 ReplaceNode(
N, New);
4089bool PPCDAGToDAGISel::tryBitPermutation(SDNode *
N) {
4090 if (
N->getValueType(0) != MVT::i32 &&
4091 N->getValueType(0) != MVT::i64)
4097 switch (
N->getOpcode()) {
4102 if (Subtarget->isISA3_1() &&
N->getValueType(0) == MVT::i32 &&
4104 auto &OpRight =
N->getOperand(1);
4114 BitPermutationSelector BPS(CurDAG);
4115 if (SDNode *New = BPS.Select(
N)) {
4116 ReplaceNode(
N, New);
4129 const SDLoc &dl, SDValue Chain) {
4133 if (
LHS.getValueType() == MVT::i32) {
4140 getI32Imm(
Imm & 0xFFFF, dl)),
4145 getI32Imm(
Imm & 0xFFFF, dl)),
4158 getI32Imm(
Imm >> 16, dl)), 0);
4160 getI32Imm(
Imm & 0xFFFF, dl)), 0);
4166 getI32Imm(
Imm & 0xFFFF, dl)), 0);
4172 getI32Imm((
int)SImm & 0xFFFF,
4177 }
else if (
LHS.getValueType() == MVT::i64) {
4184 getI32Imm(
Imm & 0xFFFF, dl)),
4189 getI32Imm(
Imm & 0xFFFF, dl)),
4203 getI64Imm(
Imm >> 16, dl)), 0);
4205 getI64Imm(
Imm & 0xFFFF, dl)),
4213 getI64Imm(
Imm & 0xFFFF, dl)), 0);
4219 getI64Imm(SImm & 0xFFFF, dl)),
4223 }
else if (
LHS.getValueType() == MVT::f32) {
4224 if (Subtarget->hasSPE()) {
4229 Opc = PPC::EFSCMPEQ;
4237 Opc = PPC::EFSCMPLT;
4245 Opc = PPC::EFSCMPGT;
4250 }
else if (
LHS.getValueType() == MVT::f64) {
4251 if (Subtarget->hasSPE()) {
4256 Opc = PPC::EFDCMPEQ;
4264 Opc = PPC::EFDCMPLT;
4272 Opc = PPC::EFDCMPGT;
4276 Opc = Subtarget->hasVSX() ? PPC::XSCMPUDP : PPC::FCMPUD;
4278 assert(
LHS.getValueType() == MVT::f128 &&
"Unknown vt!");
4279 assert(Subtarget->hasP9Vector() &&
"XSCMPUQP requires Power9 Vector");
4280 Opc = PPC::XSCMPUQP;
4348 case ISD::SETO: Invert =
true;
return 3;
4365 bool HasVSX,
bool &
Swap,
bool &Negate) {
4392 if (VecVT == MVT::v4f32)
4393 return HasVSX ? PPC::XVCMPEQSP : PPC::VCMPEQFP;
4394 else if (VecVT == MVT::v2f64)
4395 return PPC::XVCMPEQDP;
4399 if (VecVT == MVT::v4f32)
4400 return HasVSX ? PPC::XVCMPGTSP : PPC::VCMPGTFP;
4401 else if (VecVT == MVT::v2f64)
4402 return PPC::XVCMPGTDP;
4406 if (VecVT == MVT::v4f32)
4407 return HasVSX ? PPC::XVCMPGESP : PPC::VCMPGEFP;
4408 else if (VecVT == MVT::v2f64)
4409 return PPC::XVCMPGEDP;
4436 if (VecVT == MVT::v16i8)
4437 return PPC::VCMPEQUB;
4438 else if (VecVT == MVT::v8i16)
4439 return PPC::VCMPEQUH;
4440 else if (VecVT == MVT::v4i32)
4441 return PPC::VCMPEQUW;
4442 else if (VecVT == MVT::v2i64)
4443 return PPC::VCMPEQUD;
4444 else if (VecVT == MVT::v1i128)
4445 return PPC::VCMPEQUQ;
4448 if (VecVT == MVT::v16i8)
4449 return PPC::VCMPGTSB;
4450 else if (VecVT == MVT::v8i16)
4451 return PPC::VCMPGTSH;
4452 else if (VecVT == MVT::v4i32)
4453 return PPC::VCMPGTSW;
4454 else if (VecVT == MVT::v2i64)
4455 return PPC::VCMPGTSD;
4456 else if (VecVT == MVT::v1i128)
4457 return PPC::VCMPGTSQ;
4460 if (VecVT == MVT::v16i8)
4461 return PPC::VCMPGTUB;
4462 else if (VecVT == MVT::v8i16)
4463 return PPC::VCMPGTUH;
4464 else if (VecVT == MVT::v4i32)
4465 return PPC::VCMPGTUW;
4466 else if (VecVT == MVT::v2i64)
4467 return PPC::VCMPGTUD;
4468 else if (VecVT == MVT::v1i128)
4469 return PPC::VCMPGTUQ;
4478bool PPCDAGToDAGISel::trySETCC(SDNode *
N) {
4481 bool IsStrict =
N->isStrictFPOpcode();
4486 bool isPPC64 = (PtrVT == MVT::i64);
4487 SDValue Chain = IsStrict ?
N->getOperand(0) : SDValue();
4489 SDValue
LHS =
N->getOperand(IsStrict ? 1 : 0);
4490 SDValue
RHS =
N->getOperand(IsStrict ? 2 : 1);
4502 SDValue
Ops[] = {
Op, getI32Imm(27, dl), getI32Imm(5, dl),
4503 getI32Imm(31, dl) };
4510 SDValue(CurDAG->
getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Glue,
4511 Op, getI32Imm(~0U, dl)), 0);
4516 SDValue
Ops[] = {
Op, getI32Imm(1, dl), getI32Imm(31, dl),
4517 getI32Imm(31, dl) };
4525 SDValue
Ops[] = {
T, getI32Imm(1, dl), getI32Imm(31, dl),
4526 getI32Imm(31, dl) };
4531 }
else if (
Imm == ~0U) {
4538 Op, getI32Imm(1, dl)), 0);
4543 0),
Op.getValue(1));
4548 SDNode *AD = CurDAG->
getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Glue,
4549 Op, getI32Imm(~0U, dl));
4556 getI32Imm(1, dl)), 0);
4557 SDValue AN = SDValue(CurDAG->
getMachineNode(PPC::AND, dl, MVT::i32, AD,
4559 SDValue
Ops[] = { AN, getI32Imm(1, dl), getI32Imm(31, dl),
4560 getI32Imm(31, dl) };
4565 SDValue
Ops[] = {
Op, getI32Imm(1, dl), getI32Imm(31, dl),
4566 getI32Imm(31, dl) };
4577 if (!IsStrict &&
LHS.getValueType().isVector()) {
4578 if (Subtarget->hasSPE())
4581 EVT VecVT =
LHS.getValueType();
4597 unsigned int VCmpInst =
4605 CurDAG->
SelectNodeTo(
N, Subtarget->hasVSX() ? PPC::XXLNOR : PPC::VNOR,
4614 if (Subtarget->useCRBits())
4619 SDValue CCReg = SelectCC(
LHS,
RHS, CC, dl, Chain);
4626 if (Subtarget->hasSPE() &&
LHS.getValueType().isFloatingPoint()) {
4631 SDValue CR7Reg = CurDAG->
getRegister(PPC::CR7, MVT::i32);
4637 IntCR = SDValue(CurDAG->
getMachineNode(PPC::MFOCRF, dl, MVT::i32, CR7Reg,
4640 SDValue
Ops[] = { IntCR, getI32Imm((32 - (3 - Idx)) & 31, dl),
4641 getI32Imm(31, dl), getI32Imm(31, dl) };
4650 CurDAG->
SelectNodeTo(
N, PPC::XORI, MVT::i32, Tmp, getI32Imm(1, dl));
4656bool PPCDAGToDAGISel::isOffsetMultipleOf(SDNode *
N,
unsigned Val)
const {
4661 if (LDN || (MIN &&
MIN->getOpcode() == PPCISD::LD_SPLAT))
4677 if ((SlotAlign % Val) != 0)
4692void PPCDAGToDAGISel::transferMemOperands(SDNode *
N, SDNode *Result) {
4699 bool &NeedSwapOps,
bool &IsUnCmp) {
4705 SDValue TrueRes =
N->getOperand(2);
4706 SDValue FalseRes =
N->getOperand(3);
4708 if (!TrueConst || (
N->getSimpleValueType(0) != MVT::i64 &&
4709 N->getSimpleValueType(0) != MVT::i32))
4718 if ((TrueResVal < -1 || TrueResVal > 1) ||
4755 if (!SelCCTrueConst || !SelCCFalseConst)
4760 if (SelCCTVal == -1 && SelCCFVal == 1) {
4762 }
else if (SelCCTVal != 1 || SelCCFVal != -1)
4772 bool InnerSwapped =
false;
4773 if (
LHS == InnerRHS &&
RHS == InnerLHS)
4774 InnerSwapped =
true;
4775 else if (
LHS != InnerLHS ||
RHS != InnerRHS)
4786 NeedSwapOps = (InnerCC ==
ISD::SETGT) ? InnerSwapped : !InnerSwapped;
4803 NeedSwapOps = (TrueResVal == 1);
4822 NeedSwapOps = (TrueResVal == -1);
4831 LLVM_DEBUG(
dbgs() <<
"Found a node that can be lowered to a SETB: ");
4839 if (
N.getOpcode() == PPCISD::FTSQRT)
4844 switch (
N.getConstantOperandVal(0)) {
4845 case Intrinsic::ppc_vsx_xvtdivdp:
4846 case Intrinsic::ppc_vsx_xvtdivsp:
4847 case Intrinsic::ppc_vsx_xvtsqrtdp:
4848 case Intrinsic::ppc_vsx_xvtsqrtsp:
4854bool PPCDAGToDAGISel::tryFoldSWTestBRCC(SDNode *
N) {
4870 SDValue CmpRHS =
N->getOperand(3);
4874 SDValue CmpLHS =
N->getOperand(2);
4912bool PPCDAGToDAGISel::trySelectLoopCountIntrinsic(SDNode *
N) {
4917 SDValue
LHS =
N->getOperand(2),
RHS =
N->getOperand(3);
4924 LHS.getOperand(0).getConstantOperandVal(1) != Intrinsic::loop_decrement)
4931 "Counter decrement comparison is not EQ or NE");
4933 SDValue OldDecrement =
LHS.getOperand(0);
4934 assert(OldDecrement.
hasOneUse() &&
"loop decrement has more than one use!");
4936 SDLoc DecrementLoc(OldDecrement);
4937 SDValue ChainInput = OldDecrement.
getOperand(0);
4938 SDValue DecrementOps[] = {Subtarget->isPPC64() ? getI64Imm(1, DecrementLoc)
4939 : getI32Imm(1, DecrementLoc)};
4940 unsigned DecrementOpcode =
4941 Subtarget->isPPC64() ? PPC::DecreaseCTR8loop : PPC::DecreaseCTRloop;
4942 SDNode *NewDecrement = CurDAG->
getMachineNode(DecrementOpcode, DecrementLoc,
4943 MVT::i1, DecrementOps);
4945 unsigned Val =
RHS->getAsZExtVal();
4947 unsigned Opcode = IsBranchOnTrue ? PPC::BC : PPC::BCn;
4949 ReplaceUses(
LHS.getValue(0),
LHS.getOperand(1));
4953 ReplaceUses(OldDecrement.
getValue(1), ChainInput);
4957 ChainInput,
N->getOperand(0));
4959 CurDAG->
SelectNodeTo(
N, Opcode, MVT::Other, SDValue(NewDecrement, 0),
4960 N->getOperand(4), Chain);
4964bool PPCDAGToDAGISel::tryAsSingleRLWINM(SDNode *
N) {
4971 SDValue Val =
N->getOperand(0);
4972 unsigned SH, MB, ME;
4975 if (isRotateAndMask(Val.
getNode(),
Imm,
false, SH, MB, ME)) {
4977 SDValue
Ops[] = {Val, getI32Imm(SH, dl), getI32Imm(MB, dl),
4988 unsigned AlreadyCleared = 0;
4991 if (IntrinsicID == Intrinsic::ppc_lbarx)
4992 AlreadyCleared = 24;
4993 else if (IntrinsicID == Intrinsic::ppc_lharx)
4994 AlreadyCleared = 16;
4995 if (AlreadyCleared != 0 && AlreadyCleared == MB && ME == 31) {
4996 ReplaceUses(SDValue(
N, 0),
N->getOperand(0));
5001 SDValue
Ops[] = {Val, getI32Imm(0, dl), getI32Imm(MB, dl),
5009 ReplaceUses(SDValue(
N, 0),
N->getOperand(1));
5016bool PPCDAGToDAGISel::tryAsSingleRLWINM8(SDNode *
N) {
5033 SDValue
Ops[] = {
N->getOperand(0), getI64Imm(0, dl), getI64Imm(MB - 32, dl),
5034 getI64Imm(ME - 32, dl)};
5042bool PPCDAGToDAGISel::tryAsPairOfRLDICL(SDNode *
N) {
5062 if (NumOfLeadingZeros != 0)
5075 unsigned OnesOnLeft = ME + 1;
5076 unsigned ZerosInBetween = (MB - ME + 63) & 63;
5079 Val = SDValue(CurDAG->
getMachineNode(PPC::RLDICL, Loc, MVT::i64, Val,
5080 getI64Imm(OnesOnLeft, Loc),
5081 getI64Imm(ZerosInBetween, Loc)),
5090 SDValue
Ops[] = {Val, getI64Imm(64 - OnesOnLeft, Loc),
5091 getI64Imm(NumOfLeadingZeros, Loc)};
5096bool PPCDAGToDAGISel::tryAsSingleRLWIMI(SDNode *
N) {
5126 getI32Imm(MB, dl), getI32Imm(ME, dl)};
5134bool PPCDAGToDAGISel::tryAsSingleRLDCL(SDNode *
N) {
5158 SDValue
Ops[] = {Val.
getOperand(0), RotateAmt, getI32Imm(MB, dl)};
5163bool PPCDAGToDAGISel::tryAsSingleRLDICL(SDNode *
N) {
5182 auto ImDef = CurDAG->
getMachineNode(PPC::IMPLICIT_DEF, dl, ResultType);
5183 SDValue IDVal(ImDef, 0);
5185 Val = SDValue(CurDAG->
getMachineNode(PPC::INSERT_SUBREG, dl, ResultType,
5187 getI32Imm(PPC::sub_32, dl)),
5200 assert(
Imm < 64 &&
"Illegal shift amount");
5205 SDValue
Ops[] = {Val, getI32Imm(SH, dl), getI32Imm(MB, dl)};
5210bool PPCDAGToDAGISel::tryAsSingleRLDICR(SDNode *
N) {
5223 SDValue
Ops[] = {
N->getOperand(0), getI32Imm(SH, dl), getI32Imm(MB, dl)};
5228bool PPCDAGToDAGISel::tryAsSingleRLDIMI(SDNode *
N) {
5232 SDValue N0 =
N->getOperand(0);
5242 unsigned SH = 63 - ME;
5248 getI32Imm(SH, Dl), getI32Imm(MB, Dl)};
5255void PPCDAGToDAGISel::Select(SDNode *
N) {
5257 if (
N->isMachineOpcode()) {
5270 if (tryBitPermutation(
N))
5274 if (tryIntCompareInGPR(
N))
5277 switch (
N->getOpcode()) {
5281 if (
N->getValueType(0) == MVT::i64) {
5288 auto IntrinsicID =
N->getConstantOperandVal(1);
5289 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
5290 IntrinsicID != Intrinsic::ppc_trapd &&
5291 IntrinsicID != Intrinsic::ppc_trap)
5293 unsigned Opcode = (IntrinsicID == Intrinsic::ppc_tdw ||
5294 IntrinsicID == Intrinsic::ppc_trapd)
5299 if (IntrinsicID == Intrinsic::ppc_tdw ||
5300 IntrinsicID == Intrinsic::ppc_tw) {
5301 SDValue
Ops[] = {
N->getOperand(4),
N->getOperand(2),
N->getOperand(3)};
5302 int16_t SImmOperand2;
5303 int16_t SImmOperand3;
5304 int16_t SImmOperand4;
5305 bool isOperand2IntS16Immediate =
5307 bool isOperand3IntS16Immediate =
5312 if (isOperand2IntS16Immediate == isOperand3IntS16Immediate)
5313 Opcode = IntrinsicID == Intrinsic::ppc_tdw ? PPC::TD : PPC::TW;
5314 else if (isOperand3IntS16Immediate)
5316 Ops[2] = getI32Imm(
int(SImmOperand3) & 0xFFFF, dl);
5319 bool isOperand4IntS16Immediate =
5321 (void)isOperand4IntS16Immediate;
5322 assert(isOperand4IntS16Immediate &&
5323 "The 4th operand is not an Immediate");
5325 int16_t TO = int(SImmOperand4) & 0x1F;
5327 if ((TO & 0x1) != ((TO & 0x2) >> 1))
5328 TO = (TO & 0x1) ? TO + 1 : TO - 1;
5330 if ((TO & 0x8) != ((TO & 0x10) >> 1))
5331 TO = (TO & 0x8) ? TO + 8 : TO - 8;
5332 Ops[0] = getI32Imm(TO, dl);
5333 Ops[1] =
N->getOperand(3);
5334 Ops[2] = getI32Imm(
int(SImmOperand2) & 0xFFFF, dl);
5339 OpsWithMD = {getI32Imm(24, dl),
N->getOperand(2), getI32Imm(0, dl)};
5343 if (
N->getNumOperands() > MDIndex) {
5344 SDValue MDV =
N->getOperand(MDIndex);
5349 "ppc-trap-reason") &&
5350 "Unsupported annotation data type!");
5353 "Invalid data type for annotation ppc-trap-reason!");
5356 MD->
getOperand(i))->getString().str()), dl));
5371 auto IntID =
N->getConstantOperandVal(0);
5372 if (IntID == Intrinsic::ppc_fsels) {
5373 SDValue
Ops[] = {
N->getOperand(1),
N->getOperand(2),
N->getOperand(3)};
5378 if (IntID == Intrinsic::ppc_bcdadd_p || IntID == Intrinsic::ppc_bcdsub_p) {
5379 auto Pred =
N->getConstantOperandVal(1);
5381 IntID == Intrinsic::ppc_bcdadd_p ? PPC::BCDADD_rec : PPC::BCDSUB_rec;
5382 unsigned SubReg = 0;
5383 unsigned ShiftVal = 0;
5387 SubReg = PPC::sub_eq;
5391 SubReg = PPC::sub_eq;
5396 SubReg = PPC::sub_lt;
5400 SubReg = PPC::sub_lt;
5405 SubReg = PPC::sub_gt;
5409 SubReg = PPC::sub_gt;
5414 SubReg = PPC::sub_un;
5417 SubReg = PPC::sub_un;
5422 EVT VTs[] = {MVT::v16i8, MVT::Glue};
5423 SDValue
Ops[] = {
N->getOperand(2),
N->getOperand(3),
5426 SDValue CR6Reg = CurDAG->
getRegister(PPC::CR6, MVT::i32);
5429 if (Subtarget->isISA3_1()) {
5431 SDValue CRBit = SDValue(
5432 CurDAG->
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
5433 CR6Reg, SubRegIdx, BCDOp.
getValue(1)),
5439 SDValue(CurDAG->
getMachineNode(PPC::MFOCRF, dl, MVT::i32, CR6Reg,
5442 SDValue
Ops[] = {Move, getI32Imm((32 - (4 + ShiftVal)) & 31, dl),
5443 getI32Imm(31, dl), getI32Imm(31, dl)};
5447 SDValue Shift = SDValue(
5449 CurDAG->
SelectNodeTo(
N, PPC::XORI, MVT::i32, Shift, getI32Imm(1, dl));
5455 if (!Subtarget->isISA3_1())
5457 unsigned Opcode = 0;
5461 case Intrinsic::ppc_altivec_vstribr_p:
5462 Opcode = PPC::VSTRIBR_rec;
5464 case Intrinsic::ppc_altivec_vstribl_p:
5465 Opcode = PPC::VSTRIBL_rec;
5467 case Intrinsic::ppc_altivec_vstrihr_p:
5468 Opcode = PPC::VSTRIHR_rec;
5470 case Intrinsic::ppc_altivec_vstrihl_p:
5471 Opcode = PPC::VSTRIHL_rec;
5478 EVT VTs[] = {MVT::v16i8, MVT::Glue};
5480 SDValue(CurDAG->
getMachineNode(Opcode, dl, VTs,
N->getOperand(2)), 0);
5484 SDValue CR6Reg = CurDAG->
getRegister(PPC::CR6, MVT::i32);
5485 SDValue CRBit = SDValue(
5486 CurDAG->
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
5487 CR6Reg, SubRegIdx, VecStrOp.
getValue(1)),
5501 case PPCISD::ADDI_TLSLD_L_ADDR:
5502 case PPCISD::ADDI_TLSGD_L_ADDR: {
5504 if (PPCLowering->getPointerTy(CurDAG->
getDataLayout()) != MVT::i32 ||
5505 !Subtarget->isSecurePlt() || !Subtarget->
isTargetELF() ||
5513 case PPCISD::CALL_RM: {
5515 !Subtarget->isSecurePlt() || !Subtarget->
isTargetELF())
5518 SDValue
Op =
N->getOperand(1);
5531 ReplaceNode(
N, getGlobalBaseReg());
5535 selectFrameIndex(
N,
N);
5541 N->getOperand(0), InGlue));
5546 ReplaceNode(
N, CurDAG->
getMachineNode(PPC::ReadTB, dl, MVT::i32, MVT::i32,
5547 MVT::Other,
N->getOperand(0)));
5554 getConstantIntValue(), dl,
5555 N->getValueType(0));
5556 if (
N->getValueType(0) == MVT::i64) {
5564 assert(
N->getValueType(0) == MVT::i32 &&
5565 "Expecting i64 or i32 in PPCISD::SRA_ADDZE");
5581 if (tryTLSXFormStore(ST))
5588 EVT LoadedVT =
LD->getMemoryVT();
5595 if (tryTLSXFormLoad(LD))
5606 if (
LD->getValueType(0) != MVT::i64) {
5608 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5611 case MVT::f64: Opcode = PPC::LFDU;
break;
5612 case MVT::f32: Opcode = PPC::LFSU;
break;
5613 case MVT::i32: Opcode = PPC::LWZU;
break;
5614 case MVT::i16: Opcode = isSExt ? PPC::LHAU : PPC::LHZU;
break;
5616 case MVT::i8: Opcode = PPC::LBZU;
break;
5619 assert(
LD->getValueType(0) == MVT::i64 &&
"Unknown load result type!");
5620 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5623 case MVT::i64: Opcode = PPC::LDU;
break;
5624 case MVT::i32: Opcode = PPC::LWZU8;
break;
5625 case MVT::i16: Opcode = isSExt ? PPC::LHAU8 : PPC::LHZU8;
break;
5627 case MVT::i8: Opcode = PPC::LBZU8;
break;
5631 SDValue Chain =
LD->getChain();
5632 SDValue
Base =
LD->getBasePtr();
5635 Opcode, dl,
LD->getValueType(0),
5637 transferMemOperands(
N, MN);
5643 if (
LD->getValueType(0) != MVT::i64) {
5645 assert((!isSExt || LoadedVT == MVT::i16) &&
"Invalid sext update load");
5648 case MVT::f64: Opcode = PPC::LFDUX;
break;
5649 case MVT::f32: Opcode = PPC::LFSUX;
break;
5650 case MVT::i32: Opcode = PPC::LWZUX;
break;
5651 case MVT::i16: Opcode = isSExt ? PPC::LHAUX : PPC::LHZUX;
break;
5653 case MVT::i8: Opcode = PPC::LBZUX;
break;
5656 assert(
LD->getValueType(0) == MVT::i64 &&
"Unknown load result type!");
5657 assert((!isSExt || LoadedVT == MVT::i16 || LoadedVT == MVT::i32) &&
5658 "Invalid sext update load");
5661 case MVT::i64: Opcode = PPC::LDUX;
break;
5662 case MVT::i32: Opcode = isSExt ? PPC::LWAUX : PPC::LWZUX8;
break;
5663 case MVT::i16: Opcode = isSExt ? PPC::LHAUX8 : PPC::LHZUX8;
break;
5665 case MVT::i8: Opcode = PPC::LBZUX8;
break;
5669 SDValue Chain =
LD->getChain();
5670 SDValue
Base =
LD->getBasePtr();
5673 Opcode, dl,
LD->getValueType(0),
5675 transferMemOperands(
N, MN);
5683 if (tryAsSingleRLWINM(
N) || tryAsSingleRLWIMI(
N) || tryAsSingleRLDCL(
N) ||
5684 tryAsSingleRLDICL(
N) || tryAsSingleRLDICR(
N) || tryAsSingleRLWINM8(
N) ||
5685 tryAsPairOfRLDICL(
N))
5691 if (
N->getValueType(0) == MVT::i32)
5692 if (tryBitfieldInsert(
N))
5703 selectFrameIndex(
N,
N->getOperand(0).getNode(), (int64_t)
Imm);
5710 if (tryAsSingleRLDIMI(
N))
5716 bool IsPPC64 = Subtarget->isPPC64();
5718 (Imm64 & ~0xFFFFFFFFuLL) == 0) {
5722 if (ImmHi != 0 && ImmLo != 0) {
5725 getI16Imm(ImmLo, dl));
5726 SDValue Ops1[] = { SDValue(
Lo, 0), getI16Imm(ImmHi, dl)};
5739 bool IsPPC64 = Subtarget->isPPC64();
5741 (Imm64 & ~0xFFFFFFFFuLL) == 0) {
5745 if (ImmHi != 0 && ImmLo != 0) {
5748 getI16Imm(ImmLo, dl));
5749 SDValue Ops1[] = { SDValue(
Lo, 0), getI16Imm(ImmHi, dl)};
5761 selectFrameIndex(
N,
N->getOperand(0).getNode(), (int64_t)
Imm);
5768 unsigned Imm, SH, MB, ME;
5770 isRotateAndMask(
N,
Imm,
true, SH, MB, ME)) {
5771 SDValue
Ops[] = {
N->getOperand(0).getOperand(0),
5772 getI32Imm(SH, dl), getI32Imm(MB, dl),
5773 getI32Imm(ME, dl) };
5782 unsigned Imm, SH, MB, ME;
5784 isRotateAndMask(
N,
Imm,
true, SH, MB, ME)) {
5785 SDValue
Ops[] = {
N->getOperand(0).getOperand(0),
5786 getI32Imm(SH, dl), getI32Imm(MB, dl),
5787 getI32Imm(ME, dl) };
5817 SDNode *MulNode = CurDAG->
getMachineNode(PPC::MULLI8, dl, MVT::i64,
5818 N->getOperand(0), SDImm);
5820 SDValue
Ops[] = {SDValue(MulNode, 0), getI32Imm(Shift, dl),
5821 getI32Imm(63 - Shift, dl)};
5826 SDNode *MulNode = CurDAG->
getMachineNode(PPC::MULLI, dl, MVT::i32,
5827 N->getOperand(0), SDImm);
5829 SDValue
Ops[] = {SDValue(MulNode, 0), getI32Imm(Shift, dl),
5830 getI32Imm(0, dl), getI32Imm(31 - Shift, dl)};
5842 EVT InVT =
N->getOperand(0).getValueType();
5843 assert((InVT == MVT::i64 || InVT == MVT::i32) &&
5844 "Invalid input type for ANDI_rec_1_EQ_BIT");
5846 unsigned Opcode = (InVT == MVT::i64) ? PPC::ANDI8_rec : PPC::ANDI_rec;
5851 SDValue CR0Reg = CurDAG->
getRegister(PPC::CR0, MVT::i32);
5856 CurDAG->
SelectNodeTo(
N, TargetOpcode::EXTRACT_SUBREG, MVT::i1, CR0Reg,
5857 SRIdxVal, SDValue(AndI.getNode(), 1) );
5864 bool isPPC64 = (PtrVT == MVT::i64);
5867 if (Subtarget->useCRBits() &&
N->getOperand(0).getValueType() == MVT::i1)
5870 if (Subtarget->isISA3_0() && Subtarget->isPPC64()) {
5871 bool NeedSwapOps =
false;
5872 bool IsUnCmp =
false;
5874 SDValue
LHS =
N->getOperand(0);
5875 SDValue
RHS =
N->getOperand(1);
5888 N,
N->getSimpleValueType(0) == MVT::i64 ? PPC::SETB8 : PPC::SETB,
5889 N->getValueType(0), GenCC);
5900 N->getValueType(0) == MVT::i32) {
5903 N->getOperand(0), getI32Imm(~0U, dl));
5904 CurDAG->
SelectNodeTo(
N, PPC::SUBFE, MVT::i32, SDValue(Tmp, 0),
5905 N->getOperand(0), SDValue(Tmp, 1));
5909 SDValue CCReg = SelectCC(
N->getOperand(0),
N->getOperand(1), CC, dl);
5911 if (
N->getValueType(0) == MVT::i1) {
5919 case 0: SRI = PPC::sub_lt;
break;
5920 case 1: SRI = PPC::sub_gt;
break;
5921 case 2: SRI = PPC::sub_eq;
break;
5922 case 3: SRI = PPC::sub_un;
break;
5929 SDValue
C = Inv ? NotCCBit : CCBit,
5930 NotC = Inv ? CCBit : NotCCBit;
5933 C,
N->getOperand(2)), 0);
5935 NotC,
N->getOperand(3)), 0);
5937 CurDAG->
SelectNodeTo(
N, PPC::CROR, MVT::i1, CAndT, NotCAndF);
5944 unsigned SelectCCOp;
5945 if (
N->getValueType(0) == MVT::i32)
5946 SelectCCOp = PPC::SELECT_CC_I4;
5947 else if (
N->getValueType(0) == MVT::i64)
5948 SelectCCOp = PPC::SELECT_CC_I8;
5949 else if (
N->getValueType(0) == MVT::f32) {
5950 if (Subtarget->hasP8Vector())
5951 SelectCCOp = PPC::SELECT_CC_VSSRC;
5952 else if (Subtarget->hasSPE())
5953 SelectCCOp = PPC::SELECT_CC_SPE4;
5955 SelectCCOp = PPC::SELECT_CC_F4;
5956 }
else if (
N->getValueType(0) == MVT::f64) {
5957 if (Subtarget->hasVSX())
5958 SelectCCOp = PPC::SELECT_CC_VSFRC;
5959 else if (Subtarget->hasSPE())
5960 SelectCCOp = PPC::SELECT_CC_SPE;
5962 SelectCCOp = PPC::SELECT_CC_F8;
5963 }
else if (
N->getValueType(0) == MVT::f128)
5964 SelectCCOp = PPC::SELECT_CC_F16;
5965 else if (Subtarget->hasSPE())
5966 SelectCCOp = PPC::SELECT_CC_SPE;
5967 else if (
N->getValueType(0) == MVT::v2f64 ||
5968 N->getValueType(0) == MVT::v2i64)
5969 SelectCCOp = PPC::SELECT_CC_VSRC;
5971 SelectCCOp = PPC::SELECT_CC_VRRC;
5974 getI32Imm(BROpc, dl) };
5979 if (Subtarget->hasVSX() && (
N->getValueType(0) == MVT::v2f64 ||
5980 N->getValueType(0) == MVT::v2i64)) {
5987 for (
int i = 0; i < 2; ++i)
5993 if (Op1 == Op2 &&
DM[0] == 0 &&
DM[1] == 0 &&
5999 if (
LD->isUnindexed() &&
LD->hasOneUse() && Op1.
hasOneUse() &&
6000 (
LD->getMemoryVT() == MVT::f64 ||
6001 LD->getMemoryVT() == MVT::i64) &&
6003 SDValue Chain =
LD->getChain();
6005 MachineMemOperand *MemOp =
LD->getMemOperand();
6007 N->getValueType(0),
Ops);
6017 unsigned tmp =
DM[0];
6024 SDValue
Ops[] = { Op1, Op2, DMV };
6032 bool IsPPC64 = Subtarget->isPPC64();
6033 SDValue
Ops[] = {
N->getOperand(1),
N->getOperand(0) };
6035 ? (IsPPC64 ? PPC::BDNZ8 : PPC::BDNZ)
6036 : (IsPPC64 ? PPC::BDZ8 : PPC::BDZ),
6040 case PPCISD::COND_BRANCH: {
6047 unsigned PCC =
N->getConstantOperandVal(1);
6051 SDValue Pred = getI32Imm(PCC, dl);
6058 if (tryFoldSWTestBRCC(
N))
6060 if (trySelectLoopCountIntrinsic(
N))
6066 if (
N->getOperand(2).getValueType() == MVT::i1) {
6089 N->getOperand(
Swap ? 3 : 2),
6090 N->getOperand(
Swap ? 2 : 3)), 0);
6091 CurDAG->
SelectNodeTo(
N, PPC::BC, MVT::Other, BitComp,
N->getOperand(4),
6099 SDValue
CondCode = SelectCC(
N->getOperand(2),
N->getOperand(3), CC, dl);
6101 N->getOperand(4),
N->getOperand(0) };
6108 SDValue
Target =
N->getOperand(1);
6109 unsigned Opc =
Target.getValueType() == MVT::i32 ? PPC::MTCTR : PPC::MTCTR8;
6110 unsigned Reg =
Target.getValueType() == MVT::i32 ? PPC::BCTR : PPC::BCTR8;
6116 case PPCISD::TOC_ENTRY: {
6117 const bool isPPC64 = Subtarget->isPPC64();
6118 const bool isELFABI = Subtarget->
isSVR4ABI();
6119 const bool isAIXABI = Subtarget->
isAIXABI();
6125 "PowerPC doesn't support tiny or kernel code models.");
6136 auto replaceWith = [
this, &dl](
unsigned OpCode, SDNode *TocEntry,
6138 SDValue GA = TocEntry->getOperand(0);
6139 SDValue TocBase = TocEntry->getOperand(1);
6140 SDNode *MN =
nullptr;
6141 if (OpCode == PPC::ADDItoc || OpCode == PPC::ADDItoc8)
6147 transferMemOperands(TocEntry, MN);
6149 ReplaceNode(TocEntry, MN);
6158 "32-bit ELF can only have TOC entries in position independent"
6161 replaceWith(PPC::LWZtoc,
N, MVT::i32);
6165 assert(isAIXABI &&
"ELF ABI already handled");
6168 replaceWith(PPC::ADDItoc,
N, MVT::i32);
6172 replaceWith(PPC::LWZtoc,
N, MVT::i32);
6177 assert(isAIXABI &&
"ELF ABI handled in common SelectCode");
6180 replaceWith(PPC::ADDItoc8,
N, MVT::i64);
6190 assert((isPPC64 || (isAIXABI && !isPPC64)) &&
"We are dealing with 64-bit"
6191 " ELF/AIX or 32-bit AIX in the following.");
6216 isPPC64 ? PPC::ADDIStocHA8 : PPC::ADDIStocHA, dl, VT, TOCbase, GA);
6223 dl, VT, SDValue(Tmp, 0), GA));
6227 if (PPCLowering->isAccessedAsGotIndirect(GA)) {
6231 isPPC64 ? PPC::LDtocL : PPC::LWZtocL, dl, VT, GA, SDValue(Tmp, 0));
6233 transferMemOperands(
N, MN);
6238 assert(isPPC64 &&
"TOC_ENTRY already handled for 32-bit.");
6241 SDValue(Tmp, 0), GA));
6247 "PPCISD::PPC32_PICGOT is only supported for 32-bit SVR4");
6258 "Invalid operand on VADD_SPLAT!");
6260 int Elt =
N->getConstantOperandVal(0);
6261 int EltSize =
N->getConstantOperandVal(1);
6262 unsigned Opc1, Opc2, Opc3;
6266 Opc1 = PPC::VSPLTISB;
6267 Opc2 = PPC::VADDUBM;
6268 Opc3 = PPC::VSUBUBM;
6270 }
else if (EltSize == 2) {
6271 Opc1 = PPC::VSPLTISH;
6272 Opc2 = PPC::VADDUHM;
6273 Opc3 = PPC::VSUBUHM;
6276 assert(EltSize == 4 &&
"Invalid element size on VADD_SPLAT!");
6277 Opc1 = PPC::VSPLTISW;
6278 Opc2 = PPC::VADDUWM;
6279 Opc3 = PPC::VSUBUWM;
6283 if ((Elt & 1) == 0) {
6290 SDValue EltVal = getI32Imm(Elt >> 1, dl);
6292 SDValue TmpVal = SDValue(Tmp, 0);
6295 }
else if (Elt > 0) {
6302 SDValue EltVal = getI32Imm(Elt - 16, dl);
6304 EltVal = getI32Imm(-16, dl);
6316 SDValue EltVal = getI32Imm(Elt + 16, dl);
6318 EltVal = getI32Imm(-16, dl);
6325 case PPCISD::LD_SPLAT: {
6329 if (!Subtarget->hasAltivec() || Subtarget->hasDirectMove())
6332 EVT
Type =
N->getValueType(0);
6333 if (
Type != MVT::v16i8 &&
Type != MVT::v8i16)
6342 isOffsetMultipleOf(
N, 16))
6346 CurDAG->
getRegister(Subtarget->isPPC64() ? PPC::ZERO8 : PPC::ZERO,
6348 unsigned LIOpcode = Subtarget->isPPC64() ? PPC::LI8 : PPC::LI;
6363 unsigned SplatOp = (
Type == MVT::v16i8) ? PPC::VSPLTB : PPC::VSPLTH;
6364 unsigned SplatElemIndex =
6375 SDNode *LoadHigh = LoadLow;
6376 if (
Type == MVT::v8i16) {
6378 PPC::LVX, dl, MVT::v16i8, MVT::Other,
6380 LIOpcode, dl, MVT::i32,
6383 N->getOperand(1), SDValue(LoadLow, 1)});
6387 transferMemOperands(
N, LoadHigh);
6391 SDValue(LoadHigh, 0), SDValue(Mask, 0));
6408SDValue PPCDAGToDAGISel::combineToCMPB(SDNode *
N) {
6412 "Only OR nodes are supported for CMPB");
6415 if (!Subtarget->hasCMPB())
6418 if (
N->getValueType(0) != MVT::i32 &&
6419 N->getValueType(0) != MVT::i64)
6422 EVT VT =
N->getValueType(0);
6425 bool BytesFound[8] = {
false,
false,
false,
false,
false,
false,
false,
false};
6428 auto IsByteSelectCC = [
this](SDValue
O,
unsigned &
b,
6430 SDValue &
LHS, SDValue &
RHS) {
6439 uint64_t PM =
O.getConstantOperandVal(2);
6440 uint64_t PAlt =
O.getConstantOperandVal(3);
6441 for (b = 0;
b < 8; ++
b) {
6443 if (PM && (PM & Mask) == PM && (PAlt & Mask) == PAlt)
6453 O.getConstantOperandVal(1) != 0) {
6454 SDValue Op0 =
O.getOperand(0), Op1 =
O.getOperand(1);
6486 uint64_t ULim =
O.getConstantOperandVal(1);
6487 if (ULim != (UINT64_C(1) << b*8))
6508 SDValue
Op =
O.getOperand(0);
6512 if (
Op.getConstantOperandVal(1) != (UINT64_C(0xFF) << (8*b)))
6515 SDValue
XOR =
Op.getOperand(0);
6527 unsigned Bits =
Op.getValueSizeInBits();
6530 if (
Op.getConstantOperandVal(1) != Bits-8)
6533 SDValue
XOR =
Op.getOperand(0);
6548 while (!
Queue.empty()) {
6549 SDValue
V =
Queue.pop_back_val();
6551 for (
const SDValue &O :
V.getNode()->ops()) {
6557 }
else if (IsByteSelectCC(O, b, M,
A, OLHS, ORHS)) {
6561 BytesFound[
b] =
true;
6564 }
else if ((
LHS == ORHS &&
RHS == OLHS) ||
6565 (
RHS == ORHS &&
LHS == OLHS)) {
6566 BytesFound[
b] =
true;
6578 unsigned LastB = 0, BCnt = 0;
6579 for (
unsigned i = 0; i < 8; ++i)
6580 if (BytesFound[LastB]) {
6585 if (!LastB || BCnt < 2)
6590 if (
LHS.getValueType() != VT) {
6597 bool NonTrivialMask = ((int64_t)
Mask) != INT64_C(-1);
6598 if (NonTrivialMask && !Alt) {
6625void PPCDAGToDAGISel::foldBoolExts(SDValue &Res, SDNode *&
N) {
6626 if (!Subtarget->useCRBits())
6634 if (
N->getOperand(0).getValueType() != MVT::i1)
6637 if (!
N->hasOneUse())
6641 EVT VT =
N->getValueType(0);
6642 SDValue
Cond =
N->getOperand(0);
6645 SDValue ConstFalse = CurDAG->
getConstant(0, dl, VT);
6648 SDNode *
User = *
N->user_begin();
6649 if (
User->getNumOperands() != 2)
6652 auto TryFold = [
this,
N,
User, dl](SDValue Val) {
6653 SDValue UserO0 =
User->getOperand(0), UserO1 =
User->getOperand(1);
6654 SDValue
O0 = UserO0.
getNode() ==
N ? Val : UserO0;
6655 SDValue
O1 = UserO1.
getNode() ==
N ? Val : UserO1;
6658 User->getValueType(0), {O0, O1});
6663 SDValue TrueRes = TryFold(ConstTrue);
6664 if (!TrueRes || TrueRes.
isUndef())
6666 SDValue FalseRes = TryFold(ConstFalse);
6667 if (!FalseRes || FalseRes.
isUndef())
6680 ConstTrue = TrueRes;
6681 ConstFalse = FalseRes;
6682 }
while (
N->hasOneUse());
6685void PPCDAGToDAGISel::PreprocessISelDAG() {
6688 bool MadeChange =
false;
6690 SDNode *
N = &*--Position;
6695 switch (
N->getOpcode()) {
6698 Res = combineToCMPB(
N);
6703 foldBoolExts(Res,
N);
6723void PPCDAGToDAGISel::PostprocessISelDAG() {
6730 PeepholePPC64ZExt();
6738bool PPCDAGToDAGISel::AllUsersSelectZero(SDNode *
N) {
6739 for (
const SDNode *User :
N->users()) {
6740 if (!
User->isMachineOpcode())
6742 if (
User->getMachineOpcode() != PPC::SELECT_I4 &&
6743 User->getMachineOpcode() != PPC::SELECT_I8)
6746 SDNode *Op1 =
User->getOperand(1).getNode();
6747 SDNode *Op2 =
User->getOperand(2).getNode();
6767void PPCDAGToDAGISel::SwapAllSelectUsers(SDNode *
N) {
6769 for (SDNode *User :
N->users()) {
6770 assert((
User->getMachineOpcode() == PPC::SELECT_I4 ||
6771 User->getMachineOpcode() == PPC::SELECT_I8) &&
6772 "Must have all select users");
6776 for (SDNode *User : ToReplace) {
6779 User->getValueType(0),
User->getOperand(0),
6780 User->getOperand(2),
6781 User->getOperand(1));
6789 ReplaceUses(User, ResNode);
6793void PPCDAGToDAGISel::PeepholeCROps() {
6797 for (SDNode &Node : CurDAG->
allnodes()) {
6799 if (!MachineNode || MachineNode->
use_empty())
6801 SDNode *ResNode = MachineNode;
6803 bool Op1Set =
false, Op1Unset =
false,
6805 Op2Set =
false, Op2Unset =
false,
6820 if (
Op.isMachineOpcode()) {
6821 if (
Op.getMachineOpcode() == PPC::CRSET)
6823 else if (
Op.getMachineOpcode() == PPC::CRUNSET)
6825 else if ((
Op.getMachineOpcode() == PPC::CRNOR &&
6826 Op.getOperand(0) ==
Op.getOperand(1)) ||
6827 Op.getMachineOpcode() == PPC::CRNOT)
6834 case PPC::SELECT_I4:
6835 case PPC::SELECT_I8:
6836 case PPC::SELECT_F4:
6837 case PPC::SELECT_F8:
6838 case PPC::SELECT_SPE:
6839 case PPC::SELECT_SPE4:
6840 case PPC::SELECT_VRRC:
6841 case PPC::SELECT_VSFRC:
6842 case PPC::SELECT_VSSRC:
6843 case PPC::SELECT_VSRC: {
6845 if (
Op.isMachineOpcode()) {
6846 if (
Op.getMachineOpcode() == PPC::CRSET)
6848 else if (
Op.getMachineOpcode() == PPC::CRUNSET)
6850 else if ((
Op.getMachineOpcode() == PPC::CRNOR &&
6851 Op.getOperand(0) ==
Op.getOperand(1)) ||
6852 Op.getMachineOpcode() == PPC::CRNOT)
6859 bool SelectSwap =
false;
6872 else if (Op1Unset || Op2Unset)
6874 ResNode = CurDAG->
getMachineNode(PPC::CRUNSET, SDLoc(MachineNode),
6878 ResNode = CurDAG->
getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
6884 ResNode = CurDAG->
getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
6888 else if (AllUsersSelectZero(MachineNode)) {
6889 ResNode = CurDAG->
getMachineNode(PPC::CRNAND, SDLoc(MachineNode),
6911 else if (Op1Unset || Op2Unset)
6927 else if (AllUsersSelectZero(MachineNode)) {
6938 else if (Op1Set || Op2Set)
6960 else if (AllUsersSelectZero(MachineNode)) {
6970 ResNode = CurDAG->
getMachineNode(PPC::CRUNSET, SDLoc(MachineNode),
7000 else if (AllUsersSelectZero(MachineNode)) {
7008 if (Op1Set || Op2Set)
7010 ResNode = CurDAG->
getMachineNode(PPC::CRUNSET, SDLoc(MachineNode),
7024 ResNode = CurDAG->
getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
7030 ResNode = CurDAG->
getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
7034 else if (AllUsersSelectZero(MachineNode)) {
7074 else if (AllUsersSelectZero(MachineNode)) {
7084 ResNode = CurDAG->
getMachineNode(PPC::CRUNSET, SDLoc(MachineNode),
7091 else if (Op1Unset || Op2Set)
7093 ResNode = CurDAG->
getMachineNode(PPC::CRUNSET, SDLoc(MachineNode),
7110 else if (AllUsersSelectZero(MachineNode)) {
7122 else if (Op1Set || Op2Unset)
7136 ResNode = CurDAG->
getMachineNode(PPC::CRNAND, SDLoc(MachineNode),
7146 else if (AllUsersSelectZero(MachineNode)) {
7147 ResNode = CurDAG->
getMachineNode(PPC::CRANDC, SDLoc(MachineNode),
7153 case PPC::SELECT_I4:
7154 case PPC::SELECT_I8:
7155 case PPC::SELECT_F4:
7156 case PPC::SELECT_F8:
7157 case PPC::SELECT_SPE:
7158 case PPC::SELECT_SPE4:
7159 case PPC::SELECT_VRRC:
7160 case PPC::SELECT_VSFRC:
7161 case PPC::SELECT_VSSRC:
7162 case PPC::SELECT_VSRC:
7194 SwapAllSelectUsers(MachineNode);
7196 if (ResNode != MachineNode) {
7203 ReplaceUses(MachineNode, ResNode);
7209 }
while (IsModified);
7320 if (!Op0OK && !Op1OK)
7343 if (!Op0OK && !Op1OK)
7357void PPCDAGToDAGISel::PeepholePPC64ZExt() {
7358 if (!Subtarget->isPPC64())
7372 bool MadeChange =
false;
7374 SDNode *
N = &*--Position;
7376 if (
N->use_empty() || !
N->isMachineOpcode())
7379 if (
N->getMachineOpcode() != PPC::RLDICL)
7382 if (
N->getConstantOperandVal(1) != 0 ||
7383 N->getConstantOperandVal(2) != 32)
7386 SDValue ISR =
N->getOperand(0);
7412 SmallPtrSet<SDNode *, 16> ToPromote;
7418 bool OutsideUse =
false;
7419 for (SDNode *PN : ToPromote) {
7420 for (SDNode *UN : PN->users()) {
7421 if (!ToPromote.count(UN) && UN != ISR.
getNode()) {
7439 for (SDNode *PN : ToPromote) {
7441 switch (PN->getMachineOpcode()) {
7444 case PPC::RLWINM: NewOpcode = PPC::RLWINM8;
break;
7445 case PPC::RLWNM: NewOpcode = PPC::RLWNM8;
break;
7446 case PPC::SLW: NewOpcode = PPC::SLW8;
break;
7447 case PPC::SRW: NewOpcode = PPC::SRW8;
break;
7448 case PPC::LI: NewOpcode = PPC::LI8;
break;
7449 case PPC::LIS: NewOpcode = PPC::LIS8;
break;
7450 case PPC::LHBRX: NewOpcode = PPC::LHBRX8;
break;
7451 case PPC::LWBRX: NewOpcode = PPC::LWBRX8;
break;
7452 case PPC::CNTLZW: NewOpcode = PPC::CNTLZW8;
break;
7453 case PPC::CNTTZW: NewOpcode = PPC::CNTTZW8;
break;
7454 case PPC::RLWIMI: NewOpcode = PPC::RLWIMI8;
break;
7455 case PPC::OR: NewOpcode = PPC::OR8;
break;
7456 case PPC::SELECT_I4: NewOpcode = PPC::SELECT_I8;
break;
7457 case PPC::ORI: NewOpcode = PPC::ORI8;
break;
7458 case PPC::ORIS: NewOpcode = PPC::ORIS8;
break;
7459 case PPC::AND: NewOpcode = PPC::AND8;
break;
7461 NewOpcode = PPC::ANDI8_rec;
7463 case PPC::ANDIS_rec:
7464 NewOpcode = PPC::ANDIS8_rec;
7474 for (
const SDValue &V : PN->ops()) {
7475 if (!ToPromote.count(
V.getNode()) &&
V.getValueType() == MVT::i32 &&
7481 Ops.push_back(SDValue(ReplOp, 0));
7492 SDVTList VTs = PN->getVTList();
7493 for (
unsigned i = 0, ie = VTs.
NumVTs; i != ie; ++i)
7494 if (VTs.
VTs[i] == MVT::i32)
7527 if (!
N->isMachineOpcode())
7529 unsigned Opc =
N->getMachineOpcode();
7533 if (
Opc == PPC::XXPERMDIs) {
7535 N->getConstantOperandVal(1) == 2;
7536 }
else if (
Opc == PPC::XXPERMDI ||
Opc == PPC::XXSLDWI) {
7537 return N->getOperand(0) ==
N->getOperand(1) &&
7539 N->getConstantOperandVal(2) == 2;
7547 if (!
N->isMachineOpcode())
7549 unsigned Opc =
N->getMachineOpcode();
7598 auto SkipRCCopy = [](
SDValue V) {
7599 while (V->isMachineOpcode() &&
7600 V->getMachineOpcode() == TargetOpcode::COPY_TO_REGCLASS) {
7602 if (V->use_empty() || !V->user_begin()->isOnlyUserOf(V.getNode()))
7604 V = V->getOperand(0);
7606 return V.hasOneUse() ? V :
SDValue();
7609 SDValue VecOp = SkipRCCopy(
N->getOperand(0));
7629 if (GV->hasAttribute(
"aix-small-tls"))
7650 if (!(Subtarget.hasAIXSmallLocalDynamicTLS() ||
7691 if (
N->getMachineOpcode() != PPC::ADDI8)
7696 SDValue InitialADDI =
N->getOperand(0);
7707 assert(GA &&
"Expecting a valid GlobalAddressSDNode when folding addi into "
7708 "local-[exec|dynamic] accesses!");
7716 int Offset =
N->getConstantOperandVal(1);
7725void PPCDAGToDAGISel::PeepholePPC64() {
7729 SDNode *
N = &*--Position;
7731 if (
N->use_empty() || !
N->isMachineOpcode())
7742 unsigned StorageOpcode =
N->getMachineOpcode();
7743 bool RequiresMod4Offset =
false;
7745 switch (StorageOpcode) {
7750 case PPC::DFLOADf64:
7751 case PPC::DFLOADf32:
7752 RequiresMod4Offset =
true;
7768 case PPC::DFSTOREf64:
7769 case PPC::DFSTOREf32:
7770 RequiresMod4Offset =
true;
7791 SDValue
Base =
N->getOperand(FirstOp + 1);
7792 if (!
Base.isMachineOpcode())
7796 bool ReplaceFlags =
true;
7808 switch (
Base.getMachineOpcode()) {
7816 ReplaceFlags =
false;
7818 case PPC::ADDIdtprelL:
7821 case PPC::ADDItlsldL:
7824 case PPC::ADDItocL8:
7833 SDValue ImmOpnd =
Base.getOperand(1);
7839 int MaxDisplacement = 7;
7841 const GlobalValue *GV = GA->getGlobal();
7843 MaxDisplacement = std::min((
int)
Alignment.value() - 1, MaxDisplacement);
7846 bool UpdateHBase =
false;
7847 SDValue HBase =
Base.getOperand(0);
7849 int Offset =
N->getConstantOperandVal(FirstOp);
7855 if (
Base.getMachineOpcode() != PPC::ADDItocL8)
7866 if (HImmOpnd != ImmOpnd)
7874 if (RequiresMod4Offset) {
7875 if (GlobalAddressSDNode *GA =
7877 const GlobalValue *GV = GA->getGlobal();
7892 if (RequiresMod4Offset && (
Offset % 4) != 0)
7900 }
else if (
Offset != 0) {
7908 assert(GA &&
"Expecting a valid GlobalAddressSDNode when folding "
7909 "addi into local-[exec|dynamic] accesses!");
7922 LLVM_DEBUG(
dbgs() <<
"Folding add-immediate into mem-op:\nBase: ");
7933 const GlobalValue *GV = GA->getGlobal();
7937 if (Alignment < 4 && (RequiresMod4Offset || (
Offset % 4) != 0)) {
7938 LLVM_DEBUG(
dbgs() <<
"Rejected this candidate for alignment.\n\n");
7942 }
else if (ConstantPoolSDNode *CP =
7952 Base.getOperand(0),
N->getOperand(3));
7962 if (
Base.getNode()->use_empty())
7972 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...
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< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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.
static constexpr Value * getValue(Ty &ValueOrUse)
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
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
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)
cl::opt< bool > ANDIGlueBug("ppc-expose-andi-glue-bug", cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden)
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)
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.
const TargetRegisterClass * getInlineAsmMemoryOperandRegClass(InlineAsm::ConstraintCode C) const override
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.
unsigned getID() const
getID() - Return the register class ID number.
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, in exactly one operand.
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.
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.
@ 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
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
bool operator<(int64_t V1, const APSInt &V2)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
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.
@ O1
Optimize quickly without destroying debuggability.
@ O0
Disable as many optimizations as possible.
static bool isRunOfOnes64(uint64_t Val, unsigned &MB, unsigned &ME)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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.
MCRegisterClass TargetRegisterClass
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.