70 #define DEBUG_TYPE "ppc-codegen" 73 "Number of (sext(setcc)) nodes expanded into GPR sequence.");
75 "Number of (zext(setcc)) nodes expanded into GPR sequence.");
77 "Number of sign extensions for compare inputs added.");
79 "Number of zero extensions for compare inputs added.");
81 "Number of logical ops on i1 values calculated in GPR.");
83 "Number of compares not eliminated as they have non-extending uses.");
85 "Number of compares lowered to setb.");
93 cl::desc(
"use aggressive ppc isel for bit permutations"),
96 "ppc-bit-perm-rewriter-stress-rotates",
97 cl::desc(
"stress rotate selection in aggressive ppc isel for " 102 "ppc-use-branch-hint",
cl::init(
true),
103 cl::desc(
"Enable static hinting of branches on ppc"),
108 cl::desc(
"Enable tls optimization peephole"),
117 cl::desc(
"Specify the types of comparisons to emit GPR-only code for."),
123 "Only comparisons where inputs don't need [sz]ext."),
126 "Only i32 comparisons with zext result."),
128 "Only i64 comparisons with zext result."),
131 "Only i32 comparisons with sext result."),
133 "Only i64 comparisons with sext result.")));
158 InsertVRSaveCode(MF);
163 void PreprocessISelDAG()
override;
164 void PostprocessISelDAG()
override;
168 inline SDValue getI16Imm(
unsigned Imm,
const SDLoc &dl) {
169 return CurDAG->getTargetConstant(Imm, dl,
MVT::i16);
174 inline SDValue getI32Imm(
unsigned Imm,
const SDLoc &dl) {
175 return CurDAG->getTargetConstant(Imm, dl,
MVT::i32);
180 inline SDValue getI64Imm(uint64_t Imm,
const SDLoc &dl) {
181 return CurDAG->getTargetConstant(Imm, dl,
MVT::i64);
185 inline SDValue getSmallIPtrImm(
unsigned Imm,
const SDLoc &dl) {
186 return CurDAG->getTargetConstant(
187 Imm, dl, PPCLowering->getPointerTy(CurDAG->getDataLayout()));
192 static bool isRotateAndMask(
SDNode *
N,
unsigned Mask,
bool isShiftMask,
193 unsigned &SH,
unsigned &MB,
unsigned &ME);
197 SDNode *getGlobalBaseReg();
205 bool tryBitfieldInsert(
SDNode *
N);
206 bool tryBitPermutation(
SDNode *
N);
207 bool tryIntCompareInGPR(
SDNode *
N);
226 return PPCLowering->SelectAddressRegImm(N, Disp, Base, *CurDAG, 0);
246 return PPCLowering->SelectAddressRegReg(N, Base, Index, *CurDAG);
252 return PPCLowering->SelectAddressRegRegOnly(N, Base, Index, *CurDAG);
259 return PPCLowering->SelectAddressRegImm(N, Disp, Base, *CurDAG, 4);
263 return PPCLowering->SelectAddressRegImm(N, Disp, Base, *CurDAG, 16);
277 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
278 unsigned ConstraintID,
279 std::vector<SDValue> &OutOps)
override {
280 switch(ConstraintID) {
282 errs() <<
"ConstraintID: " << ConstraintID <<
"\n";
298 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
302 OutOps.push_back(NewOp);
311 return "PowerPC DAG->DAG Pattern Instruction Selection";
315 #include "PPCGenDAGISel.inc" 320 void PeepholePPC64();
321 void PeepholePPC64ZExt();
322 void PeepholeCROps();
327 bool AllUsersSelectZero(
SDNode *N);
328 void SwapAllSelectUsers(
SDNode *N);
330 bool isOffsetMultipleOf(
SDNode *N,
unsigned Val)
const;
345 bool HasVectorVReg =
false;
346 for (
unsigned i = 0, e = RegInfo->getNumVirtRegs(); i != e; ++i) {
348 if (RegInfo->getRegClass(Reg) == &PPC::VRRCRegClass) {
349 HasVectorVReg =
true;
353 if (!HasVectorVReg)
return;
367 unsigned InVRSAVE = RegInfo->createVirtualRegister(&PPC::GPRCRegClass);
368 unsigned UpdatedVRSAVE = RegInfo->createVirtualRegister(&PPC::GPRCRegClass);
378 BuildMI(EntryBB, IP, dl, TII.
get(PPC::MFVRSAVE), InVRSAVE);
379 BuildMI(EntryBB, IP, dl, TII.
get(PPC::UPDATE_VRSAVE),
380 UpdatedVRSAVE).addReg(InVRSAVE);
381 BuildMI(EntryBB, IP, dl, TII.
get(PPC::MTVRSAVE)).addReg(UpdatedVRSAVE);
385 if (BB->isReturnBlock()) {
386 IP = BB->end(); --IP;
391 while (I2 != BB->begin() && (--I2)->isTerminator())
395 BuildMI(*BB, IP, dl, TII.
get(PPC::MTVRSAVE)).addReg(InVRSAVE);
403 SDNode *PPCDAGToDAGISel::getGlobalBaseReg() {
404 if (!GlobalBaseReg) {
412 if (PPCLowering->getPointerTy(CurDAG->getDataLayout()) ==
MVT::i32) {
414 GlobalBaseReg = PPC::R30;
416 BuildMI(FirstMBB, MBBI, dl, TII.
get(PPC::MoveGOTtoLR));
420 BuildMI(FirstMBB, MBBI, dl, TII.
get(PPC::MovePCtoLR));
422 unsigned TempReg = RegInfo->createVirtualRegister(&PPC::GPRCRegClass);
430 RegInfo->createVirtualRegister(&PPC::GPRC_and_GPRC_NOR0RegClass);
431 BuildMI(FirstMBB, MBBI, dl, TII.
get(PPC::MovePCtoLR));
445 GlobalBaseReg = RegInfo->createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
446 BuildMI(FirstMBB, MBBI, dl, TII.
get(PPC::MovePCtoLR8));
450 return CurDAG->getRegister(GlobalBaseReg,
451 PPCLowering->getPointerTy(CurDAG->getDataLayout()))
459 Imm = cast<ConstantSDNode>(
N)->getZExtValue();
469 Imm = cast<ConstantSDNode>(
N)->getZExtValue();
489 assert(isa<BasicBlockSDNode>(DestMBB));
519 if (
std::max(TProb, FProb) / Threshold < std::min(TProb, FProb))
523 <<
"::" << BB->
getName() <<
"'\n" 524 <<
" -> " << TBB->
getName() <<
": " << TProb <<
"\n" 525 <<
" -> " << FBB->
getName() <<
": " << FProb <<
"\n");
531 if (BBDN->getBasicBlock()->getBasicBlock() != TBB)
547 int FI = cast<FrameIndexSDNode>(
N)->getIndex();
552 getSmallIPtrImm(Offset, dl));
554 ReplaceNode(SN, CurDAG->getMachineNode(Opc, dl, N->
getValueType(0), TFI,
555 getSmallIPtrImm(Offset, dl)));
558 bool PPCDAGToDAGISel::isRotateAndMask(
SDNode *N,
unsigned Mask,
559 bool isShiftMask,
unsigned &SH,
560 unsigned &MB,
unsigned &ME) {
567 unsigned Indeterminant = ~0;
575 if (isShiftMask) Mask = Mask << Shift;
577 Indeterminant = ~(0xFFFFFFFFu << Shift);
580 if (isShiftMask) Mask = Mask >> Shift;
582 Indeterminant = ~(0xFFFFFFFFu >> Shift);
592 if (Mask && !(Mask & Indeterminant)) {
617 Opcode = (RegVT ==
MVT::i32) ? PPC::STBXTLS_32 : PPC::STBXTLS;
621 Opcode = (RegVT ==
MVT::i32) ? PPC::STHXTLS_32 : PPC::STHXTLS;
625 Opcode = (RegVT ==
MVT::i32) ? PPC::STWXTLS_32 : PPC::STWXTLS;
629 Opcode = PPC::STDXTLS;
637 SDNode *MN = CurDAG->getMachineNode(Opcode, dl, VTs, Ops);
638 transferMemOperands(ST, MN);
659 Opcode = (RegVT ==
MVT::i32) ? PPC::LBZXTLS_32 : PPC::LBZXTLS;
663 Opcode = (RegVT ==
MVT::i32) ? PPC::LHZXTLS_32 : PPC::LHZXTLS;
667 Opcode = (RegVT ==
MVT::i32) ? PPC::LWZXTLS_32 : PPC::LWZXTLS;
671 Opcode = PPC::LDXTLS;
678 SDNode *MN = CurDAG->getMachineNode(Opcode, dl, VTs, Ops);
679 transferMemOperands(LD, MN);
686 bool PPCDAGToDAGISel::tryBitfieldInsert(
SDNode *N) {
691 KnownBits LKnown = CurDAG->computeKnownBits(Op0);
692 KnownBits RKnown = CurDAG->computeKnownBits(Op1);
697 if ((TargetMask | InsertMask) == 0xFFFFFFFF) {
700 unsigned Value, SH = 0;
701 TargetMask = ~TargetMask;
702 InsertMask = ~InsertMask;
730 SH = (Op1Opc ==
ISD::SHL) ? Value : 32 - Value;
745 SH = (SHOpc ==
ISD::SHL) ? Value : 32 - Value;
750 SDValue Ops[] = { Op0, Op1, getI32Imm(SH, dl), getI32Imm(MB, dl),
752 ReplaceNode(N, CurDAG->getMachineNode(PPC::RLWIMI, dl,
MVT::i32, Ops));
763 unsigned Remainder = 0;
769 Shift = countTrailingZeros<uint64_t>(Imm);
770 int64_t ImmSh =
static_cast<uint64_t
>(Imm) >> Shift;
788 unsigned Lo = Imm & 0xFFFF;
803 if (!Shift)
return Result;
807 if ((
unsigned)(Imm & 0xFFFFFFFF) == Remainder) {
817 if ((Remainder >> 16) & 0xFFFF)
819 if (Remainder & 0xFFFF)
825 static uint64_t
Rot64(uint64_t Imm,
unsigned R) {
826 return (Imm << R) | (Imm >> (64 - R));
837 for (
unsigned r = 1; r < 63; ++r) {
838 uint64_t RImm =
Rot64(Imm, r);
840 Count = std::min(Count, RCount);
847 uint64_t OnesMask = -(int64_t) (UINT64_C(1) << (LS+1));
848 uint64_t RImmWithOnes = RImm | OnesMask;
851 Count = std::min(Count, RCount);
862 unsigned Remainder = 0;
868 Shift = countTrailingZeros<uint64_t>(Imm);
869 int64_t ImmSh =
static_cast<uint64_t
>(Imm) >> Shift;
887 unsigned Lo = Imm & 0xFFFF;
888 unsigned Hi = (Imm >> 16) & 0xFFFF;
890 auto getI32Imm = [CurDAG, dl](
unsigned Imm) {
902 unsigned OpC = Hi ? PPC::LIS8 : PPC::LI8;
906 SDValue(Result, 0), getI32Imm(Lo));
913 if (!Shift)
return Result;
917 if ((
unsigned)(Imm & 0xFFFFFFFF) == Remainder) {
919 {
SDValue(Result, 0),
SDValue(Result, 0), getI32Imm(Shift), getI32Imm(0)};
928 getI32Imm(63 - Shift));
932 if ((Hi = (Remainder >> 16) & 0xFFFF)) {
934 SDValue(Result, 0), getI32Imm(Hi));
936 if ((Lo = Remainder & 0xFFFF)) {
938 SDValue(Result, 0), getI32Imm(Lo));
958 for (
unsigned r = 1; r < 63; ++r) {
959 uint64_t RImm =
Rot64(Imm, r);
961 if (RCount < Count) {
980 uint64_t OnesMask = -(int64_t) (UINT64_C(1) << (LS+1));
981 uint64_t RImmWithOnes = RImm | OnesMask;
984 if (RCount < Count) {
987 MatImm = RImmWithOnes;
995 auto getI32Imm = [CurDAG, dl](
unsigned Imm) {
1001 getI32Imm(64 - RMin), getI32Imm(MaskEnd));
1005 unsigned MaxTruncation = 0;
1012 Use->isMachineOpcode() ?
Use->getMachineOpcode() :
Use->getOpcode();
1016 if (
Use->isMachineOpcode())
1019 std::max(MaxTruncation,
Use->getValueType(0).getSizeInBits());
1022 if (
Use->isMachineOpcode())
1026 if (MemVTSize == 64 || Use.getOperandNo() != 0)
1028 MaxTruncation =
std::max(MaxTruncation, MemVTSize);
1037 MaxTruncation =
std::max(MaxTruncation, 32u);
1045 MaxTruncation =
std::max(MaxTruncation, 16u);
1053 MaxTruncation =
std::max(MaxTruncation, 8u);
1057 return MaxTruncation;
1065 int64_t Imm = cast<ConstantSDNode>(
N)->getZExtValue();
1077 class BitPermutationSelector {
1092 VariableKnownToBeZero
1096 : V(V), Idx(I), K(K) {}
1097 ValueBit(
Kind K = Variable)
1098 : V(
SDValue(
nullptr, 0)), Idx(UINT32_MAX), K(K) {}
1101 return K == ConstZero || K == VariableKnownToBeZero;
1104 bool hasValue()
const {
1105 return K == Variable || K == VariableKnownToBeZero;
1109 assert(hasValue() &&
"Cannot get the value of a constant bit");
1113 unsigned getValueBitIndex()
const {
1114 assert(hasValue() &&
"Cannot get the value bit index of a constant bit");
1123 unsigned StartIdx, EndIdx;
1133 bool Repl32Coalesced;
1135 BitGroup(
SDValue V,
unsigned R,
unsigned S,
unsigned E)
1136 : V(V), RLAmt(R), StartIdx(S), EndIdx(E), Repl32(
false), Repl32CR(
false),
1137 Repl32Coalesced(
false) {
1139 <<
" [" << S <<
", " << E <<
"]\n");
1145 struct ValueRotInfo {
1148 unsigned NumGroups = 0;
1150 bool Repl32 =
false;
1152 ValueRotInfo() =
default;
1160 if (Repl32 < Other.Repl32)
1162 else if (Repl32 > Other.Repl32)
1164 else if (NumGroups > Other.NumGroups)
1166 else if (NumGroups < Other.NumGroups)
1168 else if (RLAmt == 0 && Other.RLAmt != 0)
1170 else if (RLAmt != 0 && Other.RLAmt == 0)
1172 else if (FirstGroupStartIdx < Other.FirstGroupStartIdx)
1178 using ValueBitsMemoizedValue = std::pair<bool, SmallVector<ValueBit, 64>>;
1179 using ValueBitsMemoizer =
1181 ValueBitsMemoizer Memoizer;
1187 std::pair<bool, SmallVector<ValueBit, 64> *> getValueBits(
SDValue V,
1189 auto &ValueEntry = Memoizer[V];
1191 return std::make_pair(ValueEntry->first, &ValueEntry->second);
1192 ValueEntry.reset(
new ValueBitsMemoizedValue());
1193 bool &Interesting = ValueEntry->first;
1205 for (
unsigned i = 0; i < NumBits; ++i)
1206 Bits[i] = LHSBits[i < RotAmt ? i + (NumBits - RotAmt) : i - RotAmt];
1208 return std::make_pair(Interesting =
true, &Bits);
1217 for (
unsigned i = ShiftAmt; i < NumBits; ++i)
1218 Bits[i] = LHSBits[i - ShiftAmt];
1220 for (
unsigned i = 0; i < ShiftAmt; ++i)
1221 Bits[i] = ValueBit(ValueBit::ConstZero);
1223 return std::make_pair(Interesting =
true, &Bits);
1232 for (
unsigned i = 0; i < NumBits - ShiftAmt; ++i)
1233 Bits[i] = LHSBits[i + ShiftAmt];
1235 for (
unsigned i = NumBits - ShiftAmt; i < NumBits; ++i)
1236 Bits[i] = ValueBit(ValueBit::ConstZero);
1238 return std::make_pair(Interesting =
true, &Bits);
1250 std::tie(Interesting, LHSBits) = getValueBits(V.
getOperand(0), NumBits);
1252 for (
unsigned i = 0; i < NumBits; ++i)
1253 if (((Mask >> i) & 1) == 1)
1254 Bits[i] = (*LHSBits)[i];
1258 if ((*LHSBits)[i].isZero())
1259 Bits[i] = (*LHSBits)[i];
1261 Bits[i] = ValueBit(ValueBit::ConstZero);
1264 return std::make_pair(Interesting, &Bits);
1271 bool AllDisjoint =
true;
1273 unsigned LastIdx = 0;
1274 for (
unsigned i = 0; i < NumBits; ++i) {
1282 if (LHSBits[i].hasValue() && LHSBits[i].getValue() == LastVal &&
1283 LHSBits[i].getValueBitIndex() == LastIdx + 1)
1284 Bits[i] = LHSBits[i];
1285 else if (RHSBits[i].hasValue() && RHSBits[i].getValue() == LastVal &&
1286 RHSBits[i].getValueBitIndex() == LastIdx + 1)
1287 Bits[i] = RHSBits[i];
1289 Bits[i] = ValueBit(ValueBit::ConstZero);
1291 else if (LHSBits[i].
isZero())
1292 Bits[i] = RHSBits[i];
1293 else if (RHSBits[i].
isZero())
1294 Bits[i] = LHSBits[i];
1296 AllDisjoint =
false;
1300 if (Bits[i].hasValue()) {
1301 LastVal = Bits[i].getValue();
1302 LastIdx = Bits[i].getValueBitIndex();
1305 if (LastVal) LastVal =
SDValue();
1313 return std::make_pair(Interesting =
true, &Bits);
1322 const unsigned NumOperandBits = 32;
1323 std::tie(Interesting, LHSBits) = getValueBits(V.
getOperand(0),
1326 for (
unsigned i = 0; i < NumOperandBits; ++i)
1327 Bits[i] = (*LHSBits)[i];
1329 for (
unsigned i = NumOperandBits; i < NumBits; ++i)
1330 Bits[i] = ValueBit(ValueBit::ConstZero);
1332 return std::make_pair(Interesting, &Bits);
1342 std::tie(Interesting, InBits) = getValueBits(V.
getOperand(0),
1348 bool UseUpper32bit =
false;
1349 for (
unsigned i = 0; i < NumValidBits; ++i)
1350 if ((*InBits)[i].hasValue() && (*InBits)[i].getValueBitIndex() >= 32) {
1351 UseUpper32bit =
true;
1357 for (
unsigned i = 0; i < NumValidBits; ++i)
1358 Bits[i] = (*InBits)[i];
1360 return std::make_pair(Interesting, &Bits);
1366 std::tie(Interesting, LHSBits) = getValueBits(V.
getOperand(0),
1370 const unsigned NumValidBits = FromType.getSizeInBits();
1371 for (
unsigned i = 0; i < NumValidBits; ++i)
1372 Bits[i] = (*LHSBits)[i];
1375 for (
unsigned i = NumValidBits; i < NumBits; ++i)
1376 Bits[i] = ValueBit((*LHSBits)[i].getValue(),
1377 (*LHSBits)[i].getValueBitIndex(),
1378 ValueBit::VariableKnownToBeZero);
1380 return std::make_pair(Interesting, &Bits);
1388 for (
unsigned i = 0; i < NumValidBits; ++i)
1389 Bits[i] = ValueBit(V, i);
1392 for (
unsigned i = NumValidBits; i < NumBits; ++i)
1393 Bits[i] = ValueBit(V, i, ValueBit::VariableKnownToBeZero);
1397 return std::make_pair(Interesting =
false, &Bits);
1402 for (
unsigned i = 0; i < NumBits; ++i)
1403 Bits[i] = ValueBit(V, i);
1405 return std::make_pair(Interesting =
false, &Bits);
1410 void computeRotationAmounts() {
1412 RLAmt.resize(
Bits.size());
1413 for (
unsigned i = 0; i <
Bits.size(); ++i)
1414 if (
Bits[i].hasValue()) {
1415 unsigned VBI =
Bits[i].getValueBitIndex();
1419 RLAmt[i] =
Bits.size() - (VBI - i);
1422 RLAmt[i] = UINT32_MAX;
1431 void collectBitGroups(
bool LateMask) {
1434 unsigned LastRLAmt = RLAmt[0];
1436 unsigned LastGroupStartIdx = 0;
1437 bool IsGroupOfZeros = !
Bits[LastGroupStartIdx].hasValue();
1438 for (
unsigned i = 1; i <
Bits.size(); ++i) {
1439 unsigned ThisRLAmt = RLAmt[i];
1441 if (LateMask && !ThisValue) {
1442 ThisValue = LastValue;
1443 ThisRLAmt = LastRLAmt;
1446 if (BitGroups.empty())
1447 LastGroupStartIdx = 0;
1459 if (ThisRLAmt == LastRLAmt && ThisValue == LastValue)
1462 if (!(IsGroupOfZeros && ThisValue && !
Bits[i].
isZero()))
1466 BitGroups.push_back(BitGroup(LastValue, LastRLAmt, LastGroupStartIdx,
1468 LastRLAmt = ThisRLAmt;
1469 LastValue = ThisValue;
1470 LastGroupStartIdx = i;
1471 IsGroupOfZeros = !
Bits[LastGroupStartIdx].hasValue();
1474 BitGroups.push_back(BitGroup(LastValue, LastRLAmt, LastGroupStartIdx,
1477 if (BitGroups.empty())
1481 if (BitGroups.size() > 1) {
1485 if (BitGroups[0].StartIdx == 0 &&
1486 BitGroups[BitGroups.size()-1].EndIdx ==
Bits.size()-1 &&
1487 BitGroups[0].V == BitGroups[BitGroups.size()-1].V &&
1488 BitGroups[0].RLAmt == BitGroups[BitGroups.size()-1].RLAmt) {
1489 LLVM_DEBUG(
dbgs() <<
"\tcombining final bit group with initial one\n");
1490 BitGroups[BitGroups.size()-1].EndIdx = BitGroups[0].EndIdx;
1491 BitGroups.erase(BitGroups.begin());
1501 void collectValueRotInfo() {
1504 for (
auto &BG : BitGroups) {
1505 unsigned RLAmtKey = BG.RLAmt + (BG.Repl32 ? 64 : 0);
1506 ValueRotInfo &VRI = ValueRots[std::make_pair(BG.V, RLAmtKey)];
1508 VRI.RLAmt = BG.RLAmt;
1509 VRI.Repl32 = BG.Repl32;
1511 VRI.FirstGroupStartIdx = std::min(VRI.FirstGroupStartIdx, BG.StartIdx);
1516 ValueRotsVec.clear();
1517 for (
auto &
I : ValueRots) {
1518 ValueRotsVec.push_back(
I.second);
1531 void assignRepl32BitGroups() {
1542 auto IsAllLow32 = [
this](BitGroup & BG) {
1543 if (BG.StartIdx <= BG.EndIdx) {
1544 for (
unsigned i = BG.StartIdx; i <= BG.EndIdx; ++i) {
1545 if (!
Bits[i].hasValue())
1547 if (
Bits[i].getValueBitIndex() >= 32)
1551 for (
unsigned i = BG.StartIdx; i <
Bits.size(); ++i) {
1552 if (!
Bits[i].hasValue())
1554 if (
Bits[i].getValueBitIndex() >= 32)
1557 for (
unsigned i = 0; i <= BG.EndIdx; ++i) {
1558 if (!
Bits[i].hasValue())
1560 if (
Bits[i].getValueBitIndex() >= 32)
1568 for (
auto &BG : BitGroups) {
1572 if (BG.RLAmt == 0) {
1573 auto PotentiallyMerged = [
this](BitGroup & BG) {
1574 for (
auto &BG2 : BitGroups)
1575 if (&BG != &BG2 && BG.V == BG2.V &&
1576 (BG2.RLAmt == 0 || BG2.RLAmt == 32))
1580 if (!PotentiallyMerged(BG))
1583 if (BG.StartIdx < 32 && BG.EndIdx < 32) {
1584 if (IsAllLow32(BG)) {
1585 if (BG.RLAmt >= 32) {
1593 << BG.V.getNode() <<
" RLAmt = " << BG.RLAmt <<
" [" 1594 << BG.StartIdx <<
", " << BG.EndIdx <<
"]\n");
1600 for (
auto I = BitGroups.begin();
I != BitGroups.end();) {
1603 auto IP = (
I == BitGroups.begin()) ?
1604 std::prev(BitGroups.end()) : std::prev(
I);
1605 if (
I->Repl32 && IP->Repl32 &&
I->V == IP->V &&
I->RLAmt == IP->RLAmt &&
1606 I->StartIdx == (IP->EndIdx + 1) % 64 &&
I != IP) {
1608 LLVM_DEBUG(
dbgs() <<
"\tcombining 32-bit replicated bit group for " 1609 <<
I->V.getNode() <<
" RLAmt = " <<
I->RLAmt <<
" [" 1610 <<
I->StartIdx <<
", " <<
I->EndIdx
1611 <<
"] with group with range [" << IP->StartIdx <<
", " 1612 << IP->EndIdx <<
"]\n");
1614 IP->EndIdx =
I->EndIdx;
1615 IP->Repl32CR = IP->Repl32CR ||
I->Repl32CR;
1616 IP->Repl32Coalesced =
true;
1617 I = BitGroups.erase(
I);
1626 if (
I->StartIdx == 32 &&
I->EndIdx == 63) {
1627 assert(std::next(
I) == BitGroups.end() &&
1628 "bit group ends at index 63 but there is another?");
1629 auto IN = BitGroups.begin();
1631 if (IP->Repl32 && IN->Repl32 &&
I->V == IP->V &&
I->V == IN->V &&
1632 (
I->RLAmt % 32) == IP->RLAmt && (
I->RLAmt % 32) == IN->RLAmt &&
1633 IP->EndIdx == 31 && IN->StartIdx == 0 &&
I != IP &&
1637 <<
" RLAmt = " <<
I->RLAmt <<
" [" <<
I->StartIdx
1638 <<
", " <<
I->EndIdx
1639 <<
"] with 32-bit replicated groups with ranges [" 1640 << IP->StartIdx <<
", " << IP->EndIdx <<
"] and [" 1641 << IN->StartIdx <<
", " << IN->EndIdx <<
"]\n");
1649 IP->Repl32CR = IP->Repl32CR ||
I->RLAmt >= 32;
1650 IP->Repl32Coalesced =
true;
1651 I = BitGroups.erase(
I);
1656 IP->EndIdx = IN->EndIdx;
1657 IP->Repl32CR = IP->Repl32CR || IN->Repl32CR ||
I->RLAmt >= 32;
1658 IP->Repl32Coalesced =
true;
1659 I = BitGroups.erase(
I);
1660 BitGroups.erase(BitGroups.begin());
1675 return CurDAG->getTargetConstant(Imm, dl,
MVT::i32);
1678 uint64_t getZerosMask() {
1680 for (
unsigned i = 0; i <
Bits.size(); ++i) {
1681 if (
Bits[i].hasValue())
1683 Mask |= (UINT64_C(1) << i);
1698 SDValue SubRegIdx = CurDAG->getTargetConstant(PPC::sub_32, dl,
MVT::i32);
1699 SDValue ImDef =
SDValue(CurDAG->getMachineNode(PPC::IMPLICIT_DEF, dl,
1701 SDValue ExtVal =
SDValue(CurDAG->getMachineNode(PPC::INSERT_SUBREG, dl,
1712 SDValue SubRegIdx = CurDAG->getTargetConstant(PPC::sub_32, dl,
MVT::i32);
1713 SDValue SubVal =
SDValue(CurDAG->getMachineNode(PPC::EXTRACT_SUBREG, dl,
1721 void SelectAndParts32(
const SDLoc &dl,
SDValue &Res,
unsigned *InstCnt) {
1725 for (ValueRotInfo &VRI : ValueRotsVec) {
1727 for (
unsigned i = 0; i <
Bits.size(); ++i) {
1728 if (!
Bits[i].hasValue() ||
Bits[i].getValue() != VRI.V)
1730 if (RLAmt[i] != VRI.RLAmt)
1736 unsigned ANDIMask = (Mask & UINT16_MAX), ANDISMask = Mask >> 16;
1737 assert((ANDIMask != 0 || ANDISMask != 0) &&
1738 "No set bits in mask for value bit groups");
1739 bool NeedsRotate = VRI.RLAmt != 0;
1755 unsigned NumAndInsts = (
unsigned) NeedsRotate +
1756 (
unsigned) (ANDIMask != 0) +
1757 (
unsigned) (ANDISMask != 0) +
1758 (
unsigned) (ANDIMask != 0 && ANDISMask != 0) +
1759 (
unsigned) (
bool) Res;
1761 LLVM_DEBUG(
dbgs() <<
"\t\trotation groups for " << VRI.V.getNode()
1762 <<
" RL: " << VRI.RLAmt <<
":" 1763 <<
"\n\t\t\tisel using masking: " << NumAndInsts
1764 <<
" using rotates: " << VRI.NumGroups <<
"\n");
1766 if (NumAndInsts >= VRI.NumGroups)
1771 if (InstCnt) *InstCnt += NumAndInsts;
1776 { TruncateToInt32(VRI.V, dl), getI32Imm(VRI.RLAmt, dl),
1777 getI32Imm(0, dl), getI32Imm(31, dl) };
1781 VRot = TruncateToInt32(VRI.V, dl);
1787 VRot, getI32Imm(ANDIMask, dl)), 0);
1790 VRot, getI32Imm(ANDISMask, dl)), 0);
1794 TotalVal = ANDISVal;
1799 ANDIVal, ANDISVal), 0);
1809 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
1810 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt;
1816 SDNode *Select32(
SDNode *N,
bool LateMask,
unsigned *InstCnt) {
1820 if (InstCnt) *InstCnt = 0;
1823 SelectAndParts32(dl, Res, InstCnt);
1828 if ((!NeedMask || LateMask) && !Res) {
1829 ValueRotInfo &VRI = ValueRotsVec[0];
1831 if (InstCnt) *InstCnt += 1;
1833 { TruncateToInt32(VRI.V, dl), getI32Imm(VRI.RLAmt, dl),
1834 getI32Imm(0, dl), getI32Imm(31, dl) };
1838 Res = TruncateToInt32(VRI.V, dl);
1842 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
1843 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt;
1847 if (InstCnt) *InstCnt += BitGroups.size();
1850 for (
auto &BG : BitGroups) {
1853 { TruncateToInt32(BG.V, dl), getI32Imm(BG.RLAmt, dl),
1854 getI32Imm(
Bits.size() - BG.EndIdx - 1, dl),
1855 getI32Imm(
Bits.size() - BG.StartIdx - 1, dl) };
1856 Res =
SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl,
MVT::i32, Ops), 0);
1859 { Res, TruncateToInt32(BG.V, dl), getI32Imm(BG.RLAmt, dl),
1860 getI32Imm(
Bits.size() - BG.EndIdx - 1, dl),
1861 getI32Imm(
Bits.size() - BG.StartIdx - 1, dl) };
1862 Res =
SDValue(CurDAG->getMachineNode(PPC::RLWIMI, dl,
MVT::i32, Ops), 0);
1867 unsigned Mask = (
unsigned) getZerosMask();
1869 unsigned ANDIMask = (Mask & UINT16_MAX), ANDISMask = Mask >> 16;
1870 assert((ANDIMask != 0 || ANDISMask != 0) &&
1871 "No set bits in zeros mask?");
1873 if (InstCnt) *InstCnt += (
unsigned) (ANDIMask != 0) +
1875 (
unsigned) (ANDIMask != 0 && ANDISMask != 0);
1880 Res, getI32Imm(ANDIMask, dl)), 0);
1883 Res, getI32Imm(ANDISMask, dl)), 0);
1891 ANDIVal, ANDISVal), 0);
1897 unsigned SelectRotMask64Count(
unsigned RLAmt,
bool Repl32,
1898 unsigned MaskStart,
unsigned MaskEnd,
1902 unsigned InstMaskStart = 64 - MaskEnd - 1,
1903 InstMaskEnd = 64 - MaskStart - 1;
1908 if ((!IsIns && (InstMaskEnd == 63 || InstMaskStart == 0)) ||
1909 InstMaskEnd == 63 - RLAmt)
1918 bool Repl32,
unsigned MaskStart,
unsigned MaskEnd,
1919 unsigned *InstCnt =
nullptr) {
1922 unsigned InstMaskStart = 64 - MaskEnd - 1,
1923 InstMaskEnd = 64 - MaskStart - 1;
1925 if (InstCnt) *InstCnt += 1;
1931 assert(InstMaskStart >= 32 &&
"Mask cannot start out of range");
1932 assert(InstMaskEnd >= 32 &&
"Mask cannot end out of range");
1934 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
1935 getI32Imm(InstMaskStart - 32, dl), getI32Imm(InstMaskEnd - 32, dl) };
1940 if (InstMaskEnd == 63) {
1942 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
1943 getI32Imm(InstMaskStart, dl) };
1944 return SDValue(CurDAG->getMachineNode(PPC::RLDICL, dl,
MVT::i64, Ops), 0);
1947 if (InstMaskStart == 0) {
1949 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
1950 getI32Imm(InstMaskEnd, dl) };
1951 return SDValue(CurDAG->getMachineNode(PPC::RLDICR, dl,
MVT::i64, Ops), 0);
1954 if (InstMaskEnd == 63 - RLAmt) {
1956 { ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
1957 getI32Imm(InstMaskStart, dl) };
1958 return SDValue(CurDAG->getMachineNode(PPC::RLDIC, dl,
MVT::i64, Ops), 0);
1967 if (InstCnt) *InstCnt += 1;
1970 unsigned RLAmt2 = MaskStart;
1973 unsigned RLAmt1 = (64 + RLAmt - RLAmt2) % 64;
1975 V = SelectRotMask64(V, dl, RLAmt1,
false, 0, 63);
1976 return SelectRotMask64(V, dl, RLAmt2,
false, MaskStart, MaskEnd);
1982 unsigned RLAmt,
bool Repl32,
unsigned MaskStart,
1983 unsigned MaskEnd,
unsigned *InstCnt =
nullptr) {
1986 unsigned InstMaskStart = 64 - MaskEnd - 1,
1987 InstMaskEnd = 64 - MaskStart - 1;
1989 if (InstCnt) *InstCnt += 1;
1995 assert(InstMaskStart >= 32 &&
"Mask cannot start out of range");
1996 assert(InstMaskEnd >= 32 &&
"Mask cannot end out of range");
1998 { ExtendToInt64(Base, dl), ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
1999 getI32Imm(InstMaskStart - 32, dl), getI32Imm(InstMaskEnd - 32, dl) };
2004 if (InstMaskEnd == 63 - RLAmt) {
2006 { ExtendToInt64(Base, dl), ExtendToInt64(V, dl), getI32Imm(RLAmt, dl),
2007 getI32Imm(InstMaskStart, dl) };
2008 return SDValue(CurDAG->getMachineNode(PPC::RLDIMI, dl,
MVT::i64, Ops), 0);
2017 if (InstCnt) *InstCnt += 1;
2020 unsigned RLAmt2 = MaskStart;
2023 unsigned RLAmt1 = (64 + RLAmt - RLAmt2) % 64;
2025 V = SelectRotMask64(V, dl, RLAmt1,
false, 0, 63);
2026 return SelectRotMaskIns64(Base, V, dl, RLAmt2,
false, MaskStart, MaskEnd);
2029 void SelectAndParts64(
const SDLoc &dl,
SDValue &Res,
unsigned *InstCnt) {
2042 for (ValueRotInfo &VRI : ValueRotsVec) {
2050 auto MatchingBG = [VRI](
const BitGroup &BG) {
2054 unsigned EffRLAmt = BG.RLAmt;
2055 if (!VRI.Repl32 && BG.Repl32) {
2056 if (BG.StartIdx < 32 && BG.EndIdx < 32 && BG.StartIdx <= BG.EndIdx &&
2057 !BG.Repl32Coalesced) {
2063 }
else if (VRI.Repl32 != BG.Repl32) {
2067 return VRI.RLAmt == EffRLAmt;
2070 for (
auto &BG : BitGroups) {
2071 if (!MatchingBG(BG))
2074 if (BG.StartIdx <= BG.EndIdx) {
2075 for (
unsigned i = BG.StartIdx; i <= BG.EndIdx; ++i)
2076 Mask |= (UINT64_C(1) << i);
2078 for (
unsigned i = BG.StartIdx; i <
Bits.size(); ++i)
2079 Mask |= (UINT64_C(1) << i);
2080 for (
unsigned i = 0; i <= BG.EndIdx; ++i)
2081 Mask |= (UINT64_C(1) << i);
2090 unsigned ANDIMask = (Mask & UINT16_MAX),
2091 ANDISMask = (Mask >> 16) & UINT16_MAX;
2093 bool NeedsRotate = VRI.RLAmt || (VRI.Repl32 && !
isUInt<32>(
Mask));
2095 unsigned NumAndInsts = (
unsigned) NeedsRotate +
2096 (
unsigned) (
bool) Res;
2099 (
unsigned) (ANDIMask != 0 && ANDISMask != 0);
2103 unsigned NumRLInsts = 0;
2104 bool FirstBG =
true;
2105 bool MoreBG =
false;
2106 for (
auto &BG : BitGroups) {
2107 if (!MatchingBG(BG)) {
2112 SelectRotMask64Count(BG.RLAmt, BG.Repl32, BG.StartIdx, BG.EndIdx,
2117 LLVM_DEBUG(
dbgs() <<
"\t\trotation groups for " << VRI.V.getNode()
2118 <<
" RL: " << VRI.RLAmt << (VRI.Repl32 ?
" (32):" :
":")
2119 <<
"\n\t\t\tisel using masking: " << NumAndInsts
2120 <<
" using rotates: " << NumRLInsts <<
"\n");
2126 if (NumAndInsts > NumRLInsts)
2131 if ((Use32BitInsts || MoreBG) && NumAndInsts == NumRLInsts)
2136 if (InstCnt) *InstCnt += NumAndInsts;
2143 if (VRI.RLAmt || (VRI.Repl32 && !
isUInt<32>(Mask)))
2144 VRot = SelectRotMask64(VRI.V, dl, VRI.RLAmt, VRI.Repl32,
2145 VRI.Repl32 ? 31 : 0, VRI.Repl32 ? 30 : 63);
2150 if (Use32BitInsts) {
2151 assert((ANDIMask != 0 || ANDISMask != 0) &&
2152 "No set bits in mask when using 32-bit ands for 64-bit value");
2157 ExtendToInt64(VRot, dl),
2158 getI32Imm(ANDIMask, dl)),
2162 ExtendToInt64(VRot, dl),
2163 getI32Imm(ANDISMask, dl)),
2167 TotalVal = ANDISVal;
2172 ExtendToInt64(ANDIVal, dl), ANDISVal), 0);
2177 ExtendToInt64(VRot, dl), TotalVal),
2185 ExtendToInt64(Res, dl), TotalVal),
2190 eraseMatchingBitGroups(MatchingBG);
2195 SDNode *Select64(
SDNode *N,
bool LateMask,
unsigned *InstCnt) {
2199 if (InstCnt) *InstCnt = 0;
2202 SelectAndParts64(dl, Res, InstCnt);
2207 if ((!NeedMask || LateMask) && !Res) {
2211 unsigned MaxGroupsIdx = 0;
2212 if (!ValueRotsVec[0].Repl32) {
2213 for (
unsigned i = 0, ie = ValueRotsVec.size(); i < ie; ++i)
2214 if (ValueRotsVec[i].Repl32) {
2215 if (ValueRotsVec[i].NumGroups > ValueRotsVec[0].NumGroups)
2221 ValueRotInfo &VRI = ValueRotsVec[MaxGroupsIdx];
2222 bool NeedsRotate =
false;
2225 }
else if (VRI.Repl32) {
2226 for (
auto &BG : BitGroups) {
2227 if (BG.V != VRI.V || BG.RLAmt != VRI.RLAmt ||
2228 BG.Repl32 != VRI.Repl32)
2233 if (BG.StartIdx < 32 && BG.EndIdx < 32 && BG.StartIdx < BG.EndIdx)
2242 Res = SelectRotMask64(VRI.V, dl, VRI.RLAmt, VRI.Repl32,
2243 VRI.Repl32 ? 31 : 0, VRI.Repl32 ? 30 : 63,
2250 eraseMatchingBitGroups([VRI](
const BitGroup &BG) {
2251 return BG.V == VRI.V && BG.RLAmt == VRI.RLAmt &&
2252 BG.Repl32 == VRI.Repl32;
2259 for (
auto I = BitGroups.begin(),
IE = BitGroups.end();
I !=
IE; ++
I) {
2260 if (SelectRotMask64Count(
I->RLAmt,
I->Repl32,
I->StartIdx,
I->EndIdx,
2262 SelectRotMask64Count(
I->RLAmt,
I->Repl32,
I->StartIdx,
I->EndIdx,
2264 if (
I != BitGroups.begin()) {
2267 BitGroups.insert(BitGroups.begin(), BG);
2275 for (
auto &BG : BitGroups) {
2277 Res = SelectRotMask64(BG.V, dl, BG.RLAmt, BG.Repl32, BG.StartIdx,
2278 BG.EndIdx, InstCnt);
2280 Res = SelectRotMaskIns64(Res, BG.V, dl, BG.RLAmt, BG.Repl32,
2281 BG.StartIdx, BG.EndIdx, InstCnt);
2285 uint64_t Mask = getZerosMask();
2292 unsigned ANDIMask = (Mask & UINT16_MAX),
2293 ANDISMask = (Mask >> 16) & UINT16_MAX;
2295 if (Use32BitInsts) {
2296 assert((ANDIMask != 0 || ANDISMask != 0) &&
2297 "No set bits in mask when using 32-bit ands for 64-bit value");
2299 if (InstCnt) *InstCnt += (
unsigned) (ANDIMask != 0) +
2301 (
unsigned) (ANDIMask != 0 && ANDISMask != 0);
2306 ExtendToInt64(Res, dl), getI32Imm(ANDIMask, dl)), 0);
2309 ExtendToInt64(Res, dl), getI32Imm(ANDISMask, dl)), 0);
2317 ExtendToInt64(ANDIVal, dl), ANDISVal), 0);
2324 ExtendToInt64(Res, dl), MaskVal), 0);
2333 collectBitGroups(LateMask);
2334 if (BitGroups.empty())
2338 if (
Bits.size() == 64)
2339 assignRepl32BitGroups();
2342 collectValueRotInfo();
2344 if (
Bits.size() == 32) {
2345 return Select32(N, LateMask, InstCnt);
2347 assert(
Bits.size() == 64 &&
"Not 64 bits here?");
2348 return Select64(N, LateMask, InstCnt);
2354 void eraseMatchingBitGroups(
function_ref<
bool(
const BitGroup &)>
F) {
2355 BitGroups.erase(
remove_if(BitGroups,
F), BitGroups.end());
2383 Bits = std::move(*Result.second);
2385 LLVM_DEBUG(
dbgs() <<
"Considering bit-permutation-based instruction" 2386 " selection for: ");
2390 computeRotationAmounts();
2403 unsigned InstCnt = 0, InstCntLateMask = 0;
2406 LLVM_DEBUG(
dbgs() <<
"\t\tisel would use " << InstCnt <<
" instructions\n");
2411 <<
" instructions\n");
2413 if (InstCnt <= InstCntLateMask) {
2423 class IntegerCompareEliminator {
2428 enum ExtOrTruncConversion {
Ext, Trunc };
2436 enum SetccInGPROpts { ZExtOrig, ZExtInvert, SExtOrig, SExtInvert };
2446 enum ZeroCompare { GEZExt, GESExt, LEZExt, LESExt };
2453 SDValue addExtOrTrunc(
SDValue NatWidthRes, ExtOrTruncConversion Conv);
2457 int64_t RHSValue,
SDLoc dl);
2459 int64_t RHSValue,
SDLoc dl);
2461 int64_t RHSValue,
SDLoc dl);
2463 int64_t RHSValue,
SDLoc dl);
2468 PPCDAGToDAGISel *Sel) : CurDAG(DAG), S(Sel) {
2471 "Only expecting to use this on 64 bit targets.");
2487 return tryEXTEND(N);
2491 return tryLogicOpOfCompares(N);
2497 static bool isLogicOp(
unsigned Opc) {
2502 SDNode *IntegerCompareEliminator::tryEXTEND(
SDNode *N) {
2505 "Expecting a zero/sign extend node!");
2512 WideRes = computeLogicOpInGPR(N->
getOperand(0));
2519 SetccInGPROpts::SExtOrig : SetccInGPROpts::ZExtOrig);
2532 if (Input32Bit != Output32Bit)
2534 ExtOrTruncConversion::Trunc);
2542 SDNode *IntegerCompareEliminator::tryLogicOpOfCompares(
SDNode *N) {
2546 "Expected a logic operation on setcc results.");
2548 if (!LoweredLogical)
2553 unsigned SubRegToExtract = IsBitwiseNegate ? PPC::sub_eq : PPC::sub_gt;
2562 if (IsBitwiseNegate &&
2565 else if (IsBitwiseNegate)
2567 OpToConvToRecForm = LoweredLogical.
getOperand(0);
2571 OpToConvToRecForm = LoweredLogical;
2581 if (NewOpc != -1 && IsBitwiseNegate) {
2584 "Expected a PPC::XORI8 only for bitwise negation.");
2586 std::vector<SDValue> Ops;
2587 for (
int i = 0, e = OpToConvToRecForm.
getNumOperands(); i < e; i++)
2588 Ops.push_back(OpToConvToRecForm.
getOperand(i));
2591 SDValue(CurDAG->getMachineNode(NewOpc, dl,
2595 assert((NewOpc != -1 || !IsBitwiseNegate) &&
2596 "No record form available for AND8/OR8/XOR8?");
2598 SDValue(CurDAG->getMachineNode(NewOpc == -1 ? PPC::ANDIo8 : NewOpc, dl,
2607 CurDAG->getTargetConstant(SubRegToExtract, dl,
MVT::i32);
2609 SDValue(CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl,
2623 SDValue IntegerCompareEliminator::computeLogicOpInGPR(
SDValue LogicOp) {
2625 "Can only handle logic operations here.");
2627 "Can only handle logic operations on i1 values here.");
2639 unsigned OperandOpcode = Operand.
getOpcode();
2641 return getSETCCInGPR(Operand, SetccInGPROpts::ZExtOrig);
2645 return SDValue(CurDAG->getMachineNode(InVT ==
MVT::i32 ? PPC::RLDICL_32 :
2646 PPC::RLDICL, dl, InVT, InputOp,
2647 S->getI64Imm(0, dl),
2648 S->getI64Imm(63, dl)), 0);
2649 }
else if (isLogicOp(OperandOpcode))
2650 return computeLogicOpInGPR(Operand);
2653 LHS = getLogicOperand(LogicOp.
getOperand(0));
2654 RHS = getLogicOperand(LogicOp.
getOperand(1));
2659 if (!LHS || (!RHS && !IsBitwiseNegation))
2662 NumLogicOpsOnComparison++;
2667 if (!IsBitwiseNegation && RHS.getValueType() ==
MVT::i32)
2673 case ISD::AND: NewOpc = PPC::AND8;
break;
2674 case ISD::OR: NewOpc = PPC::OR8;
break;
2675 case ISD::XOR: NewOpc = PPC::XOR8;
break;
2678 if (IsBitwiseNegation) {
2679 RHS = S->getI64Imm(1, dl);
2680 NewOpc = PPC::XORI8;
2683 return SDValue(CurDAG->getMachineNode(NewOpc, dl,
MVT::i64, LHS, RHS), 0);
2691 SDValue IntegerCompareEliminator::signExtendInputIfNeeded(
SDValue Input) {
2693 "Can only sign-extend 32-bit values here.");
2715 SignExtensionsAdded++;
2716 return SDValue(CurDAG->getMachineNode(PPC::EXTSW_32_64, dl,
2724 SDValue IntegerCompareEliminator::zeroExtendInputIfNeeded(
SDValue Input) {
2726 "Can only zero-extend 32-bit values here.");
2736 if (IsTruncateOfZExt)
2750 ZeroExtensionsAdded++;
2751 return SDValue(CurDAG->getMachineNode(PPC::RLDICL_32_64, dl,
MVT::i64, Input,
2752 S->getI64Imm(0, dl),
2753 S->getI64Imm(32, dl)), 0);
2760 SDValue IntegerCompareEliminator::addExtOrTrunc(
SDValue NatWidthRes,
2761 ExtOrTruncConversion Conv) {
2762 SDLoc dl(NatWidthRes);
2767 SDValue ImDef(CurDAG->getMachineNode(PPC::IMPLICIT_DEF, dl,
MVT::i64), 0);
2769 CurDAG->getTargetConstant(PPC::sub_32, dl,
MVT::i32);
2770 return SDValue(CurDAG->getMachineNode(PPC::INSERT_SUBREG, dl,
MVT::i64,
2771 ImDef, NatWidthRes, SubRegIdx), 0);
2774 assert(Conv == ExtOrTruncConversion::Trunc &&
2775 "Unknown convertion between 32 and 64 bit values.");
2779 CurDAG->getTargetConstant(PPC::sub_32, dl,
MVT::i32);
2780 return SDValue(CurDAG->getMachineNode(PPC::EXTRACT_SUBREG, dl,
MVT::i32,
2781 NatWidthRes, SubRegIdx), 0);
2787 IntegerCompareEliminator::getCompoundZeroComparisonInGPR(
SDValue LHS,
SDLoc dl,
2788 ZeroCompare CmpTy) {
2795 case ZeroCompare::GEZExt:
2796 case ZeroCompare::GESExt:
2797 ToExtend =
SDValue(CurDAG->getMachineNode(Is32Bit ? PPC::NOR : PPC::NOR8,
2798 dl, InVT, LHS, LHS), 0);
2800 case ZeroCompare::LEZExt:
2801 case ZeroCompare::LESExt: {
2804 LHS = signExtendInputIfNeeded(LHS);
2809 Neg, S->getI64Imm(1, dl),
2810 S->getI64Imm(63, dl)), 0);
2814 S->getI64Imm(~0ULL, dl)), 0);
2824 (CmpTy == ZeroCompare::GEZExt || CmpTy == ZeroCompare::LEZExt))
2826 ToExtend, S->getI64Imm(1, dl),
2827 S->getI64Imm(63, dl)), 0);
2829 (CmpTy == ZeroCompare::GESExt || CmpTy == ZeroCompare::LESExt))
2830 return SDValue(CurDAG->getMachineNode(PPC::SRADI, dl,
MVT::i64, ToExtend,
2831 S->getI64Imm(63, dl)), 0);
2833 assert(Is32Bit &&
"Should have handled the 32-bit sequences above.");
2836 case ZeroCompare::GEZExt: {
2837 SDValue ShiftOps[] = { ToExtend, S->getI32Imm(1, dl), S->getI32Imm(31, dl),
2838 S->getI32Imm(31, dl) };
2842 case ZeroCompare::GESExt:
2843 return SDValue(CurDAG->getMachineNode(PPC::SRAWI, dl,
MVT::i32, ToExtend,
2844 S->getI32Imm(31, dl)), 0);
2845 case ZeroCompare::LEZExt:
2846 return SDValue(CurDAG->getMachineNode(PPC::XORI8, dl,
MVT::i64, ToExtend,
2847 S->getI32Imm(1, dl)), 0);
2848 case ZeroCompare::LESExt:
2849 return SDValue(CurDAG->getMachineNode(PPC::ADDI8, dl,
MVT::i64, ToExtend,
2850 S->getI32Imm(-1, dl)), 0);
2861 IntegerCompareEliminator::get32BitZExtCompare(
SDValue LHS,
SDValue RHS,
2863 int64_t RHSValue,
SDLoc dl) {
2867 bool IsRHSZero = RHSValue == 0;
2868 bool IsRHSOne = RHSValue == 1;
2869 bool IsRHSNegOne = RHSValue == -1LL;
2875 SDValue Xor = IsRHSZero ? LHS :
2879 SDValue ShiftOps[] = { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl),
2880 S->getI32Imm(31, dl) };
2887 SDValue Xor = IsRHSZero ? LHS :
2891 SDValue ShiftOps[] = { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl),
2892 S->getI32Imm(31, dl) };
2894 SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl,
MVT::i32, ShiftOps), 0);
2896 S->getI32Imm(1, dl)), 0);
2902 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt);
2919 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LEZExt);
2923 LHS = signExtendInputIfNeeded(LHS);
2924 RHS = signExtendInputIfNeeded(RHS);
2926 SDValue(CurDAG->getMachineNode(PPC::SUBF8, dl,
MVT::i64, LHS, RHS), 0);
2929 S->getI64Imm(1, dl), S->getI64Imm(63, dl)),
2932 SDValue(CurDAG->getMachineNode(PPC::XORI8, dl,
2933 MVT::i64, Shift, S->getI32Imm(1, dl)), 0);
2941 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt);
2947 LHS = signExtendInputIfNeeded(LHS);
2948 RHS = signExtendInputIfNeeded(RHS);
2952 Neg, S->getI32Imm(1, dl), S->getI32Imm(63, dl)), 0);
2970 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LEZExt);
2974 SDValue ShiftOps[] = { LHS, S->getI32Imm(1, dl), S->getI32Imm(31, dl),
2975 S->getI32Imm(31, dl) };
2983 LHS = signExtendInputIfNeeded(LHS);
2984 RHS = signExtendInputIfNeeded(RHS);
2986 SDValue(CurDAG->getMachineNode(PPC::SUBF8, dl,
MVT::i64, RHS, LHS), 0);
2988 SUBFNode, S->getI64Imm(1, dl),
2989 S->getI64Imm(63, dl)), 0);
3000 LHS = zeroExtendInputIfNeeded(LHS);
3001 RHS = zeroExtendInputIfNeeded(RHS);
3003 SDValue(CurDAG->getMachineNode(PPC::SUBF8, dl,
MVT::i64, LHS, RHS), 0);
3006 Subtract, S->getI64Imm(1, dl),
3007 S->getI64Imm(63, dl)), 0);
3008 return SDValue(CurDAG->getMachineNode(PPC::XORI8, dl,
MVT::i64, SrdiNode,
3009 S->getI32Imm(1, dl)), 0);
3020 LHS = zeroExtendInputIfNeeded(LHS);
3021 RHS = zeroExtendInputIfNeeded(RHS);
3023 SDValue(CurDAG->getMachineNode(PPC::SUBF8, dl,
MVT::i64, RHS, LHS), 0);
3025 Subtract, S->getI64Imm(1, dl),
3026 S->getI64Imm(63, dl)), 0);
3034 IntegerCompareEliminator::get32BitSExtCompare(
SDValue LHS,
SDValue RHS,
3036 int64_t RHSValue,
SDLoc dl) {
3040 bool IsRHSZero = RHSValue == 0;
3041 bool IsRHSOne = RHSValue == 1;
3042 bool IsRHSNegOne = RHSValue == -1LL;
3051 SDValue CountInput = IsRHSZero ? LHS :
3054 SDValue(CurDAG->getMachineNode(PPC::CNTLZW, dl,
MVT::i32, CountInput), 0);
3055 SDValue SHLOps[] = { Cntlzw, S->getI32Imm(27, dl),
3056 S->getI32Imm(5, dl), S->getI32Imm(31, dl) };
3058 SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl,
MVT::i32, SHLOps), 0);
3069 SDValue Xor = IsRHSZero ? LHS :
3074 { Clz, S->getI32Imm(27, dl), S->getI32Imm(5, dl), S->getI32Imm(31, dl) };
3076 SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl,
MVT::i32, ShiftOps), 0);
3079 S->getI32Imm(1, dl)), 0);
3086 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt);
3101 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LESExt);
3104 LHS = signExtendInputIfNeeded(LHS);
3105 RHS = signExtendInputIfNeeded(RHS);
3111 SUBFNode, S->getI64Imm(1, dl),
3112 S->getI64Imm(63, dl)), 0);
3114 S->getI32Imm(-1, dl)), 0);
3121 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt);
3126 LHS = signExtendInputIfNeeded(LHS);
3127 RHS = signExtendInputIfNeeded(RHS);
3131 S->getI64Imm(63, dl)), 0);
3148 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LESExt);
3152 S->getI32Imm(31, dl)), 0);
3157 LHS = signExtendInputIfNeeded(LHS);
3158 RHS = signExtendInputIfNeeded(RHS);
3160 SDValue(CurDAG->getMachineNode(PPC::SUBF8, dl,
MVT::i64, RHS, LHS), 0);
3162 SUBFNode, S->getI64Imm(63, dl)), 0);
3173 LHS = zeroExtendInputIfNeeded(LHS);
3174 RHS = zeroExtendInputIfNeeded(RHS);
3176 SDValue(CurDAG->getMachineNode(PPC::SUBF8, dl,
MVT::i64, LHS, RHS), 0);
3179 S->getI32Imm(1, dl), S->getI32Imm(63,dl)),
3181 return SDValue(CurDAG->getMachineNode(PPC::ADDI8, dl,
MVT::i64, Shift,
3182 S->getI32Imm(-1, dl)), 0);
3193 LHS = zeroExtendInputIfNeeded(LHS);
3194 RHS = zeroExtendInputIfNeeded(RHS);
3196 SDValue(CurDAG->getMachineNode(PPC::SUBF8, dl,
MVT::i64, RHS, LHS), 0);
3198 Subtract, S->getI64Imm(63, dl)), 0);
3206 IntegerCompareEliminator::get64BitZExtCompare(
SDValue LHS,
SDValue RHS,
3208 int64_t RHSValue,
SDLoc dl) {
3212 bool IsRHSZero = RHSValue == 0;
3213 bool IsRHSOne = RHSValue == 1;
3214 bool IsRHSNegOne = RHSValue == -1LL;
3220 SDValue Xor = IsRHSZero ? LHS :
3221 SDValue(CurDAG->getMachineNode(PPC::XOR8, dl,
MVT::i64, LHS, RHS), 0);
3225 S->getI64Imm(58, dl),
3226 S->getI64Imm(63, dl)), 0);
3233 SDValue Xor = IsRHSZero ? LHS :
3234 SDValue(CurDAG->getMachineNode(PPC::XOR8, dl,
MVT::i64, LHS, RHS), 0);
3237 Xor, S->getI32Imm(~0U, dl)), 0);
3247 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt);
3259 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LEZExt);
3262 S->getI64Imm(1, dl),
3263 S->getI64Imm(63, dl)), 0);
3266 S->getI64Imm(63, dl)), 0);
3271 ShiftR, ShiftL, SubtractCarry), 0);
3279 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GEZExt);
3283 S->getI64Imm(~0ULL, dl)), 0);
3285 SDValue(CurDAG->getMachineNode(PPC::NOR8, dl,
MVT::i64, Addi, LHS), 0);
3287 S->getI64Imm(1, dl),
3288 S->getI64Imm(63, dl)), 0);
3302 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LEZExt);
3305 S->getI64Imm(1, dl),
3306 S->getI64Imm(63, dl)), 0);
3309 LHS, S->getI64Imm(63, dl)), 0);
3312 RHS, S->getI64Imm(1, dl),
3313 S->getI64Imm(63, dl)), 0);
3319 SRDINode, SRADINode, SUBFC8Carry), 0);
3321 ADDE8Node, S->getI64Imm(1, dl)), 0);
3336 LHS, LHS, SUBFC8Carry), 0);
3338 SUBFE8Node, S->getI64Imm(1, dl)), 0);
3353 LHS, LHS, SubtractCarry), 0);
3363 IntegerCompareEliminator::get64BitSExtCompare(
SDValue LHS,
SDValue RHS,
3365 int64_t RHSValue,
SDLoc dl) {
3369 bool IsRHSZero = RHSValue == 0;
3370 bool IsRHSOne = RHSValue == 1;
3371 bool IsRHSNegOne = RHSValue == -1LL;
3379 SDValue AddInput = IsRHSZero ? LHS :
3380 SDValue(CurDAG->getMachineNode(PPC::XOR8, dl,
MVT::i64, LHS, RHS), 0);
3383 AddInput, S->getI32Imm(~0U, dl)), 0);
3384 return SDValue(CurDAG->getMachineNode(PPC::SUBFE8, dl,
MVT::i64, Addic,
3385 Addic, Addic.getValue(1)), 0);
3392 SDValue Xor = IsRHSZero ? LHS :
3393 SDValue(CurDAG->getMachineNode(PPC::XOR8, dl,
MVT::i64, LHS, RHS), 0);
3396 Xor, S->getI32Imm(0, dl)), 0);
3398 SC, SC.getValue(1)), 0);
3406 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt);
3418 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LESExt);
3421 S->getI64Imm(63, dl)), 0);
3424 S->getI64Imm(1, dl),
3425 S->getI64Imm(63, dl)), 0);
3431 ShiftR, ShiftL, SubtractCarry), 0);
3432 return SDValue(CurDAG->getMachineNode(PPC::NEG8, dl,
MVT::i64, Adde), 0);
3440 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::GESExt);
3444 S->getI64Imm(-1, dl)), 0);
3446 SDValue(CurDAG->getMachineNode(PPC::NOR8, dl,
MVT::i64, Add, LHS), 0);
3448 S->getI64Imm(63, dl)), 0);
3462 return getCompoundZeroComparisonInGPR(LHS, dl, ZeroCompare::LESExt);
3465 S->getI64Imm(63, dl)), 0);
3469 LHS, S->getI64Imm(63, dl)), 0);
3472 RHS, S->getI64Imm(1, dl),
3473 S->getI64Imm(63, dl)), 0);
3479 SRDINode, SRADINode, SUBFC8Carry), 0);
3482 ADDE8Node, S->getI64Imm(1, dl)), 0);
3499 LHS, SubtractCarry), 0);
3501 ExtSub, ExtSub), 0);
3515 LHS, LHS, SubCarry), 0);
3526 "An ISD::SETCC node required here.");
3538 !isLogicOp(CompareUse->getOpcode())) {
3539 OmittedForNonExtendUses++;
3549 SetccInGPROpts ConvOpts) {
3552 "An ISD::SETCC node required here.");
3565 cast<CondCodeSDNode>(Compare.
getOperand(CCOpNum))->
get();
3570 if (ConvOpts == SetccInGPROpts::ZExtInvert ||
3571 ConvOpts == SetccInGPROpts::SExtInvert)
3574 bool Inputs32Bit = InputVT ==
MVT::i32;
3579 bool IsSext = ConvOpts == SetccInGPROpts::SExtOrig ||
3580 ConvOpts == SetccInGPROpts::SExtInvert;
3582 if (IsSext && Inputs32Bit)
3583 return get32BitSExtCompare(LHS, RHS, CC, RHSValue, dl);
3584 else if (Inputs32Bit)
3585 return get32BitZExtCompare(LHS, RHS, CC, RHSValue, dl);
3587 return get64BitSExtCompare(LHS, RHS, CC, RHSValue, dl);
3588 return get64BitZExtCompare(LHS, RHS, CC, RHSValue, dl);
3593 bool PPCDAGToDAGISel::tryIntCompareInGPR(
SDNode *N) {
3611 IntegerCompareEliminator ICmpElim(CurDAG,
this);
3612 if (
SDNode *New = ICmpElim.Select(N)) {
3613 ReplaceNode(N, New);
3621 bool PPCDAGToDAGISel::tryBitPermutation(
SDNode *N) {
3636 BitPermutationSelector BPS(CurDAG);
3637 if (
SDNode *New = BPS.Select(N)) {
3638 ReplaceNode(N, New);
3662 getI32Imm(Imm & 0xFFFF, dl)),
3667 getI32Imm(Imm & 0xFFFF, dl)),
3680 getI32Imm(Imm >> 16, dl)), 0);
3682 getI32Imm(Imm & 0xFFFF, dl)), 0);
3688 getI32Imm(Imm & 0xFFFF, dl)), 0);
3694 getI32Imm((
int)SImm & 0xFFFF,
3706 getI32Imm(Imm & 0xFFFF, dl)),
3711 getI32Imm(Imm & 0xFFFF, dl)),
3725 getI64Imm(Imm >> 16, dl)), 0);
3727 getI64Imm(Imm & 0xFFFF, dl)),
3735 getI64Imm(Imm & 0xFFFF, dl)), 0);
3741 getI64Imm(SImm & 0xFFFF, dl)),
3746 if (PPCSubTarget->
hasSPE()) {
3751 Opc = PPC::EFSCMPEQ;
3759 Opc = PPC::EFSCMPLT;
3767 Opc = PPC::EFSCMPGT;
3773 if (PPCSubTarget->
hasSPE()) {
3778 Opc = PPC::EFDCMPEQ;
3786 Opc = PPC::EFDCMPLT;
3794 Opc = PPC::EFDCMPGT;
3798 Opc = PPCSubTarget->
hasVSX() ? PPC::XSCMPUDP : PPC::FCMPUD;
3801 assert(PPCSubTarget->
hasVSX() &&
"__float128 requires VSX");
3802 Opc = PPC::XSCMPUQP;
3804 return SDValue(CurDAG->getMachineNode(Opc, dl,
MVT::i32, LHS, RHS), 0);
3855 case ISD::SETO: Invert =
true;
return 3;
3871 bool HasVSX,
bool &Swap,
bool &Negate) {
3899 return HasVSX ? PPC::XVCMPEQSP : PPC::VCMPEQFP;
3901 return PPC::XVCMPEQDP;
3906 return HasVSX ? PPC::XVCMPGTSP : PPC::VCMPGTFP;
3908 return PPC::XVCMPGTDP;
3913 return HasVSX ? PPC::XVCMPGESP : PPC::VCMPGEFP;
3915 return PPC::XVCMPGEDP;
3943 return PPC::VCMPEQUB;
3945 return PPC::VCMPEQUH;
3947 return PPC::VCMPEQUW;
3949 return PPC::VCMPEQUD;
3953 return PPC::VCMPGTSB;
3955 return PPC::VCMPGTSH;
3957 return PPC::VCMPGTSW;
3959 return PPC::VCMPGTSD;
3963 return PPC::VCMPGTUB;
3965 return PPC::VCMPGTUH;
3967 return PPC::VCMPGTUW;
3969 return PPC::VCMPGTUD;
3978 bool PPCDAGToDAGISel::trySETCC(
SDNode *N) {
3983 CurDAG->getTargetLoweringInfo().getPointerTy(CurDAG->getDataLayout());
3984 bool isPPC64 = (PtrVT ==
MVT::i64);
3996 Op =
SDValue(CurDAG->getMachineNode(PPC::CNTLZW, dl,
MVT::i32, Op), 0);
3997 SDValue Ops[] = {
Op, getI32Imm(27, dl), getI32Imm(5, dl),
3998 getI32Imm(31, dl) };
3999 CurDAG->SelectNodeTo(N, PPC::RLWINM,
MVT::i32, Ops);
4006 Op, getI32Imm(~0U, dl)), 0);
4011 SDValue Ops[] = {
Op, getI32Imm(1, dl), getI32Imm(31, dl),
4012 getI32Imm(31, dl) };
4013 CurDAG->SelectNodeTo(N, PPC::RLWINM,
MVT::i32, Ops);
4019 T =
SDValue(CurDAG->getMachineNode(PPC::ANDC, dl,
MVT::i32, T, Op), 0);
4020 SDValue Ops[] = {
T, getI32Imm(1, dl), getI32Imm(31, dl),
4021 getI32Imm(31, dl) };
4022 CurDAG->SelectNodeTo(N, PPC::RLWINM,
MVT::i32, Ops);
4026 }
else if (Imm == ~0U) {
4033 Op, getI32Imm(1, dl)), 0);
4034 CurDAG->SelectNodeTo(N, PPC::ADDZE,
MVT::i32,
4035 SDValue(CurDAG->getMachineNode(PPC::LI, dl,
4042 Op =
SDValue(CurDAG->getMachineNode(PPC::NOR, dl,
MVT::i32, Op, Op), 0);
4044 Op, getI32Imm(~0U, dl));
4051 getI32Imm(1, dl)), 0);
4054 SDValue Ops[] = { AN, getI32Imm(1, dl), getI32Imm(31, dl),
4055 getI32Imm(31, dl) };
4056 CurDAG->SelectNodeTo(N, PPC::RLWINM,
MVT::i32, Ops);
4060 SDValue Ops[] = {
Op, getI32Imm(1, dl), getI32Imm(31, dl),
4061 getI32Imm(31, dl) };
4062 Op =
SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl,
MVT::i32, Ops), 0);
4063 CurDAG->SelectNodeTo(N, PPC::XORI,
MVT::i32, Op, getI32Imm(1, dl));
4082 PPCSubTarget->
hasVSX(), Swap, Negate);
4088 SDValue VCmp(CurDAG->getMachineNode(VCmpInst, dl, ResVT, LHS, RHS), 0);
4089 CurDAG->SelectNodeTo(N, PPCSubTarget->
hasVSX() ? PPC::XXLNOR :
PPC::VNOR,
4094 CurDAG->SelectNodeTo(N, VCmpInst, ResVT, LHS, RHS);
4103 SDValue CCReg = SelectCC(LHS, RHS, CC, dl);
4116 CCReg = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, CR7Reg, CCReg,
4117 InFlag).getValue(1);
4122 SDValue Ops[] = { IntCR, getI32Imm((32 - (3 - Idx)) & 31, dl),
4123 getI32Imm(31, dl), getI32Imm(31, dl) };
4125 CurDAG->SelectNodeTo(N, PPC::RLWINM,
MVT::i32, Ops);
4132 CurDAG->SelectNodeTo(N, PPC::XORI,
MVT::i32, Tmp, getI32Imm(1, dl));
4138 bool PPCDAGToDAGISel::isOffsetMultipleOf(
SDNode *N,
unsigned Val)
const {
4151 AddrOp.getOpcode() ==
ISD::ADD ? AddrOp.getOperand(0) :
4158 if ((SlotAlign % Val) != 0)
4162 if (AddrOp.getOpcode() !=
ISD::ADD)
4166 if (AddrOp.getOpcode() ==
ISD::ADD)
4173 void PPCDAGToDAGISel::transferMemOperands(
SDNode *N,
SDNode *Result) {
4176 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Result), {MemOp});
4180 bool &NeedSwapOps,
bool &IsUnCmp) {
4194 "Expecting either i64 or i32 here.");
4202 if ((TrueResVal < -1 || TrueResVal > 1) ||
4229 cast<CondCodeSDNode>(SetOrSelCC.
getOperand(InnerIsSel ? 4 : 2))->
get();
4237 if (!SelCCTrueConst || !SelCCFalseConst)
4240 int64_t SelCCFVal = SelCCFalseConst->getSExtValue();
4242 if (SelCCTVal == -1 && SelCCFVal == 1) {
4244 }
else if (SelCCTVal != 1 || SelCCFVal != -1)
4254 bool InnerSwapped =
false;
4255 if (LHS == InnerRHS && RHS == InnerLHS)
4256 InnerSwapped =
true;
4257 else if (LHS != InnerLHS || RHS != InnerRHS)
4268 NeedSwapOps = (InnerCC ==
ISD::SETGT) ? InnerSwapped : !InnerSwapped;
4285 NeedSwapOps = (TrueResVal == 1);
4304 NeedSwapOps = (TrueResVal == -1);
4313 LLVM_DEBUG(
dbgs() <<
"Found a node that can be lowered to a SETB: ");
4336 if (tryBitPermutation(N))
4340 if (tryIntCompareInGPR(N))
4361 if (PPCLowering->getPointerTy(CurDAG->getDataLayout()) !=
MVT::i32 ||
4380 ReplaceNode(N, getGlobalBaseReg());
4384 selectFrameIndex(N, N);
4402 CurDAG->getTargetConstant(*cast<ConstantSDNode>(N->
getOperand(1))->
4403 getConstantIntValue(), dl,
4414 "Expecting i64 or i32 in PPCISD::SRA_ADDZE");
4429 if (tryTLSXFormStore(ST))
4442 if (tryTLSXFormLoad(LD))
4455 assert((!isSExt || LoadedVT ==
MVT::i16) &&
"Invalid sext update load");
4456 switch (LoadedVT.getSimpleVT().SimpleTy) {
4458 case MVT::f64: Opcode = PPC::LFDU;
break;
4459 case MVT::f32: Opcode = PPC::LFSU;
break;
4460 case MVT::i32: Opcode = PPC::LWZU;
break;
4461 case MVT::i16: Opcode = isSExt ? PPC::LHAU : PPC::LHZU;
break;
4463 case MVT::i8: Opcode = PPC::LBZU;
break;
4467 assert((!isSExt || LoadedVT ==
MVT::i16) &&
"Invalid sext update load");
4468 switch (LoadedVT.getSimpleVT().SimpleTy) {
4470 case MVT::i64: Opcode = PPC::LDU;
break;
4471 case MVT::i32: Opcode = PPC::LWZU8;
break;
4472 case MVT::i16: Opcode = isSExt ? PPC::LHAU8 : PPC::LHZU8;
break;
4474 case MVT::i8: Opcode = PPC::LBZU8;
break;
4481 SDNode *MN = CurDAG->getMachineNode(
4483 PPCLowering->getPointerTy(CurDAG->getDataLayout()),
MVT::Other, Ops);
4484 transferMemOperands(N, MN);
4492 assert((!isSExt || LoadedVT ==
MVT::i16) &&
"Invalid sext update load");
4493 switch (LoadedVT.getSimpleVT().SimpleTy) {
4495 case MVT::v4f64: Opcode = PPC::QVLFDUX;
break;
4496 case MVT::v4f32: Opcode = PPC::QVLFSUX;
break;
4497 case MVT::f64: Opcode = PPC::LFDUX;
break;
4498 case MVT::f32: Opcode = PPC::LFSUX;
break;
4499 case MVT::i32: Opcode = PPC::LWZUX;
break;
4500 case MVT::i16: Opcode = isSExt ? PPC::LHAUX : PPC::LHZUX;
break;
4502 case MVT::i8: Opcode = PPC::LBZUX;
break;
4507 "Invalid sext update load");
4508 switch (LoadedVT.getSimpleVT().SimpleTy) {
4510 case MVT::i64: Opcode = PPC::LDUX;
break;
4511 case MVT::i32: Opcode = isSExt ? PPC::LWAUX : PPC::LWZUX8;
break;
4512 case MVT::i16: Opcode = isSExt ? PPC::LHAUX8 : PPC::LHZUX8;
break;
4514 case MVT::i8: Opcode = PPC::LBZUX8;
break;
4521 SDNode *MN = CurDAG->getMachineNode(
4523 PPCLowering->getPointerTy(CurDAG->getDataLayout()),
MVT::Other, Ops);
4524 transferMemOperands(N, MN);
4531 unsigned Imm, Imm2, SH, MB, ME;
4539 SDValue Ops[] = { Val, getI32Imm(SH, dl), getI32Imm(MB, dl),
4540 getI32Imm(ME, dl) };
4541 CurDAG->SelectNodeTo(N, PPC::RLWINM,
MVT::i32, Ops);
4550 SDValue Ops[] = { Val, getI32Imm(0, dl), getI32Imm(MB, dl),
4551 getI32Imm(ME, dl) };
4552 CurDAG->SelectNodeTo(N, PPC::RLWINM,
MVT::i32, Ops);
4564 if ( Op0.getOpcode() ==
ISD::SRL &&
4568 auto ImDef = CurDAG->getMachineNode(PPC::IMPLICIT_DEF, dl,
4572 Val =
SDValue(CurDAG->getMachineNode(PPC::INSERT_SUBREG, dl,
4574 getI32Imm(1, dl)), 0);
4586 assert(Imm < 64 &&
"Illegal shift amount");
4591 SDValue Ops[] = { Val, getI32Imm(SH, dl), getI32Imm(MB, dl) };
4592 CurDAG->SelectNodeTo(N, PPC::RLDICL,
MVT::i64, Ops);
4603 SDValue Ops[] = { Val, getI32Imm(SH, dl), getI32Imm(MB, dl) };
4604 CurDAG->SelectNodeTo(N, PPC::RLDICR,
MVT::i64, Ops);
4632 if (
isRunOfOnes(~(Imm^Imm2), MB, ME) && !(~Imm & Imm2)) {
4635 getI32Imm(0, dl), getI32Imm(MB, dl),
4636 getI32Imm(ME, dl) };
4637 ReplaceNode(N, CurDAG->getMachineNode(PPC::RLWIMI, dl,
MVT::i32, Ops));
4647 if (tryBitfieldInsert(N))
4666 bool IsPPC64 = PPCSubTarget->
isPPC64();
4668 (Imm64 & ~0xFFFFFFFFuLL) == 0) {
4670 uint64_t ImmHi = Imm64 >> 16;
4671 uint64_t ImmLo = Imm64 & 0xFFFF;
4672 if (ImmHi != 0 && ImmLo != 0) {
4675 getI16Imm(ImmLo, dl));
4677 CurDAG->SelectNodeTo(N, PPC::ORIS8,
MVT::i64, Ops1);
4689 bool IsPPC64 = PPCSubTarget->
isPPC64();
4691 (Imm64 & ~0xFFFFFFFFuLL) == 0) {
4693 uint64_t ImmHi = Imm64 >> 16;
4694 uint64_t ImmLo = Imm64 & 0xFFFF;
4695 if (ImmHi != 0 && ImmLo != 0) {
4698 getI16Imm(ImmLo, dl));
4700 CurDAG->SelectNodeTo(N, PPC::XORIS8,
MVT::i64, Ops1);
4718 unsigned Imm, SH, MB, ME;
4720 isRotateAndMask(N, Imm,
true, SH, MB, ME)) {
4722 getI32Imm(SH, dl), getI32Imm(MB, dl),
4723 getI32Imm(ME, dl) };
4724 CurDAG->SelectNodeTo(N, PPC::RLWINM,
MVT::i32, Ops);
4732 unsigned Imm, SH, MB, ME;
4734 isRotateAndMask(N, Imm,
true, SH, MB, ME)) {
4736 getI32Imm(SH, dl), getI32Imm(MB, dl),
4737 getI32Imm(ME, dl) };
4738 CurDAG->SelectNodeTo(N, PPC::RLWINM,
MVT::i32, Ops);
4753 "Invalid input type for ANDIo_1_EQ_BIT");
4755 unsigned Opcode = (InVT ==
MVT::i64) ? PPC::ANDIo8 : PPC::ANDIo;
4758 CurDAG->getTargetConstant(1, dl, InVT)),
4763 PPC::sub_eq : PPC::sub_gt, dl,
MVT::i32);
4765 CurDAG->SelectNodeTo(N, TargetOpcode::EXTRACT_SUBREG,
MVT::i1, CR0Reg,
4772 CurDAG->getTargetLoweringInfo().getPointerTy(CurDAG->getDataLayout());
4773 bool isPPC64 = (PtrVT ==
MVT::i64);
4781 bool NeedSwapOps =
false;
4782 bool IsUnCmp =
false;
4783 if (
mayUseP9Setb(N, CC, CurDAG, NeedSwapOps, IsUnCmp)) {
4797 CurDAG->SelectNodeTo(
4810 if (N1C->isNullValue() && N3C->isNullValue() &&
4811 N2C->getZExtValue() == 1ULL && CC ==
ISD::SETNE &&
4832 case 0: SRI = PPC::sub_lt;
break;
4833 case 1: SRI = PPC::sub_gt;
break;
4834 case 2: SRI = PPC::sub_eq;
break;
4835 case 3: SRI = PPC::sub_un;
break;
4838 SDValue CCBit = CurDAG->getTargetExtractSubreg(SRI, dl,
MVT::i1, CCReg);
4842 SDValue C = Inv ? NotCCBit : CCBit,
4843 NotC = Inv ? CCBit : NotCCBit;
4850 CurDAG->SelectNodeTo(N, PPC::CROR,
MVT::i1, CAndT, NotCAndF);
4856 unsigned SelectCCOp;
4858 SelectCCOp = PPC::SELECT_CC_I4;
4860 SelectCCOp = PPC::SELECT_CC_I8;
4863 SelectCCOp = PPC::SELECT_CC_VSSRC;
4864 else if (PPCSubTarget->
hasSPE())
4865 SelectCCOp = PPC::SELECT_CC_SPE4;
4867 SelectCCOp = PPC::SELECT_CC_F4;
4869 if (PPCSubTarget->
hasVSX())
4870 SelectCCOp = PPC::SELECT_CC_VSFRC;
4871 else if (PPCSubTarget->
hasSPE())
4872 SelectCCOp = PPC::SELECT_CC_SPE;
4874 SelectCCOp = PPC::SELECT_CC_F8;
4876 SelectCCOp = PPC::SELECT_CC_F16;
4877 else if (PPCSubTarget->
hasSPE())
4878 SelectCCOp = PPC::SELECT_CC_SPE;
4880 SelectCCOp = PPC::SELECT_CC_QFRC;
4882 SelectCCOp = PPC::SELECT_CC_QSRC;
4884 SelectCCOp = PPC::SELECT_CC_QBRC;
4887 SelectCCOp = PPC::SELECT_CC_VSRC;
4889 SelectCCOp = PPC::SELECT_CC_VRRC;
4892 getI32Imm(BROpc, dl) };
4893 CurDAG->SelectNodeTo(N, SelectCCOp, N->
getValueType(0), Ops);
4905 for (
int i = 0; i < 2; ++i)
4911 if (Op1 == Op2 && DM[0] == 0 && DM[1] == 0 &&
4913 isa<LoadSDNode>(Op1.getOperand(0))) {
4914 LoadSDNode *LD = cast<LoadSDNode>(Op1.getOperand(0));
4924 SDNode *NewN = CurDAG->SelectNodeTo(N, PPC::LXVDSX,
4926 CurDAG->setNodeMemRefs(cast<MachineSDNode>(NewN), {MemOp});
4935 unsigned tmp = DM[0];
4940 SDValue DMV = CurDAG->getTargetConstant(DM[1] | (DM[0] << 1), dl,
4942 SDValue Ops[] = { Op1, Op2, DMV };
4950 bool IsPPC64 = PPCSubTarget->
isPPC64();
4954 : (IsPPC64 ? PPC::BDZ8 :
PPC::BDZ),
4965 unsigned PCC = cast<ConstantSDNode>(N->
getOperand(1))->getZExtValue();
4969 SDValue Pred = getI32Imm(PCC, dl);
4972 CurDAG->SelectNodeTo(N, PPC::BCC,
MVT::Other, Ops);
4984 case PPC::PRED_LT: Opc = PPC::CRANDC; Swap =
true;
break;
4985 case PPC::PRED_LE: Opc = PPC::CRORC; Swap =
true;
break;
4986 case PPC::PRED_EQ: Opc = PPC::CREQV; Swap =
false;
break;
4987 case PPC::PRED_GE: Opc = PPC::CRORC; Swap =
false;
break;
4988 case PPC::PRED_GT: Opc = PPC::CRANDC; Swap =
false;
break;
4989 case PPC::PRED_NE: Opc = PPC::CRXOR; Swap =
false;
break;
5015 CurDAG->SelectNodeTo(N, PPC::BCC,
MVT::Other, Ops);
5026 CurDAG->SelectNodeTo(N, Reg,
MVT::Other, Chain);
5031 "Only supported for 64-bit ABI and 32-bit SVR4");
5034 SDNode *MN = CurDAG->getMachineNode(PPC::LWZtoc, dl,
MVT::i32, GA,
5036 transferMemOperands(N, MN);
5055 SDNode *Tmp = CurDAG->getMachineNode(PPC::ADDIStocHA, dl,
MVT::i64,
5057 if (PPCLowering->isAccessedAsGotIndirect(GA)) {
5060 SDNode *MN = CurDAG->getMachineNode(PPC::LDtocL, dl,
MVT::i64, GA,
5062 transferMemOperands(N, MN);
5068 ReplaceNode(N, CurDAG->getMachineNode(PPC::ADDItocL, dl,
MVT::i64,
5075 "PPCISD::PPC32_PICGOT is only supported for 32-bit SVR4");
5076 CurDAG->SelectNodeTo(N, PPC::PPC32PICGOT,
5077 PPCLowering->getPointerTy(CurDAG->getDataLayout()),
5086 "Invalid operand on VADD_SPLAT!");
5090 unsigned Opc1, Opc2, Opc3;
5094 Opc1 = PPC::VSPLTISB;
5095 Opc2 = PPC::VADDUBM;
5096 Opc3 = PPC::VSUBUBM;
5098 }
else if (EltSize == 2) {
5099 Opc1 = PPC::VSPLTISH;
5100 Opc2 = PPC::VADDUHM;
5101 Opc3 = PPC::VSUBUHM;
5104 assert(EltSize == 4 &&
"Invalid element size on VADD_SPLAT!");
5105 Opc1 = PPC::VSPLTISW;
5106 Opc2 = PPC::VADDUWM;
5107 Opc3 = PPC::VSUBUWM;
5111 if ((Elt & 1) == 0) {
5118 SDValue EltVal = getI32Imm(Elt >> 1, dl);
5119 SDNode *Tmp = CurDAG->getMachineNode(Opc1, dl, VT, EltVal);
5121 ReplaceNode(N, CurDAG->getMachineNode(Opc2, dl, VT, TmpVal, TmpVal));
5123 }
else if (Elt > 0) {
5130 SDValue EltVal = getI32Imm(Elt - 16, dl);
5131 SDNode *Tmp1 = CurDAG->getMachineNode(Opc1, dl, VT, EltVal);
5132 EltVal = getI32Imm(-16, dl);
5133 SDNode *Tmp2 = CurDAG->getMachineNode(Opc1, dl, VT, EltVal);
5134 ReplaceNode(N, CurDAG->getMachineNode(Opc3, dl, VT,
SDValue(Tmp1, 0),
5144 SDValue EltVal = getI32Imm(Elt + 16, dl);
5145 SDNode *Tmp1 = CurDAG->getMachineNode(Opc1, dl, VT, EltVal);
5146 EltVal = getI32Imm(-16, dl);
5147 SDNode *Tmp2 = CurDAG->getMachineNode(Opc1, dl, VT, EltVal);
5148 ReplaceNode(N, CurDAG->getMachineNode(Opc2, dl, VT,
SDValue(Tmp1, 0),
5168 "Only OR nodes are supported for CMPB");
5181 bool BytesFound[8] = {
false,
false,
false,
false,
false,
false,
false,
false};
5182 uint64_t Mask = 0, Alt = 0;
5184 auto IsByteSelectCC = [
this](
SDValue O,
unsigned &b,
5185 uint64_t &
Mask, uint64_t &Alt,
5197 for (b = 0; b < 8; ++b) {
5198 uint64_t Mask = UINT64_C(0xFF) << (8*b);
5199 if (PM && (PM & Mask) == PM && (PAlt &
Mask) == PAlt)
5243 if (ULim != (UINT64_C(1) << b*8))
5249 if (!CurDAG->MaskedValueIsZero(
5304 while (!Queue.
empty()) {
5309 uint64_t M = 0, A = 0;
5313 }
else if (IsByteSelectCC(O, b, M, A, OLHS, ORHS)) {
5317 BytesFound[b] =
true;
5320 }
else if ((LHS == ORHS && RHS == OLHS) ||
5321 (RHS == ORHS && LHS == OLHS)) {
5322 BytesFound[b] =
true;
5334 unsigned LastB = 0, BCnt = 0;
5335 for (
unsigned i = 0; i < 8; ++i)
5336 if (BytesFound[LastB]) {
5341 if (!LastB || BCnt < 2)
5346 if (LHS.getValueType() != VT) {
5347 LHS = CurDAG->getAnyExtOrTrunc(LHS, dl, VT);
5348 RHS = CurDAG->getAnyExtOrTrunc(RHS, dl, VT);
5353 bool NonTrivialMask = ((int64_t) Mask) != INT64_C(-1);
5354 if (NonTrivialMask && !Alt) {
5356 Res = CurDAG->getNode(
ISD::AND, dl, VT, Res,
5357 CurDAG->getConstant(Mask, dl, VT));
5365 Res = CurDAG->getNode(
ISD::AND, dl, VT, Res,
5366 CurDAG->getConstant(Mask ^ Alt, dl, VT));
5367 Res = CurDAG->getNode(
ISD::XOR, dl, VT, Res,
5368 CurDAG->getConstant(Alt, dl, VT));
5381 void PPCDAGToDAGISel::foldBoolExts(
SDValue &Res,
SDNode *&N) {
5401 SDValue ConstFalse = CurDAG->getConstant(0, dl, VT);
5408 auto TryFold = [
this,
N, User, dl](
SDValue Val) {
5413 return CurDAG->FoldConstantArithmetic(User->getOpcode(), dl,
5414 User->getValueType(0),
5420 SDValue TrueRes = TryFold(ConstTrue);
5421 if (!TrueRes || TrueRes.
isUndef())
5423 SDValue FalseRes = TryFold(ConstFalse);
5424 if (!FalseRes || FalseRes.
isUndef())
5429 uint64_t True = cast<ConstantSDNode>(TrueRes)->getZExtValue(),
5430 False = cast<ConstantSDNode>(FalseRes)->getZExtValue();
5436 Res = CurDAG->getSelect(dl, User->getValueType(0), Cond, TrueRes, FalseRes);
5438 ConstTrue = TrueRes;
5439 ConstFalse = FalseRes;
5443 void PPCDAGToDAGISel::PreprocessISelDAG() {
5446 bool MadeChange =
false;
5447 while (Position != CurDAG->allnodes_begin()) {
5456 Res = combineToCMPB(N);
5461 foldBoolExts(Res, N);
5470 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(N, 0), Res);
5476 CurDAG->RemoveDeadNodes();
5481 void PPCDAGToDAGISel::PostprocessISelDAG() {
5488 PeepholePPC64ZExt();
5496 bool PPCDAGToDAGISel::AllUsersSelectZero(
SDNode *N) {
5525 void PPCDAGToDAGISel::SwapAllSelectUsers(
SDNode *N) {
5532 "Must have all select users");
5537 UE = ToReplace.
end(); UI != UE; ++UI) {
5551 ReplaceUses(User, ResNode);
5555 void PPCDAGToDAGISel::PeepholeCROps() {
5559 for (
SDNode &Node : CurDAG->allnodes()) {
5561 if (!MachineNode || MachineNode->
use_empty())
5563 SDNode *ResNode = MachineNode;
5565 bool Op1Set =
false, Op1Unset =
false,
5567 Op2Set =
false, Op2Unset =
false,
5595 case PPC::SELECT_I4:
5596 case PPC::SELECT_I8:
5597 case PPC::SELECT_F4:
5598 case PPC::SELECT_F8:
5599 case PPC::SELECT_QFRC:
5600 case PPC::SELECT_QSRC:
5601 case PPC::SELECT_QBRC:
5602 case PPC::SELECT_SPE:
5603 case PPC::SELECT_SPE4:
5604 case PPC::SELECT_VRRC:
5605 case PPC::SELECT_VSFRC:
5606 case PPC::SELECT_VSSRC:
5607 case PPC::SELECT_VSRC: {
5622 bool SelectSwap =
false;
5635 else if (Op1Unset || Op2Unset)
5637 ResNode = CurDAG->getMachineNode(PPC::CRUNSET,
SDLoc(MachineNode),
5641 ResNode = CurDAG->getMachineNode(PPC::CRANDC,
SDLoc(MachineNode),
5647 ResNode = CurDAG->getMachineNode(PPC::CRANDC,
SDLoc(MachineNode),
5651 else if (AllUsersSelectZero(MachineNode)) {
5652 ResNode = CurDAG->getMachineNode(PPC::CRNAND,
SDLoc(MachineNode),
5661 ResNode = CurDAG->getMachineNode(PPC::CRNOR,
SDLoc(MachineNode),
5666 ResNode = CurDAG->getMachineNode(PPC::CRNOR,
SDLoc(MachineNode),
5671 ResNode = CurDAG->getMachineNode(PPC::CRNOR,
SDLoc(MachineNode),
5674 else if (Op1Unset || Op2Unset)
5676 ResNode = CurDAG->getMachineNode(PPC::CRSET,
SDLoc(MachineNode),
5680 ResNode = CurDAG->getMachineNode(PPC::CRORC,
SDLoc(MachineNode),
5686 ResNode = CurDAG->getMachineNode(PPC::CRORC,
SDLoc(MachineNode),
5690 else if (AllUsersSelectZero(MachineNode)) {
5691 ResNode = CurDAG->getMachineNode(PPC::CRAND,
SDLoc(MachineNode),
5701 else if (Op1Set || Op2Set)
5703 ResNode = CurDAG->getMachineNode(PPC::CRSET,
SDLoc(MachineNode),
5713 ResNode = CurDAG->getMachineNode(PPC::CRORC,
SDLoc(MachineNode),
5719 ResNode = CurDAG->getMachineNode(PPC::CRORC,
SDLoc(MachineNode),
5723 else if (AllUsersSelectZero(MachineNode)) {
5724 ResNode = CurDAG->getMachineNode(PPC::CRNOR,
SDLoc(MachineNode),
5733 ResNode = CurDAG->getMachineNode(PPC::CRUNSET,
SDLoc(MachineNode),
5737 ResNode = CurDAG->getMachineNode(PPC::CRNOR,
SDLoc(MachineNode),
5742 ResNode = CurDAG->getMachineNode(PPC::CRNOR,
SDLoc(MachineNode),
5753 ResNode = CurDAG->getMachineNode(PPC::CREQV,
SDLoc(MachineNode),
5759 ResNode = CurDAG->getMachineNode(PPC::CREQV,
SDLoc(MachineNode),
5763 else if (AllUsersSelectZero(MachineNode)) {
5764 ResNode = CurDAG->getMachineNode(PPC::CREQV,
SDLoc(MachineNode),
5771 if (Op1Set || Op2Set)
5773 ResNode = CurDAG->getMachineNode(PPC::CRUNSET,
SDLoc(MachineNode),
5777 ResNode = CurDAG->getMachineNode(PPC::CRNOR,
SDLoc(MachineNode),
5782 ResNode = CurDAG->getMachineNode(PPC::CRNOR,
SDLoc(MachineNode),
5787 ResNode = CurDAG->getMachineNode(PPC::CRANDC,
SDLoc(MachineNode),
5793 ResNode = CurDAG->getMachineNode(PPC::CRANDC,
SDLoc(MachineNode),
5797 else if (AllUsersSelectZero(MachineNode)) {
5798 ResNode = CurDAG->getMachineNode(PPC::CROR,
SDLoc(MachineNode),
5807 ResNode = CurDAG->getMachineNode(PPC::CRSET,
SDLoc(MachineNode),
5817 ResNode = CurDAG->getMachineNode(PPC::CRNOR,
SDLoc(MachineNode),
5822 ResNode = CurDAG->getMachineNode(PPC::CRNOR,
SDLoc(MachineNode),
5827 ResNode = CurDAG->getMachineNode(PPC::CRXOR,
SDLoc(MachineNode),
5833 ResNode = CurDAG->getMachineNode(PPC::CRXOR,
SDLoc(MachineNode),
5837 else if (AllUsersSelectZero(MachineNode)) {
5838 ResNode = CurDAG->getMachineNode(PPC::CRXOR,
SDLoc(MachineNode),
5847 ResNode = CurDAG->getMachineNode(PPC::CRUNSET,
SDLoc(MachineNode),
5851 ResNode = CurDAG->getMachineNode(PPC::CRNOR,
SDLoc(MachineNode),
5854 else if (Op1Unset || Op2Set)
5856 ResNode = CurDAG->getMachineNode(PPC::CRUNSET,
SDLoc(MachineNode),
5863 ResNode = CurDAG->getMachineNode(PPC::CRNOR,
SDLoc(MachineNode),
5869 ResNode = CurDAG->getMachineNode(PPC::CRAND,
SDLoc(MachineNode),
5873 else if (AllUsersSelectZero(MachineNode)) {
5874 ResNode = CurDAG->getMachineNode(PPC::CRORC,
SDLoc(MachineNode),
5883 ResNode = CurDAG->getMachineNode(PPC::CRSET,
SDLoc(MachineNode),
5885 else if (Op1Set || Op2Unset)
5887 ResNode = CurDAG->getMachineNode(PPC::CRSET,
SDLoc(MachineNode),
5894 ResNode = CurDAG->getMachineNode(PPC::CRNOR,
SDLoc(MachineNode),
5899 ResNode = CurDAG->getMachineNode(PPC::CRNAND,
SDLoc(MachineNode),
5905 ResNode = CurDAG->getMachineNode(PPC::CROR,
SDLoc(MachineNode),
5909 else if (AllUsersSelectZero(MachineNode)) {
5910 ResNode = CurDAG->getMachineNode(PPC::CRANDC,
SDLoc(MachineNode),
5916 case PPC::SELECT_I4:
5917 case PPC::SELECT_I8:
5918 case PPC::SELECT_F4:
5919 case PPC::SELECT_F8:
5920 case PPC::SELECT_QFRC:
5921 case PPC::SELECT_QSRC:
5922 case PPC::SELECT_QBRC:
5923 case PPC::SELECT_SPE:
5924 case PPC::SELECT_SPE4:
5925 case PPC::SELECT_VRRC:
5926 case PPC::SELECT_VSFRC:
5927 case PPC::SELECT_VSSRC:
5928 case PPC::SELECT_VSRC:
5945 ResNode = CurDAG->getMachineNode(Opcode == PPC::BC ? PPC::BCn :
5960 SwapAllSelectUsers(MachineNode);
5962 if (ResNode != MachineNode) {
5969 ReplaceUses(MachineNode, ResNode);
5974 CurDAG->RemoveDeadNodes();
5975 }
while (IsModified);
6086 if (!Op0OK && !Op1OK)
6109 if (!Op0OK && !Op1OK)
6123 void PPCDAGToDAGISel::PeepholePPC64ZExt() {
6138 bool MadeChange =
false;
6139 while (Position != CurDAG->allnodes_begin()) {
6184 bool OutsideUse =
false;
6185 for (
SDNode *PN : ToPromote) {
6187 if (!ToPromote.count(UN) && UN != ISR.
getNode()) {
6205 for (
SDNode *PN : ToPromote) {
6207 switch (PN->getMachineOpcode()) {
6210 case PPC::RLWINM: NewOpcode = PPC::RLWINM8;
break;
6211 case PPC::RLWNM: NewOpcode = PPC::RLWNM8;
break;
6212 case PPC::SLW: NewOpcode = PPC::SLW8;
break;
6213 case PPC::SRW: NewOpcode = PPC::SRW8;
break;
6214 case PPC::LI: NewOpcode = PPC::LI8;
break;
6215 case PPC::LIS: NewOpcode = PPC::LIS8;
break;
6216 case PPC::LHBRX: NewOpcode = PPC::LHBRX8;
break;
6217 case PPC::LWBRX: NewOpcode = PPC::LWBRX8;
break;
6218 case PPC::CNTLZW: NewOpcode = PPC::CNTLZW8;
break;
6219 case PPC::CNTTZW: NewOpcode = PPC::CNTTZW8;
break;
6220 case PPC::RLWIMI: NewOpcode = PPC::RLWIMI8;
break;
6221 case PPC::OR: NewOpcode = PPC::OR8;
break;
6222 case PPC::SELECT_I4: NewOpcode = PPC::SELECT_I8;
break;
6223 case PPC::ORI: NewOpcode = PPC::ORI8;
break;
6224 case PPC::ORIS: NewOpcode = PPC::ORIS8;
break;
6225 case PPC::AND: NewOpcode = PPC::AND8;
break;
6226 case PPC::ANDIo: NewOpcode = PPC::ANDIo8;
break;
6227 case PPC::ANDISo: NewOpcode = PPC::ANDISo8;
break;
6237 if (!ToPromote.count(V.getNode()) && V.getValueType() ==
MVT::i32 &&
6238 !isa<ConstantSDNode>(V)) {
6241 CurDAG->getMachineNode(TargetOpcode::INSERT_SUBREG,
SDLoc(V),
6255 for (
unsigned i = 0, ie = VTs.
NumVTs; i != ie; ++i)
6264 CurDAG->SelectNodeTo(PN, NewOpcode, CurDAG->getVTList(NewVTs), Ops);
6281 ReplaceUses(N, Op32.
getNode());
6285 CurDAG->RemoveDeadNodes();
6288 void PPCDAGToDAGISel::PeepholePPC64() {
6295 while (Position != CurDAG->allnodes_begin()) {
6303 bool RequiresMod4Offset =
false;
6305 switch (StorageOpcode) {
6310 case PPC::DFLOADf64:
6311 case PPC::DFLOADf32:
6312 RequiresMod4Offset =
true;
6328 case PPC::DFSTOREf64:
6329 case PPC::DFSTOREf32:
6330 RequiresMod4Offset =
true;
6348 if (!isa<ConstantSDNode>(N->
getOperand(FirstOp)))
6356 bool ReplaceFlags =
true;
6376 ReplaceFlags =
false;
6380 if (RequiresMod4Offset &&
6385 case PPC::ADDIdtprelL:
6388 case PPC::ADDItlsldL:
6402 int MaxDisplacement = 7;
6405 MaxDisplacement = std::min((
int) GV->
getAlignment() - 1, MaxDisplacement);
6408 bool UpdateHBase =
false;
6413 if (Offset < 0 || Offset > MaxDisplacement) {
6428 if (HImmOpnd != ImmOpnd)
6439 if (
auto *
C = dyn_cast<ConstantSDNode>(ImmOpnd)) {
6440 Offset +=
C->getSExtValue();
6442 if (RequiresMod4Offset && (Offset % 4) != 0)
6448 ImmOpnd = CurDAG->getTargetConstant(Offset,
SDLoc(ImmOpnd),
6450 }
else if (Offset != 0) {
6459 LLVM_DEBUG(
dbgs() <<
"Folding add-immediate into mem-op:\nBase: ");
6474 (RequiresMod4Offset || (Offset % 4) != 0)) {
6475 LLVM_DEBUG(
dbgs() <<
"Rejected this candidate for alignment.\n\n");
6478 ImmOpnd = CurDAG->getTargetGlobalAddress(GV, dl,
MVT::i64, Offset, Flags);
6480 dyn_cast<ConstantPoolSDNode>(ImmOpnd)) {
6482 ImmOpnd = CurDAG->getTargetConstantPool(C,
MVT::i64,
6489 (void)CurDAG->UpdateNodeOperands(N, N->
getOperand(0), ImmOpnd,
6492 (void)CurDAG->UpdateNodeOperands(N, ImmOpnd, Base.
getOperand(0),
6501 CurDAG->RemoveDeadNode(Base.
getNode());
6510 return new PPCDAGToDAGISel(TM, OptLevel);
constexpr bool isUInt< 32 >(uint64_t x)
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOffset() const
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
T findLastSet(T Val, ZeroBehavior ZB=ZB_Max)
Get the index of the last set bit starting from the least significant bit.
uint64_t getZExtValue() const
Get zero extended value.
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
static cl::opt< bool > UseBitPermRewriter("ppc-use-bit-perm-rewriter", cl::init(true), cl::desc("use aggressive ppc isel for bit permutations"), cl::Hidden)
BR_CC - Conditional branch.
This class represents lattice values for constants.
GPRC = address of GLOBAL_OFFSET_TABLE.
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
static unsigned index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
A Module instance is used to store all the information related to an LLVM module. ...
bool isPPC64() const
isPPC64 - Return true if we are generating code for 64-bit pointer mode.
BasicBlock * getSuccessor(unsigned Idx) const
Return the specified successor. This instruction must be a terminator.
const SDValue & getBasePtr() const
void push_back(const T &Elt)
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded during instruction selection to optimi...
static int getRecordFormOpcode(unsigned Opcode)
const SDValue & getValue() const
SDVTList getVTList() const
static unsigned selectI64ImmInstrCountDirect(int64_t Imm)
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
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.")))
An efficient, type-erasing, non-owning reference to a callable.
const SDValue & getChain() const
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc, or post-dec.
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)
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
bool isBitwiseNot(SDValue V)
Returns true if V is a bitwise not operation.
constexpr bool isInt< 16 >(int64_t x)
static bool isInt32Immediate(SDNode *N, unsigned &Imm)
isInt32Immediate - This method tests to see if the node is a 32-bit constant operand.
STATISTIC(NumFunctions, "Total number of functions")
unsigned const TargetRegisterInfo * TRI
MVT getSimpleValueType(unsigned ResNo) const
Return the type of a specified result as a simple type.
CALL - A direct function call.
static cl::opt< bool > EnableTLSOpt("ppc-tls-opt", cl::init(true), cl::desc("Enable tls optimization peephole"), cl::Hidden)
void setNodeId(int Id)
Set unique node id.
SDNode * getNode() const
get the SDNode which holds the desired result
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
static bool isOpcWithIntImmediate(SDNode *N, unsigned Opc, unsigned &Imm)
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
unsigned getValueSizeInBits() const
Returns the size of the value in bits.
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
bool isUnsignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs an unsigned comparison when used with intege...
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
GlobalBaseReg - On Darwin, this node represents the result of the mflr at function entry...
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
bool hasOneUse() const
Return true if there is exactly one use of this node.
A description of a memory reference used in the backend.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
const HexagonInstrInfo * TII
Shift and rotation operations.
std::size_t countTrailingOnes(T Value, ZeroBehavior ZB=ZB_Width)
Count the number of ones from the least significant bit to the first zero bit.
A Use represents the edge between a Value definition and its users.
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), MachineInstr opcode, and operands.
uint64_t getConstantOperandVal(unsigned i) const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
const DataLayout & getDataLayout() const
unsigned getID() const
Return the register class ID number.
Position
Position to insert a new instruction relative to an existing instruction.
This file implements a class to represent arbitrary precision integral constant values and operations...
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
int64_t getSExtValue() const
unsigned getSizeInBits() const
Return the size of the specified value type in bits.
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...
CHAIN = BDNZ CHAIN, DESTBB - These are used to create counter-based loops.
R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
Simple integer binary arithmetic operators.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out...
unsigned getOperandNo() const
Return the operand # of this use in its User.
TargetConstant* - Like Constant*, but the DAG does not do any folding, simplification, or lowering of the constant.
unsigned getAlignment() const
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
ArrayRef< SDUse > ops() const
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
unsigned getNumSuccessors() const
Return the number of successors that this instruction has.
This class is used to represent ISD::STORE nodes.
TargetInstrInfo - Interface to description of machine instruction set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Get a value with high bits set.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
const SDValue & getBasePtr() const
initializer< Ty > init(const Ty &Val)
cl::opt< bool > ANDIGlueBug("expose-ppc-andi-glue-bug", cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
CodeGenOpt::Level getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
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...
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
LLVM Basic Block Representation.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
static SDNode * selectI64ImmDirect(SelectionDAG *CurDAG, const SDLoc &dl, int64_t Imm)
bool isMachineOpcode() const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
const SDValue & getOperand(unsigned Num) const
static PPC::Predicate getPredicateForSetCC(ISD::CondCode CC)
CHAIN,FLAG = MTCTR(VAL, CHAIN[, INFLAG]) - Directly corresponds to a MTCTR instruction.
static ManagedStatic< OptionRegistry > OR
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
const SDValue & getOffset() const
This class provides iterator support for SDUse operands that use a specific SDNode.
unsigned getMachineOpcode() const
const PPCTargetLowering * getTargetLowering() const override
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
static bool isInt64Immediate(SDNode *N, uint64_t &Imm)
isInt64Immediate - This method tests to see if the node is a 64-bit constant operand.
FunctionPass class - This class is used to implement most global optimizations.
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Common code between 32-bit and 64-bit PowerPC targets.
auto remove_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
const MachineBasicBlock & front() const
bool isLittleEndian() const
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode...
unsigned getNumOperands() const
Return the number of values used by this operation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
MachineBasicBlock * MBB
MBB - The current block.
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
BranchProbability getEdgeProbability(const BasicBlock *Src, unsigned IndexInSuccessors) const
Get an edge's probability, relative to other out-edges of the Src.
void sort(IteratorTy Start, IteratorTy End)
bool use_empty() const
Return true if there are no uses of this node.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
void dump() const
Dump this node, for debugging.
const PPCRegisterInfo * getRegisterInfo() const override
static bool PeepholePPC64ZExtGather(SDValue Op32, SmallPtrSetImpl< SDNode *> &ToPromote)
const TargetLowering & getTargetLoweringInfo() const
Iterator for intrusive lists based on ilist_node.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
GPRC = TOC_ENTRY GA, TOC Loads the entry for GA from the TOC, where the TOC base is given by the last...
constexpr bool isInt< 32 >(int64_t x)
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
const PPCInstrInfo * getInstrInfo() const override
static bool mayUseP9Setb(SDNode *N, const ISD::CondCode &CC, SelectionDAG *DAG, bool &NeedSwapOps, bool &IsUnCmp)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
G8RC = ADD_TLS G8RReg, Symbol - Used by the initial-exec TLS model, produces an ADD instruction that ...
Module.h This file contains the declarations for the Module class.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
An SDNode that represents everything that will be needed to construct a MachineInstr.
LLVM_NODISCARD T pop_back_val()
CHAIN = SC CHAIN, Imm128 - System call.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
CondCode getSetCCInverse(CondCode Operation, bool isInteger)
Return the operation corresponding to !(X op Y), where 'op' is a valid SetCC operation.
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
These values identify relocations on immediates folded into memory operations.
const Function & getFunction() const
Return the LLVM function that this machine code represents.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
i1 = ANDIo_1_[EQ|GT]_BIT(i32 or i64 x) - Represents the result of the eq or gt bit of CR0 after execu...
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
EVT getMemoryVT() const
Return the type of the in-memory value.
Target - Wrapper for Target specific information.
CodeModel::Model getCodeModel() const
Returns the code model.
iterator_range< use_iterator > uses()
BranchProbabilityInfo * BPI
Select(COND, TRUEVAL, FALSEVAL).
static use_iterator use_end()
ZERO_EXTEND - Used for integer types, zeroing the new bits.
static cl::opt< unsigned > Threshold("loop-unswitch-threshold", cl::desc("Max loop size to unswitch"), cl::init(100), cl::Hidden)
ANY_EXTEND - Used for integer types. The high bits are undefined.
The combination of sra[wd]i and addze used to implemented signed integer division by a power of 2...
int getMaskElt(unsigned Idx) const
static SDNode * selectI64Imm(SelectionDAG *CurDAG, const SDLoc &dl, int64_t Imm)
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
static unsigned allUsesTruncate(SelectionDAG *CurDAG, SDNode *N)
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
bool isVector() const
Return true if this is a vector value type.
Bitwise operators - logical and, logical or, logical xor.
FunctionPass * createPPCISelDag(PPCTargetMachine &TM, CodeGenOpt::Level OL)
createPPCISelDag - This pass converts a legalized DAG into a PowerPC-specific DAG, ready for instruction scheduling.
LLVM_NODISCARD bool empty() const
bool isPositionIndependent() const
static unsigned selectI64ImmInstrCount(int64_t Imm)
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
StringRef getName() const
Return a constant reference to the value's name.
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
The CMPB instruction (takes two operands of i32 or i64).
static cl::opt< bool > EnableBranchHint("ppc-use-branch-hint", cl::init(true), cl::desc("Enable static hinting of branches on ppc"), cl::Hidden)
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
bool useCRBits() const
useCRBits - Return true if we should store and manipulate i1 values in the individual condition regis...
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
unsigned getOpcode() const
SDValue getValue(unsigned R) const
constexpr bool isUInt< 16 >(uint64_t x)
bool isDarwin() const
isDarwin - True if this is any darwin platform.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
CopyFromReg - This node indicates that the input value is a virtual or physical register that is defi...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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...
bool operator<(int64_t V1, const APSInt &V2)
static uint64_t Rot64(uint64_t Imm, unsigned R)
static unsigned getBranchHint(unsigned PCC, FunctionLoweringInfo *FuncInfo, const SDValue &DestMBB)
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
unsigned getResNo() const
get the index which selects a specific result in the SDNode
unsigned getSizeInBits(unsigned Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) const
Get the size in bits of Reg.
CHAIN = COND_BRANCH CHAIN, CRRC, OPC, DESTBB [, INFLAG] - This corresponds to the COND_BRANCH pseudo ...
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
static unsigned getCRIdxForSetCC(ISD::CondCode CC, bool &Invert)
getCRIdxForSetCC - Return the index of the condition register field associated with the SetCC conditi...
PICLevel::Level getPICLevel() const
Returns the PIC level (small or large model)
StringRef - Represent a constant reference to a string, i.e.
SetCC operator - This evaluates to a true value iff the condition is true.
unsigned getNumOperands() const
const SDValue & getOperand(unsigned i) const
TRUNCATE - Completely drop the high bits.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
On a symbol operand "FOO", this indicates that the reference is actually to "FOO@plt".
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...
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
XXPERMDI - The PPC XXPERMDI instruction.
virtual const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const
Returns a TargetRegisterClass used for pointer values.
static unsigned int getVCmpInst(MVT VecVT, ISD::CondCode CC, bool HasVSX, bool &Swap, bool &Negate)
This class is used to represent ISD::LOAD nodes.