23 #define DEBUG_TYPE "systemz-isel" 27 struct SystemZAddressingMode {
62 bool IncludesDynAlloc;
64 SystemZAddressingMode(AddrForm form, DispRange dr)
65 :
Form(form), DR(dr), Base(), Disp(0),
Index(),
66 IncludesDynAlloc(
false) {}
69 bool hasIndexField() {
return Form != FormBD; }
72 bool isDynAlloc() {
return Form == FormBDXDynAlloc; }
75 errs() <<
"SystemZAddressingMode " <<
this <<
'\n';
83 if (hasIndexField()) {
91 errs() <<
" Disp " << Disp;
93 errs() <<
" + ADJDYNALLOC";
99 static uint64_t
allOnes(
unsigned int Count) {
103 return (uint64_t(1) << Count) - 1;
119 struct RxSBGOperands {
122 Mask(
allOnes(BitSize)), Input(N), Start(64 - BitSize), End(63),
138 inline SDValue getImm(
const SDNode *Node, uint64_t Imm)
const {
152 bool expandAddress(SystemZAddressingMode &AM,
bool IsBase)
const;
155 bool selectAddress(
SDValue N, SystemZAddressingMode &AM)
const;
158 void getAddressOperands(
const SystemZAddressingMode &AM,
EVT VT,
160 void getAddressOperands(
const SystemZAddressingMode &AM,
EVT VT,
166 bool selectBDAddr(SystemZAddressingMode::DispRange DR,
SDValue Addr,
172 bool selectMVIAddr(SystemZAddressingMode::DispRange DR,
SDValue Addr,
178 bool selectBDXAddr(SystemZAddressingMode::AddrForm
Form,
179 SystemZAddressingMode::DispRange DR,
SDValue Addr,
193 return selectBDAddr(SystemZAddressingMode::Disp12Only, Addr, Base, Disp);
196 return selectBDAddr(SystemZAddressingMode::Disp12Pair, Addr, Base, Disp);
199 return selectBDAddr(SystemZAddressingMode::Disp20Only, Addr, Base, Disp);
202 return selectBDAddr(SystemZAddressingMode::Disp20Pair, Addr, Base, Disp);
207 return selectMVIAddr(SystemZAddressingMode::Disp12Pair, Addr, Base, Disp);
210 return selectMVIAddr(SystemZAddressingMode::Disp20Pair, Addr, Base, Disp);
216 return selectBDXAddr(SystemZAddressingMode::FormBDXNormal,
217 SystemZAddressingMode::Disp12Only,
218 Addr, Base, Disp, Index);
222 return selectBDXAddr(SystemZAddressingMode::FormBDXNormal,
223 SystemZAddressingMode::Disp12Pair,
224 Addr, Base, Disp, Index);
228 return selectBDXAddr(SystemZAddressingMode::FormBDXDynAlloc,
229 SystemZAddressingMode::Disp12Only,
230 Addr, Base, Disp, Index);
234 return selectBDXAddr(SystemZAddressingMode::FormBDXNormal,
235 SystemZAddressingMode::Disp20Only,
236 Addr, Base, Disp, Index);
240 return selectBDXAddr(SystemZAddressingMode::FormBDXNormal,
241 SystemZAddressingMode::Disp20Only128,
242 Addr, Base, Disp, Index);
246 return selectBDXAddr(SystemZAddressingMode::FormBDXNormal,
247 SystemZAddressingMode::Disp20Pair,
248 Addr, Base, Disp, Index);
252 return selectBDXAddr(SystemZAddressingMode::FormBDXLA,
253 SystemZAddressingMode::Disp12Pair,
254 Addr, Base, Disp, Index);
258 return selectBDXAddr(SystemZAddressingMode::FormBDXLA,
259 SystemZAddressingMode::Disp20Pair,
260 Addr, Base, Disp, Index);
273 bool detectOrAndInsertion(
SDValue &
Op, uint64_t InsertMask)
const;
277 bool refineRxSBGMask(RxSBGOperands &RxSBG, uint64_t
Mask)
const;
281 bool expandRxSBG(RxSBGOperands &RxSBG)
const;
291 bool tryRISBGZero(
SDNode *N);
295 bool tryRxSBG(
SDNode *N,
unsigned Opcode);
304 void splitLargeImmediate(
unsigned Opcode,
SDNode *Node,
SDValue Op0,
305 uint64_t UpperVal, uint64_t LowerVal);
308 bool tryGather(
SDNode *N,
unsigned Opcode);
316 bool tryFoldLoadStoreIntoMemOperand(
SDNode *Node);
331 bool storeLoadCanUseMVC(
SDNode *N)
const;
336 bool storeLoadCanUseBlockBinary(
SDNode *N,
unsigned I)
const;
352 return "SystemZ DAG->DAG Pattern Instruction Selection";
357 bool SelectInlineAsmMemoryOperand(
const SDValue &Op,
unsigned ConstraintID,
358 std::vector<SDValue> &OutOps)
override;
360 void PreprocessISelDAG()
override;
363 #include "SystemZGenDAGISel.inc" 369 return new SystemZDAGToDAGISel(TM, OptLevel);
375 static bool selectDisp(SystemZAddressingMode::DispRange DR, int64_t Val) {
377 case SystemZAddressingMode::Disp12Only:
378 return isUInt<12>(Val);
380 case SystemZAddressingMode::Disp12Pair:
381 case SystemZAddressingMode::Disp20Only:
382 case SystemZAddressingMode::Disp20Pair:
383 return isInt<20>(Val);
385 case SystemZAddressingMode::Disp20Only128:
386 return isInt<20>(Val) && isInt<20>(Val + 8);
406 if (AM.isDynAlloc() && !AM.IncludesDynAlloc) {
408 AM.IncludesDynAlloc =
true;
418 if (AM.hasIndexField() && !AM.Index.getNode()) {
428 static bool expandDisp(SystemZAddressingMode &AM,
bool IsBase,
431 int64_t TestDisp = AM.Disp + Op1;
443 bool SystemZDAGToDAGISel::expandAddress(SystemZAddressingMode &AM,
445 SDValue N = IsBase ? AM.Base : AM.Index;
451 if (Opcode ==
ISD::ADD || CurDAG->isBaseWithConstantOffset(N)) {
465 cast<ConstantSDNode>(Op0)->getSExtValue());
468 cast<ConstantSDNode>(Op1)->getSExtValue());
478 cast<GlobalAddressSDNode>(Anchor)->
getOffset());
486 static bool isValidDisp(SystemZAddressingMode::DispRange DR, int64_t Val) {
489 case SystemZAddressingMode::Disp12Only:
490 case SystemZAddressingMode::Disp20Only:
491 case SystemZAddressingMode::Disp20Only128:
494 case SystemZAddressingMode::Disp12Pair:
496 return isUInt<12>(Val);
498 case SystemZAddressingMode::Disp20Pair:
500 return !isUInt<12>(Val);
524 if (isUInt<12>(Disp))
543 unsigned IndexOpcode = Index->
getOpcode();
558 bool SystemZDAGToDAGISel::selectAddress(
SDValue Addr,
559 SystemZAddressingMode &AM)
const {
567 cast<ConstantSDNode>(Addr)->getSExtValue()))
575 while (expandAddress(AM,
true) ||
576 (AM.Index.getNode() && expandAddress(AM,
false)))
580 if (AM.Form == SystemZAddressingMode::FormBDXLA &&
581 !
shouldUseLA(AM.Base.getNode(), AM.Disp, AM.Index.getNode()))
589 if (AM.isDynAlloc() && !AM.IncludesDynAlloc)
615 void SystemZDAGToDAGISel::getAddressOperands(
const SystemZAddressingMode &AM,
621 Base = CurDAG->getRegister(0, VT);
624 int64_t
FrameIndex = cast<FrameIndexSDNode>(Base)->getIndex();
625 Base = CurDAG->getTargetFrameIndex(FrameIndex, VT);
629 "Unexpected truncation");
637 Disp = CurDAG->getTargetConstant(AM.Disp,
SDLoc(Base), VT);
640 void SystemZDAGToDAGISel::getAddressOperands(
const SystemZAddressingMode &AM,
644 getAddressOperands(AM, VT, Base, Disp);
649 Index = CurDAG->getRegister(0, VT);
652 bool SystemZDAGToDAGISel::selectBDAddr(SystemZAddressingMode::DispRange DR,
655 SystemZAddressingMode AM(SystemZAddressingMode::FormBD, DR);
656 if (!selectAddress(Addr, AM))
659 getAddressOperands(AM, Addr.
getValueType(), Base, Disp);
663 bool SystemZDAGToDAGISel::selectMVIAddr(SystemZAddressingMode::DispRange DR,
666 SystemZAddressingMode AM(SystemZAddressingMode::FormBDXNormal, DR);
667 if (!selectAddress(Addr, AM) || AM.Index.getNode())
670 getAddressOperands(AM, Addr.
getValueType(), Base, Disp);
674 bool SystemZDAGToDAGISel::selectBDXAddr(SystemZAddressingMode::AddrForm
Form,
675 SystemZAddressingMode::DispRange DR,
678 SystemZAddressingMode AM(
Form, DR);
679 if (!selectAddress(Addr, AM))
686 bool SystemZDAGToDAGISel::selectBDVAddr12Only(
SDValue Addr,
SDValue Elem,
691 if (selectBDXAddr12Only(Addr, Regs[0], Disp, Regs[1]) &&
692 Regs[0].getNode() && Regs[1].getNode()) {
693 for (
unsigned int I = 0;
I < 2; ++
I) {
710 bool SystemZDAGToDAGISel::detectOrAndInsertion(
SDValue &
Op,
711 uint64_t InsertMask)
const {
724 if (InsertMask & AndMask)
730 if (Used != (AndMask | InsertMask)) {
740 bool SystemZDAGToDAGISel::refineRxSBGMask(RxSBGOperands &RxSBG,
741 uint64_t
Mask)
const {
743 if (RxSBG.Rotate != 0)
744 Mask = (Mask << RxSBG.Rotate) | (Mask >> (64 - RxSBG.Rotate));
746 if (TII->
isRxSBGMask(Mask, RxSBG.BitSize, RxSBG.Start, RxSBG.End)) {
756 if (RxSBG.Rotate != 0)
757 Mask = ((Mask << RxSBG.Rotate) | (Mask >> (64 - RxSBG.Rotate)));
758 return (Mask & RxSBG.Mask) != 0;
761 bool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG)
const {
766 if (RxSBG.Opcode == SystemZ::RNSBG)
770 if (!refineRxSBGMask(RxSBG, Mask))
776 if (RxSBG.Opcode == SystemZ::RNSBG)
784 uint64_t
Mask = MaskNode->getZExtValue();
785 if (!refineRxSBGMask(RxSBG, Mask)) {
789 KnownBits Known = CurDAG->computeKnownBits(Input);
791 if (!refineRxSBGMask(RxSBG, Mask))
799 if (RxSBG.Opcode != SystemZ::RNSBG)
807 uint64_t
Mask = ~MaskNode->getZExtValue();
808 if (!refineRxSBGMask(RxSBG, Mask)) {
812 KnownBits Known = CurDAG->computeKnownBits(Input);
814 if (!refineRxSBGMask(RxSBG, Mask))
829 RxSBG.Rotate = (RxSBG.Rotate + CountNode->getZExtValue()) & 63;
840 if (RxSBG.Opcode != SystemZ::RNSBG) {
843 if (!refineRxSBGMask(RxSBG,
allOnes(InnerBitSize)))
859 if (RxSBG.Mask == 1 && RxSBG.Rotate == 1)
860 RxSBG.Rotate += (BitSize - InnerBitSize);
876 if (Count < 1 || Count >= BitSize)
879 if (RxSBG.Opcode == SystemZ::RNSBG) {
886 if (!refineRxSBGMask(RxSBG,
allOnes(BitSize - Count) << Count))
890 RxSBG.Rotate = (RxSBG.Rotate + Count) & 63;
903 if (Count < 1 || Count >= BitSize)
906 if (RxSBG.Opcode == SystemZ::RNSBG || Opcode ==
ISD::SRA) {
914 if (!refineRxSBGMask(RxSBG,
allOnes(BitSize - Count)))
918 RxSBG.Rotate = (RxSBG.Rotate - Count) & 63;
928 SDNode *
N = CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, VT);
935 return CurDAG->getTargetInsertSubreg(SystemZ::subreg_l32,
938 return CurDAG->getTargetExtractSubreg(SystemZ::subreg_l32, DL, VT, N);
943 bool SystemZDAGToDAGISel::tryRISBGZero(
SDNode *N) {
948 RxSBGOperands RISBG(SystemZ::RISBG,
SDValue(N, 0));
950 while (expandRxSBG(RISBG))
968 if (RISBG.Rotate == 0) {
969 bool PreferAnd =
false;
975 else if (RISBG.Mask == 0xff ||
976 RISBG.Mask == 0xffff ||
977 RISBG.Mask == 0x7fffffff ||
983 else if (
auto *
Load = dyn_cast<LoadSDNode>(RISBG.Input)) {
987 RISBG.Mask == 0xffffff00 &&
988 Subtarget->hasLoadAndZeroRightmostByte())
995 SDValue In = convertTo(DL, VT, RISBG.Input);
996 SDValue Mask = CurDAG->getConstant(RISBG.Mask, DL, VT);
1001 ReplaceNode(N, New.
getNode());
1011 unsigned Opcode = SystemZ::RISBG;
1013 if (Subtarget->hasMiscellaneousExtensions())
1014 Opcode = SystemZ::RISBGN;
1016 if (VT ==
MVT::i32 && Subtarget->hasHighWord() &&
1021 RISBG.Start >= 32 && RISBG.End >= RISBG.Start &&
1022 ((RISBG.Start + RISBG.Rotate) & 63) >= 32 &&
1023 ((RISBG.End + RISBG.Rotate) & 63) >=
1024 ((RISBG.Start + RISBG.Rotate) & 63)) {
1025 Opcode = SystemZ::RISBMux;
1031 getUNDEF(DL, OpcodeVT),
1032 convertTo(DL, OpcodeVT, RISBG.Input),
1033 CurDAG->getTargetConstant(RISBG.Start, DL,
MVT::i32),
1034 CurDAG->getTargetConstant(RISBG.End | 128, DL,
MVT::i32),
1035 CurDAG->getTargetConstant(RISBG.Rotate, DL,
MVT::i32)
1038 DL, VT,
SDValue(CurDAG->getMachineNode(Opcode, DL, OpcodeVT, Ops), 0));
1039 ReplaceNode(N, New.
getNode());
1043 bool SystemZDAGToDAGISel::tryRxSBG(
SDNode *N,
unsigned Opcode) {
1050 RxSBGOperands RxSBG[] = {
1054 unsigned Count[] = { 0, 0 };
1055 for (
unsigned I = 0;
I < 2; ++
I)
1056 while (expandRxSBG(RxSBG[
I]))
1065 if (Count[0] == 0 && Count[1] == 0)
1069 unsigned I = Count[0] > Count[1] ? 0 : 1;
1073 if (Opcode == SystemZ::ROSBG && (RxSBG[I].
Mask & 0xff) == 0)
1074 if (
auto *
Load = dyn_cast<LoadSDNode>(Op0.
getNode()))
1080 if (Opcode == SystemZ::ROSBG && detectOrAndInsertion(Op0, RxSBG[I].
Mask)) {
1081 Opcode = SystemZ::RISBG;
1083 if (Subtarget->hasMiscellaneousExtensions())
1084 Opcode = SystemZ::RISBGN;
1089 convertTo(DL,
MVT::i64, RxSBG[I].Input),
1090 CurDAG->getTargetConstant(RxSBG[I].Start, DL,
MVT::i32),
1091 CurDAG->getTargetConstant(RxSBG[I].End, DL,
MVT::i32),
1092 CurDAG->getTargetConstant(RxSBG[I].Rotate, DL,
MVT::i32)
1095 DL, VT,
SDValue(CurDAG->getMachineNode(Opcode, DL,
MVT::i64, Ops), 0));
1096 ReplaceNode(N, New.
getNode());
1100 void SystemZDAGToDAGISel::splitLargeImmediate(
unsigned Opcode,
SDNode *Node,
1101 SDValue Op0, uint64_t UpperVal,
1102 uint64_t LowerVal) {
1107 Upper = CurDAG->getNode(Opcode, DL, VT, Op0, Upper);
1128 SDValue Or = CurDAG->getNode(Opcode, DL, VT, Upper, Lower);
1130 ReplaceNode(Node, Or.
getNode());
1135 bool SystemZDAGToDAGISel::tryGather(
SDNode *N,
unsigned Opcode) {
1141 unsigned Elem = ElemN->getZExtValue();
1147 if (!
Load || !
Load->hasNUsesOfValue(1, 0))
1149 if (
Load->getMemoryVT().getSizeInBits() !=
1150 Load->getValueType(0).getSizeInBits())
1154 if (!selectBDVAddr12Only(
Load->getBasePtr(), ElemV, Base, Disp,
Index) ||
1161 CurDAG->getTargetConstant(Elem, DL,
MVT::i32),
Load->getChain()
1165 ReplaceNode(N, Res);
1169 bool SystemZDAGToDAGISel::tryScatter(
StoreSDNode *
Store,
unsigned Opcode) {
1183 unsigned Elem = ElemN->getZExtValue();
1188 if (!selectBDVAddr12Only(Store->
getBasePtr(), ElemV, Base, Disp,
Index) ||
1194 Vec, Base, Disp,
Index, CurDAG->getTargetConstant(Elem, DL,
MVT::i32),
1197 ReplaceNode(Store, CurDAG->getMachineNode(Opcode, DL,
MVT::Other, Ops));
1225 LoadNode = cast<LoadSDNode>(
Load);
1240 bool ChainCheck =
false;
1261 UE = UI->
use_end(); UI != UE; ++UI) {
1262 if (UI.getUse().getResNo() != 0)
1264 if (UI->getNodeId() > LoadId)
1291 bool SystemZDAGToDAGISel::tryFoldLoadStoreIntoMemOperand(
SDNode *Node) {
1295 SDLoc DL(StoreNode);
1301 unsigned NewOpc = 0;
1302 bool NegateOperand =
false;
1307 NegateOperand =
true;
1311 NewOpc = SystemZ::ASI;
1313 NewOpc = SystemZ::AGSI;
1318 NegateOperand =
true;
1322 NewOpc = SystemZ::ALSI;
1324 NewOpc = SystemZ::ALGSI;
1342 OperandV = -OperandV;
1343 if (OperandV.getMinSignedBits() > 8)
1345 Operand = CurDAG->getTargetConstant(OperandV, DL, MemVT);
1348 if (!selectBDAddr20Only(StoreNode->
getBasePtr(), Base, Disp))
1351 SDValue Ops[] = { Base, Disp, Operand, InputChain };
1354 CurDAG->setNodeMemRefs(
1358 ReplaceUses(
SDValue(StoredVal.getNode(), 1),
SDValue(Result, 0));
1359 CurDAG->RemoveDeadNode(Node);
1363 bool SystemZDAGToDAGISel::canUseBlockOperation(
StoreSDNode *Store,
1387 if (V1 == V2 && End1 == End2)
1394 bool SystemZDAGToDAGISel::storeLoadCanUseMVC(
SDNode *N)
const {
1395 auto *Store = cast<StoreSDNode>(
N);
1396 auto *Load = cast<LoadSDNode>(Store->
getValue());
1400 uint64_t
Size = Load->getMemoryVT().getStoreSize();
1401 if (Size > 1 && Size <= 8) {
1410 return canUseBlockOperation(Store, Load);
1413 bool SystemZDAGToDAGISel::storeLoadCanUseBlockBinary(
SDNode *N,
1415 auto *StoreA = cast<StoreSDNode>(
N);
1416 auto *LoadA = cast<LoadSDNode>(StoreA->getValue().getOperand(1 - I));
1417 auto *LoadB = cast<LoadSDNode>(StoreA->getValue().getOperand(I));
1418 return !LoadA->isVolatile() && canUseBlockOperation(StoreA, LoadB);
1433 if (tryRxSBG(Node, SystemZ::ROSBG))
1439 if (tryRxSBG(Node, SystemZ::RXSBG))
1448 if (
auto *Op1 = dyn_cast<ConstantSDNode>(Node->
getOperand(1))) {
1449 uint64_t Val = Op1->getZExtValue();
1451 splitLargeImmediate(Opcode, Node, Node->
getOperand(0),
1460 if (tryRxSBG(Node, SystemZ::RNSBG))
1467 if (tryRISBGZero(Node))
1475 uint64_t Val = cast<ConstantSDNode>(Node)->getZExtValue();
1490 (Subtarget->hasLoadStoreOnCond2() &&
1493 isInt<16>(cast<ConstantSDNode>(Op1)->getSExtValue()) &&
1495 isInt<16>(cast<ConstantSDNode>(Op0)->getSExtValue())))) {
1498 uint64_t ConstCCValid =
1499 cast<ConstantSDNode>(CCValid.
getNode())->getZExtValue();
1500 uint64_t ConstCCMask =
1501 cast<ConstantSDNode>(CCMask.
getNode())->getZExtValue();
1503 CCMask = CurDAG->getConstant(ConstCCValid ^ ConstCCMask,
SDLoc(Node),
1507 CurDAG->UpdateNodeOperands(Node, Op1, Op0, CCValid, CCMask, Op4);
1508 if (UpdatedNode != Node) {
1510 ReplaceNode(Node, UpdatedNode);
1520 if (ElemBitSize == 32) {
1521 if (tryGather(Node, SystemZ::VGEF))
1523 }
else if (ElemBitSize == 64) {
1524 if (tryGather(Node, SystemZ::VGEG))
1531 if (tryFoldLoadStoreIntoMemOperand(Node))
1533 auto *Store = cast<StoreSDNode>(Node);
1535 if (ElemBitSize == 32) {
1536 if (tryScatter(Store, SystemZ::VSCEF))
1538 }
else if (ElemBitSize == 64) {
1539 if (tryScatter(Store, SystemZ::VSCEG))
1549 bool SystemZDAGToDAGISel::
1550 SelectInlineAsmMemoryOperand(
const SDValue &Op,
1551 unsigned ConstraintID,
1552 std::vector<SDValue> &OutOps) {
1553 SystemZAddressingMode::AddrForm
Form;
1554 SystemZAddressingMode::DispRange DispRange;
1557 switch(ConstraintID) {
1563 Form = SystemZAddressingMode::FormBD;
1564 DispRange = SystemZAddressingMode::Disp12Only;
1568 Form = SystemZAddressingMode::FormBDXNormal;
1569 DispRange = SystemZAddressingMode::Disp12Only;
1573 Form = SystemZAddressingMode::FormBD;
1574 DispRange = SystemZAddressingMode::Disp20Only;
1583 Form = SystemZAddressingMode::FormBDXNormal;
1584 DispRange = SystemZAddressingMode::Disp20Only;
1588 if (selectBDXAddr(Form, DispRange, Op, Base, Disp, Index)) {
1590 Subtarget->getRegisterInfo()->getPointerRegClass(*MF);
1599 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
1607 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
1612 OutOps.push_back(Base);
1613 OutOps.push_back(Disp);
1614 OutOps.push_back(Index);
1624 SystemZDAGToDAGISel::IsProfitableToFold(
SDValue N,
SDNode *U,
1637 SDNode *CCRegUser =
nullptr;
1640 for (
auto *U : CCUser->
uses()) {
1641 if (CCRegUser ==
nullptr)
1643 else if (CCRegUser != U)
1647 if (CCRegUser ==
nullptr)
1660 if (!IsLegalToFold(N, U, CCRegUser, OptLevel,
false))
1670 struct IPMConversion {
1671 IPMConversion(
unsigned xorValue, int64_t addValue,
unsigned bit)
1672 : XORValue(xorValue), AddValue(addValue),
Bit(bit) {}
1698 uint64_t TopBit = uint64_t(1) << 31;
1703 if (CCMask == (CCValid & (SystemZ::CCMASK_0
1711 | SystemZ::CCMASK_3)))
1723 if (CCMask == (CCValid & (SystemZ::CCMASK_0 | SystemZ::CCMASK_3)))
1734 if (CCMask == (CCValid & (SystemZ::CCMASK_0
1736 | SystemZ::CCMASK_3)))
1738 if (CCMask == (CCValid & (SystemZ::CCMASK_0
1740 | SystemZ::CCMASK_3)))
1747 SDValue SystemZDAGToDAGISel::expandSelectBoolean(
SDNode *Node) {
1750 if (!TrueOp || !FalseOp)
1752 if (FalseOp->getZExtValue() != 0)
1754 if (TrueOp->getSExtValue() != 1 && TrueOp->getSExtValue() != -1)
1759 if (!CCValidOp || !CCMaskOp)
1761 int CCValid = CCValidOp->getZExtValue();
1762 int CCMask = CCMaskOp->getZExtValue();
1771 CurDAG->getConstant(IPM.XORValue, DL,
MVT::i32));
1775 CurDAG->getConstant(IPM.AddValue, DL,
MVT::i32));
1778 if (VT ==
MVT::i32 && IPM.Bit == 31) {
1780 Result = CurDAG->getNode(ShiftOp, DL,
MVT::i32, Result,
1781 CurDAG->getConstant(IPM.Bit, DL,
MVT::i32));
1786 if (TrueOp->getSExtValue() == 1) {
1788 Result = CurDAG->getNode(
ISD::SRL, DL, VT, Result,
1789 CurDAG->getConstant(IPM.Bit, DL,
MVT::i32));
1790 Result = CurDAG->getNode(
ISD::AND, DL, VT, Result,
1791 CurDAG->getConstant(1, DL, VT));
1796 Result = CurDAG->getNode(
ISD::SHL, DL, VT, Result,
1797 CurDAG->getConstant(ShlAmt, DL,
MVT::i32));
1798 Result = CurDAG->getNode(
ISD::SRA, DL, VT, Result,
1799 CurDAG->getConstant(SraAmt, DL,
MVT::i32));
1806 void SystemZDAGToDAGISel::PreprocessISelDAG() {
1809 if (Subtarget->hasLoadStoreOnCond2())
1812 bool MadeChange =
false;
1815 E = CurDAG->allnodes_end();
1825 Res = expandSelectBoolean(N);
1830 LLVM_DEBUG(
dbgs() <<
"SystemZ DAG preprocessing replacing:\nOld: ");
1836 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(N, 0), Res);
1842 CurDAG->RemoveDeadNodes();
static bool isImmHF(uint64_t Val)
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.
uint64_t getZExtValue() const
Get zero extended value.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
static void insertDAGNode(SelectionDAG *DAG, SDNode *Pos, SDValue N)
This class represents lattice values for constants.
static bool isImmLF(uint64_t Val)
const SDValue & getBasePtr() const
void push_back(const T &Elt)
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
const SDValue & getValue() const
static bool maskMatters(RxSBGOperands &RxSBG, uint64_t Mask)
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
const SDValue & getChain() const
constexpr bool isInt< 16 >(int64_t x)
bool isInteger() const
Return true if this is an integer or a vector integer type.
void setNodeId(int Id)
Set unique node id.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
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.
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
static uint64_t allOnes(unsigned int Count)
bool hasOneUse() const
Return true if there is exactly one use of this node.
const HexagonInstrInfo * TII
Shift and rotation operations.
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
FunctionPass * createSystemZISelDag(SystemZTargetMachine &TM, CodeGenOpt::Level OptLevel)
CopyToReg - This node has three operands: a chain, a register number to set to this value...
unsigned getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
unsigned getID() const
Return the register class ID number.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
static void InvalidateNodeId(SDNode *N)
unsigned getScalarSizeInBits() const
unsigned getSizeInBits() const
Return the size of the specified value type in bits.
Simple integer binary arithmetic operators.
static bool expandAdjDynAlloc(SystemZAddressingMode &AM, bool IsBase, SDValue Value)
static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)
int64_t getSrcValueOffset() const
static bool shouldUseLA(SDNode *Base, int64_t Disp, SDNode *Index)
This class is used to represent ISD::STORE nodes.
const Value * getValue() const
Return the base address of the memory access.
const SDValue & getBasePtr() const
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
static bool expandDisp(SystemZAddressingMode &AM, bool IsBase, SDValue Op0, uint64_t Op1)
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const SDValue & getOperand(unsigned Num) const
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL...
const SDValue & getOffset() const
This class provides iterator support for SDUse operands that use a specific SDNode.
void RepositionNode(allnodes_iterator Position, SDNode *N)
Move node N in the AllNodes list to be immediately before the given iterator Position.
static void changeComponent(SystemZAddressingMode &AM, bool IsBase, SDValue Value)
const APInt & getAPIntValue() const
FunctionPass class - This class is used to implement most global optimizations.
self_iterator getIterator()
bool isPCREL(unsigned Opcode)
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const SystemZInstrInfo * getInstrInfo() const override
bool use_empty() const
Return true if there are no uses of this node.
Representation for a specific memory location.
TokenFactor - This node takes multiple tokens as input and produces a single token result...
void dump() const
Dump this node, for debugging.
Iterator for intrusive lists based on ilist_node.
constexpr bool isInt< 32 >(int64_t x)
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
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.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isDereferenceable() const
static IPMConversion getIPMConversion(unsigned CCValid, unsigned CCMask)
EVT getMemoryVT() const
Return the type of the in-memory value.
Target - Wrapper for Target specific information.
iterator_range< use_iterator > uses()
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
static use_iterator use_end()
ZERO_EXTEND - Used for integer types, zeroing the new bits.
ANY_EXTEND - Used for integer types. The high bits are undefined.
int getNodeId() const
Return the unique node id.
const SDValue & getValue() const
Bitwise operators - logical and, logical or, logical xor.
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
unsigned getOpcode() const
SDValue getValue(unsigned R) const
static bool selectDisp(SystemZAddressingMode::DispRange DR, int64_t Val)
This class is used to form a handle around another node that is persistent and is updated across invo...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isPredecessorOf(const SDNode *N) const
Return true if this node is a predecessor of N.
static bool expandIndex(SystemZAddressingMode &AM, SDValue Base, SDValue Index)
LLVM Value Representation.
unsigned getResNo() const
get the index which selects a specific result in the SDNode
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.
bool isNonTemporal() const
static bool isValidDisp(SystemZAddressingMode::DispRange DR, int64_t Val)
bool isRxSBGMask(uint64_t Mask, unsigned BitSize, unsigned &Start, unsigned &End) const
StringRef - Represent a constant reference to a string, i.e.
unsigned getNumOperands() const
const SDValue & getOperand(unsigned i) const
uint64_t getZExtValue() const
static bool isFusableLoadOpStorePattern(StoreSDNode *StoreNode, SDValue StoredVal, SelectionDAG *CurDAG, LoadSDNode *&LoadNode, SDValue &InputChain)
TRUNCATE - Completely drop the high bits.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
This class is used to represent ISD::LOAD nodes.
static int getUninvalidatedNodeId(SDNode *N)