24#define DEBUG_TYPE "systemz-isel"
25#define PASS_NAME "SystemZ DAG->DAG Pattern Instruction Selection"
29struct SystemZAddressingMode {
64 bool IncludesDynAlloc;
66 SystemZAddressingMode(AddrForm form, DispRange dr)
67 : Form(form), DR(dr), Disp(0), IncludesDynAlloc(
false) {}
70 bool hasIndexField() {
return Form != FormBD; }
73 bool isDynAlloc() {
return Form == FormBDXDynAlloc; }
76 errs() <<
"SystemZAddressingMode " <<
this <<
'\n';
80 Base.getNode()->dump(DAG);
84 if (hasIndexField()) {
87 Index.getNode()->dump(DAG);
92 errs() <<
" Disp " << Disp;
94 errs() <<
" + ADJDYNALLOC";
120struct RxSBGOperands {
122 : Opcode(
Op), BitSize(
N.getValueSizeInBits()),
153 bool expandAddress(SystemZAddressingMode &AM,
bool IsBase)
const;
156 bool selectAddress(
SDValue N, SystemZAddressingMode &AM)
const;
159 void getAddressOperands(
const SystemZAddressingMode &AM,
EVT VT,
161 void getAddressOperands(
const SystemZAddressingMode &AM,
EVT VT,
167 bool selectBDAddr(SystemZAddressingMode::DispRange DR,
SDValue Addr,
173 bool selectMVIAddr(SystemZAddressingMode::DispRange DR,
SDValue Addr,
179 bool selectBDXAddr(SystemZAddressingMode::AddrForm Form,
180 SystemZAddressingMode::DispRange DR,
SDValue Addr,
194 return selectBDAddr(SystemZAddressingMode::Disp12Only, Addr,
Base, Disp);
197 return selectBDAddr(SystemZAddressingMode::Disp12Pair, Addr,
Base, Disp);
200 return selectBDAddr(SystemZAddressingMode::Disp20Only, Addr,
Base, Disp);
203 return selectBDAddr(SystemZAddressingMode::Disp20Pair, Addr,
Base, Disp);
208 return selectMVIAddr(SystemZAddressingMode::Disp12Pair, Addr,
Base, Disp);
211 return selectMVIAddr(SystemZAddressingMode::Disp20Pair, Addr,
Base, Disp);
217 return selectBDXAddr(SystemZAddressingMode::FormBDXNormal,
218 SystemZAddressingMode::Disp12Only,
219 Addr,
Base, Disp, Index);
223 return selectBDXAddr(SystemZAddressingMode::FormBDXNormal,
224 SystemZAddressingMode::Disp12Pair,
225 Addr,
Base, Disp, Index);
229 return selectBDXAddr(SystemZAddressingMode::FormBDXDynAlloc,
230 SystemZAddressingMode::Disp12Only,
231 Addr,
Base, Disp, Index);
235 return selectBDXAddr(SystemZAddressingMode::FormBDXNormal,
236 SystemZAddressingMode::Disp20Only,
237 Addr,
Base, Disp, Index);
241 return selectBDXAddr(SystemZAddressingMode::FormBDXNormal,
242 SystemZAddressingMode::Disp20Only128,
243 Addr,
Base, Disp, Index);
247 return selectBDXAddr(SystemZAddressingMode::FormBDXNormal,
248 SystemZAddressingMode::Disp20Pair,
249 Addr,
Base, Disp, Index);
253 return selectBDXAddr(SystemZAddressingMode::FormBDXLA,
254 SystemZAddressingMode::Disp12Pair,
255 Addr,
Base, Disp, Index);
259 return selectBDXAddr(SystemZAddressingMode::FormBDXLA,
260 SystemZAddressingMode::Disp20Pair,
261 Addr,
Base, Disp, Index);
287 bool refineRxSBGMask(RxSBGOperands &RxSBG,
uint64_t Mask)
const;
291 bool expandRxSBG(RxSBGOperands &RxSBG)
const;
305 bool tryRxSBG(
SDNode *
N,
unsigned Opcode);
323 bool tryGather(
SDNode *
N,
unsigned Opcode);
331 bool tryFoldLoadStoreIntoMemOperand(
SDNode *
Node);
346 bool storeLoadCanUseMVC(
SDNode *
N)
const;
351 bool storeLoadCanUseBlockBinary(
SDNode *
N,
unsigned I)
const;
355 bool storeLoadIsAligned(
SDNode *
N)
const;
366 bool shouldSelectForReassoc(
SDNode *
N)
const;
369 SystemZDAGToDAGISel() =
delete;
376 if (
F.getParent()->getStackProtectorGuard() !=
"global") {
377 if (
F.getParent()->hasStackProtectorGuardRecord())
379 "mstack-protector-guard=global");
387 bool SelectInlineAsmMemoryOperand(
const SDValue &
Op,
389 std::vector<SDValue> &OutOps)
override;
391 void PreprocessISelDAG()
override;
394 #include "SystemZGenDAGISel.inc"
403 ID, std::make_unique<SystemZDAGToDAGISel>(TM, OptLevel)) {}
407char SystemZDAGToDAGISelLegacy::ID = 0;
413 return new SystemZDAGToDAGISelLegacy(TM, OptLevel);
419static bool selectDisp(SystemZAddressingMode::DispRange DR, int64_t Val) {
421 case SystemZAddressingMode::Disp12Only:
424 case SystemZAddressingMode::Disp12Pair:
425 case SystemZAddressingMode::Disp20Only:
426 case SystemZAddressingMode::Disp20Pair:
429 case SystemZAddressingMode::Disp20Only128:
450 if (AM.isDynAlloc() && !AM.IncludesDynAlloc) {
452 AM.IncludesDynAlloc =
true;
462 if (AM.hasIndexField() && !AM.Index.
getNode()) {
472static bool expandDisp(SystemZAddressingMode &AM,
bool IsBase,
475 int64_t TestDisp = AM.Disp + Op1;
487bool SystemZDAGToDAGISel::expandAddress(SystemZAddressingMode &AM,
489 SDValue
N =
IsBase ? AM.Base : AM.Index;
490 unsigned Opcode =
N.getOpcode();
492 if (Opcode ==
ISD::TRUNCATE &&
N.getOperand(0).getValueSizeInBits() <= 64) {
494 Opcode =
N.getOpcode();
496 if (Opcode ==
ISD::ADD || CurDAG->isBaseWithConstantOffset(
N)) {
497 SDValue Op0 =
N.getOperand(0);
498 SDValue Op1 =
N.getOperand(1);
503 if (Op0Code == SystemZISD::ADJDYNALLOC)
505 if (Op1Code == SystemZISD::ADJDYNALLOC)
518 if (Opcode == SystemZISD::PCREL_OFFSET) {
519 SDValue
Full =
N.getOperand(0);
520 SDValue
Base =
N.getOperand(1);
521 SDValue Anchor =
Base.getOperand(0);
531static bool isValidDisp(SystemZAddressingMode::DispRange DR, int64_t Val) {
534 case SystemZAddressingMode::Disp12Only:
535 case SystemZAddressingMode::Disp20Only:
536 case SystemZAddressingMode::Disp20Only128:
539 case SystemZAddressingMode::Disp12Pair:
543 case SystemZAddressingMode::Disp20Pair:
583 if (Index->hasOneUse())
588 unsigned IndexOpcode = Index->getOpcode();
596 if (
Base->hasOneUse())
603bool SystemZDAGToDAGISel::selectAddress(SDValue Addr,
604 SystemZAddressingMode &AM)
const {
615 else if (Addr.
getOpcode() == SystemZISD::ADJDYNALLOC &&
620 while (expandAddress(AM,
true) ||
621 (AM.Index.
getNode() && expandAddress(AM,
false)))
625 if (AM.Form == SystemZAddressingMode::FormBDXLA &&
634 if (AM.isDynAlloc() && !AM.IncludesDynAlloc)
647 if (
N->getNodeId() == -1 ||
660void SystemZDAGToDAGISel::getAddressOperands(
const SystemZAddressingMode &AM,
661 EVT VT, SDValue &
Base,
662 SDValue &Disp)
const {
666 Base = CurDAG->getRegister(0, VT);
670 Base = CurDAG->getTargetFrameIndex(FrameIndex, VT);
671 }
else if (
Base.getValueType() != VT) {
673 assert(VT == MVT::i32 &&
Base.getValueType() == MVT::i64 &&
674 "Unexpected truncation");
682 Disp = CurDAG->getSignedTargetConstant(AM.Disp, SDLoc(
Base), VT);
685void SystemZDAGToDAGISel::getAddressOperands(
const SystemZAddressingMode &AM,
686 EVT VT, SDValue &
Base,
688 SDValue &Index)
const {
689 getAddressOperands(AM, VT,
Base, Disp);
692 if (!
Index.getNode())
694 Index = CurDAG->getRegister(0, VT);
697bool SystemZDAGToDAGISel::selectBDAddr(SystemZAddressingMode::DispRange DR,
698 SDValue Addr, SDValue &
Base,
699 SDValue &Disp, int64_t
Offset)
const {
700 SystemZAddressingMode AM(SystemZAddressingMode::FormBD, DR);
702 if (!selectAddress(Addr, AM))
709bool SystemZDAGToDAGISel::selectMVIAddr(SystemZAddressingMode::DispRange DR,
710 SDValue Addr, SDValue &
Base,
711 SDValue &Disp)
const {
712 SystemZAddressingMode AM(SystemZAddressingMode::FormBDXNormal, DR);
713 if (!selectAddress(Addr, AM) || AM.Index.
getNode())
720bool SystemZDAGToDAGISel::selectBDXAddr(SystemZAddressingMode::AddrForm Form,
721 SystemZAddressingMode::DispRange DR,
722 SDValue Addr, SDValue &
Base,
723 SDValue &Disp, SDValue &Index)
const {
724 SystemZAddressingMode AM(Form, DR);
725 if (!selectAddress(Addr, AM))
732bool SystemZDAGToDAGISel::selectBDVAddr12Only(SDValue Addr, SDValue Elem,
735 SDValue &Index)
const {
737 if (selectBDXAddr12Only(Addr, Regs[0], Disp, Regs[1]) &&
739 for (
unsigned int I = 0;
I < 2; ++
I) {
747 Index.getOperand(1) == Elem) {
756bool SystemZDAGToDAGISel::selectBDAddr12off1(SDValue
A, SDValue &
B,
758 return selectBDAddr(SystemZAddressingMode::Disp12Pair,
A,
B,
D, 1);
760bool SystemZDAGToDAGISel::selectBDAddr12off3(SDValue
A, SDValue &
B,
762 return selectBDAddr(SystemZAddressingMode::Disp12Pair,
A,
B,
D, 3);
764bool SystemZDAGToDAGISel::selectBDAddr12off7(SDValue
A, SDValue &
B,
766 return selectBDAddr(SystemZAddressingMode::Disp12Pair,
A,
B,
D, 7);
769bool SystemZDAGToDAGISel::selectBDAddr20off1(SDValue
A, SDValue &
B,
771 return selectBDAddr(SystemZAddressingMode::Disp20Pair,
A,
B,
D, 1);
773bool SystemZDAGToDAGISel::selectBDAddr20off3(SDValue
A, SDValue &
B,
775 return selectBDAddr(SystemZAddressingMode::Disp20Pair,
A,
B,
D, 3);
777bool SystemZDAGToDAGISel::selectBDAddr20off7(SDValue
A, SDValue &
B,
779 return selectBDAddr(SystemZAddressingMode::Disp20Pair,
A,
B,
D, 7);
782bool SystemZDAGToDAGISel::detectOrAndInsertion(SDValue &
Op,
795 uint64_t AndMask = MaskNode->getZExtValue();
796 if (InsertMask & AndMask)
802 if (Used != (AndMask | InsertMask)) {
803 KnownBits
Known = CurDAG->computeKnownBits(
Op.getOperand(0));
804 if (Used != (AndMask | InsertMask |
Known.Zero.getZExtValue()))
808 Op =
Op.getOperand(0);
812bool SystemZDAGToDAGISel::refineRxSBGMask(RxSBGOperands &RxSBG,
814 const SystemZInstrInfo *
TII = getInstrInfo();
815 if (RxSBG.Rotate != 0)
816 Mask = (
Mask << RxSBG.Rotate) | (Mask >> (64 - RxSBG.Rotate));
818 if (
TII->isRxSBGMask(Mask, RxSBG.BitSize, RxSBG.Start, RxSBG.End)) {
828 if (RxSBG.Rotate != 0)
829 Mask = ((Mask << RxSBG.Rotate) | (Mask >> (64 - RxSBG.Rotate)));
830 return (Mask & RxSBG.Mask) != 0;
833bool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG)
const {
834 SDValue
N = RxSBG.Input;
835 unsigned Opcode =
N.getOpcode();
838 if (RxSBG.Opcode == SystemZ::RNSBG)
840 if (
N.getOperand(0).getValueSizeInBits() > 64)
842 uint64_t BitSize =
N.getValueSizeInBits();
844 if (!refineRxSBGMask(RxSBG, Mask))
850 if (RxSBG.Opcode == SystemZ::RNSBG)
857 SDValue
Input =
N.getOperand(0);
859 if (!refineRxSBGMask(RxSBG, Mask)) {
863 KnownBits
Known = CurDAG->computeKnownBits(Input);
865 if (!refineRxSBGMask(RxSBG, Mask))
873 if (RxSBG.Opcode != SystemZ::RNSBG)
880 SDValue
Input =
N.getOperand(0);
882 if (!refineRxSBGMask(RxSBG, Mask)) {
886 KnownBits
Known = CurDAG->computeKnownBits(Input);
887 Mask &= ~Known.One.getZExtValue();
888 if (!refineRxSBGMask(RxSBG, Mask))
897 if (RxSBG.BitSize != 64 ||
N.getValueType() != MVT::i64)
903 RxSBG.Rotate = (RxSBG.Rotate + CountNode->getZExtValue()) & 63;
914 if (RxSBG.Opcode != SystemZ::RNSBG) {
916 unsigned InnerBitSize =
N.getOperand(0).getValueSizeInBits();
917 if (!refineRxSBGMask(RxSBG,
allOnes(InnerBitSize)))
928 unsigned BitSize =
N.getValueSizeInBits();
929 unsigned InnerBitSize =
N.getOperand(0).getValueSizeInBits();
933 if (RxSBG.Mask == 1 && RxSBG.Rotate == 1)
934 RxSBG.Rotate += (BitSize - InnerBitSize);
949 unsigned BitSize =
N.getValueSizeInBits();
953 if (RxSBG.Opcode == SystemZ::RNSBG) {
964 RxSBG.Rotate = (RxSBG.Rotate +
Count) & 63;
976 unsigned BitSize =
N.getValueSizeInBits();
980 if (RxSBG.Opcode == SystemZ::RNSBG || Opcode ==
ISD::SRA) {
992 RxSBG.Rotate = (RxSBG.Rotate -
Count) & 63;
1001SDValue SystemZDAGToDAGISel::getUNDEF(
const SDLoc &
DL, EVT VT)
const {
1002 SDNode *
N = CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
DL, VT);
1003 return SDValue(
N, 0);
1006SDValue SystemZDAGToDAGISel::convertTo(
const SDLoc &
DL, EVT VT,
1008 if (
N.getValueType() == MVT::i32 && VT == MVT::i64)
1009 return CurDAG->getTargetInsertSubreg(SystemZ::subreg_l32,
1010 DL, VT, getUNDEF(
DL, MVT::i64),
N);
1011 if (
N.getValueType() == MVT::i64 && VT == MVT::i32)
1012 return CurDAG->getTargetExtractSubreg(SystemZ::subreg_l32,
DL, VT,
N);
1013 assert(
N.getValueType() == VT &&
"Unexpected value types");
1017bool SystemZDAGToDAGISel::tryRISBGZero(SDNode *
N) {
1019 EVT VT =
N->getValueType(0);
1022 RxSBGOperands RISBG(SystemZ::RISBG, SDValue(
N, 0));
1024 while (expandRxSBG(RISBG))
1041 if (Subtarget->hasMiscellaneousExtensions4() &&
1042 RISBG.Rotate >= 1 && RISBG.Rotate <= 4 &&
1043 RISBG.Mask == (((
uint64_t)1 << 32) - 1) << RISBG.Rotate &&
1044 RISBG.Input.getOpcode() ==
ISD::ADD)
1052 if (RISBG.Rotate == 0) {
1053 bool PreferAnd =
false;
1059 else if (RISBG.Mask == 0xff ||
1060 RISBG.Mask == 0xffff ||
1061 RISBG.Mask == 0x7fffffff ||
1068 if (
Load->getMemoryVT() == MVT::i32 &&
1071 RISBG.Mask == 0xffffff00 &&
1072 Subtarget->hasLoadAndZeroRightmostByte())
1080 SDValue
Mask = CurDAG->getConstant(RISBG.Mask,
DL, VT);
1082 if (
N !=
New.getNode()) {
1085 ReplaceNode(
N,
New.getNode());
1089 if (!
N->isMachineOpcode())
1095 unsigned Opcode = SystemZ::RISBG;
1097 if (Subtarget->hasMiscellaneousExtensions())
1098 Opcode = SystemZ::RISBGN;
1099 EVT OpcodeVT = MVT::i64;
1100 if (VT == MVT::i32 && Subtarget->hasHighWord() &&
1105 RISBG.Start >= 32 && RISBG.End >= RISBG.Start &&
1106 ((RISBG.Start + RISBG.Rotate) & 63) >= 32 &&
1107 ((RISBG.End + RISBG.Rotate) & 63) >=
1108 ((RISBG.Start + RISBG.Rotate) & 63)) {
1109 Opcode = SystemZ::RISBMux;
1110 OpcodeVT = MVT::i32;
1115 getUNDEF(
DL, OpcodeVT),
1117 CurDAG->getTargetConstant(RISBG.Start,
DL, MVT::i32),
1118 CurDAG->getTargetConstant(RISBG.End | 128,
DL, MVT::i32),
1119 CurDAG->getTargetConstant(RISBG.Rotate,
DL, MVT::i32)
1122 DL, VT, SDValue(CurDAG->getMachineNode(Opcode,
DL, OpcodeVT,
Ops), 0));
1123 ReplaceNode(
N,
New.getNode());
1127bool SystemZDAGToDAGISel::tryRxSBG(SDNode *
N,
unsigned Opcode) {
1129 EVT VT =
N->getValueType(0);
1134 RxSBGOperands RxSBG[] = {
1135 RxSBGOperands(Opcode,
N->getOperand(0)),
1136 RxSBGOperands(Opcode,
N->getOperand(1))
1138 unsigned Count[] = { 0, 0 };
1139 for (
unsigned I = 0;
I < 2; ++
I)
1140 while (RxSBG[
I].
Input->hasOneUse() && expandRxSBG(RxSBG[
I]))
1160 if (Opcode == SystemZ::ROSBG && (RxSBG[
I].Mask & 0xff) == 0)
1162 if (
Load->getMemoryVT() == MVT::i8)
1167 if (Opcode == SystemZ::ROSBG && detectOrAndInsertion(Op0, RxSBG[
I].Mask)) {
1168 Opcode = SystemZ::RISBG;
1170 if (Subtarget->hasMiscellaneousExtensions())
1171 Opcode = SystemZ::RISBGN;
1177 CurDAG->getTargetConstant(RxSBG[
I].Start,
DL, MVT::i32),
1178 CurDAG->getTargetConstant(RxSBG[
I].
End,
DL, MVT::i32),
1179 CurDAG->getTargetConstant(RxSBG[
I].Rotate,
DL, MVT::i32)
1182 DL, VT, SDValue(CurDAG->getMachineNode(Opcode,
DL, MVT::i64,
Ops), 0));
1183 ReplaceNode(
N,
New.getNode());
1187void SystemZDAGToDAGISel::splitLargeImmediate(
unsigned Opcode, SDNode *Node,
1190 EVT VT =
Node->getValueType(0);
1192 SDValue
Upper = CurDAG->getConstant(UpperVal,
DL, VT);
1209 HandleSDNode Handle(
Upper);
1210 SelectCode(
Upper.getNode());
1211 Upper = Handle.getValue();
1214 SDValue
Lower = CurDAG->getConstant(LowerVal,
DL, VT);
1217 ReplaceNode(Node,
Or.getNode());
1219 SelectCode(
Or.getNode());
1222void SystemZDAGToDAGISel::loadVectorConstant(
1223 const SystemZVectorConstantInfo &VCI, SDNode *Node) {
1225 VCI.
Opcode == SystemZISD::REPLICATE ||
1226 VCI.
Opcode == SystemZISD::ROTATE_MASK) &&
1229 EVT VT =
Node->getValueType(0);
1232 for (
unsigned OpVal : VCI.
OpVals)
1233 Ops.push_back(CurDAG->getTargetConstant(OpVal,
DL, MVT::i32));
1237 ReplaceNode(Node,
Op.getNode());
1240 ReplaceNode(Node, BitCast.
getNode());
1241 SelectCode(BitCast.
getNode());
1243 unsigned SubRegIdx = (VT.
getSizeInBits() == 16 ? SystemZ::subreg_h16
1245 : SystemZ::subreg_h64);
1247 Node, CurDAG->getTargetExtractSubreg(SubRegIdx,
DL, VT,
Op).getNode());
1249 SelectCode(
Op.getNode());
1252SDNode *SystemZDAGToDAGISel::loadPoolVectorConstant(APInt Val, EVT VT, SDLoc
DL) {
1256 SDValue CP = CurDAG->getTargetConstantPool(
1257 ConstantInt::get(Type::getInt128Ty(*CurDAG->getContext()), Val),
1258 TLI->getPointerTy(CurDAG->getDataLayout()));
1262 SDValue(CurDAG->getMachineNode(SystemZ::LARL,
DL, PtrVT, CP), 0),
1263 CurDAG->getTargetConstant(0,
DL, PtrVT),
1264 CurDAG->getRegister(0, PtrVT),
1265 CurDAG->getEntryNode()
1267 ResNode = CurDAG->getMachineNode(SystemZ::VL,
DL, VT, MVT::Other,
Ops);
1273 MachineMemOperand *MemOp =
1281bool SystemZDAGToDAGISel::tryGather(SDNode *
N,
unsigned Opcode) {
1287 unsigned Elem = ElemN->getZExtValue();
1288 EVT VT =
N->getValueType(0);
1293 if (!
Load || !
Load->hasNUsesOfValue(1, 0))
1295 if (
Load->getMemoryVT().getSizeInBits() !=
1296 Load->getValueType(0).getSizeInBits())
1300 if (!selectBDVAddr12Only(
Load->getBasePtr(), ElemV,
Base, Disp, Index) ||
1307 CurDAG->getTargetConstant(Elem,
DL, MVT::i32),
Load->getChain()
1309 SDNode *Res = CurDAG->getMachineNode(Opcode,
DL, VT, MVT::Other,
Ops);
1310 ReplaceUses(SDValue(
Load, 1), SDValue(Res, 1));
1311 ReplaceNode(
N, Res);
1315bool SystemZDAGToDAGISel::tryScatter(StoreSDNode *
Store,
unsigned Opcode) {
1319 if (
Store->getMemoryVT().getSizeInBits() !=
Value.getValueSizeInBits())
1322 SDValue ElemV =
Value.getOperand(1);
1327 SDValue Vec =
Value.getOperand(0);
1329 unsigned Elem = ElemN->getZExtValue();
1334 if (!selectBDVAddr12Only(
Store->getBasePtr(), ElemV,
Base, Disp, Index) ||
1340 Vec,
Base, Disp,
Index, CurDAG->getTargetConstant(Elem,
DL, MVT::i32),
1343 ReplaceNode(
Store, CurDAG->getMachineNode(Opcode,
DL, MVT::Other,
Ops));
1374 if (!
Load.hasOneUse())
1386 bool ChainCheck =
false;
1387 if (Chain ==
Load.getValue(1)) {
1394 const unsigned int Max = 1024;
1397 if (
Op ==
Load.getValue(1)) {
1410 if (
Op.getNode() != LoadNode)
1421 MVT::Other, ChainOps);
1438bool SystemZDAGToDAGISel::tryFoldLoadStoreIntoMemOperand(SDNode *Node) {
1440 SDValue StoredVal = StoreNode->
getOperand(1);
1442 SDLoc
DL(StoreNode);
1448 unsigned NewOpc = 0;
1449 bool NegateOperand =
false;
1453 case SystemZISD::SSUBO:
1454 NegateOperand =
true;
1456 case SystemZISD::SADDO:
1457 if (MemVT == MVT::i32)
1458 NewOpc = SystemZ::ASI;
1459 else if (MemVT == MVT::i64)
1460 NewOpc = SystemZ::AGSI;
1464 case SystemZISD::USUBO:
1465 NegateOperand =
true;
1467 case SystemZISD::UADDO:
1468 if (MemVT == MVT::i32)
1469 NewOpc = SystemZ::ALSI;
1470 else if (MemVT == MVT::i64)
1471 NewOpc = SystemZ::ALGSI;
1477 LoadSDNode *LoadNode =
nullptr;
1487 auto OperandV = OperandC->getAPIntValue();
1489 OperandV = -OperandV;
1490 if (OperandV.getSignificantBits() > 8)
1492 Operand = CurDAG->getTargetConstant(OperandV,
DL, MemVT);
1498 SDValue
Ops[] = {
Base, Disp, Operand, InputChain };
1500 CurDAG->getMachineNode(NewOpc,
DL, MVT::i32, MVT::Other,
Ops);
1501 CurDAG->setNodeMemRefs(
1504 ReplaceUses(SDValue(StoreNode, 0), SDValue(Result, 1));
1505 ReplaceUses(SDValue(StoredVal.
getNode(), 1), SDValue(Result, 0));
1506 CurDAG->RemoveDeadNode(Node);
1510bool SystemZDAGToDAGISel::canUseBlockOperation(StoreSDNode *
Store,
1511 LoadSDNode *
Load)
const {
1513 if (
Load->getMemoryVT() !=
Store->getMemoryVT())
1517 if (
Load->isVolatile() ||
Store->isVolatile())
1521 if (
Load->isInvariant() &&
Load->isDereferenceable())
1525 const Value *
V1 =
Load->getMemOperand()->getValue();
1526 const Value *V2 =
Store->getMemOperand()->getValue();
1532 int64_t End1 =
Load->getSrcValueOffset() +
Size;
1533 int64_t End2 =
Store->getSrcValueOffset() +
Size;
1534 if (
V1 == V2 && End1 == End2)
1537 return BatchAA->isNoAlias(MemoryLocation(
V1, End1,
Load->getAAInfo()),
1538 MemoryLocation(V2, End2,
Store->getAAInfo()));
1541bool SystemZDAGToDAGISel::storeLoadCanUseMVC(SDNode *
N)
const {
1557 return canUseBlockOperation(
Store,
Load);
1560bool SystemZDAGToDAGISel::storeLoadCanUseBlockBinary(SDNode *
N,
1565 return !LoadA->isVolatile() && LoadA->getMemoryVT() == LoadB->getMemoryVT() &&
1566 canUseBlockOperation(StoreA, LoadB);
1569bool SystemZDAGToDAGISel::storeLoadIsAligned(SDNode *
N)
const {
1573 TypeSize StoreSize = MemAccess->getMemoryVT().getStoreSize();
1574 SDValue
BasePtr = MemAccess->getBasePtr();
1575 MachineMemOperand *MMO = MemAccess->getMemOperand();
1576 assert(MMO &&
"Expected a memory operand.");
1580 if (MemAccess->getAlign().value() < StoreSize ||
1581 (LdSt && !LdSt->getOffset().isUndef()))
1590 if ((PSV->isGOT() || PSV->isConstantPool()))
1595 if (GlobalAddressSDNode *GA =
1598 if (GA->getOffset() % StoreSize != 0)
1602 const GlobalValue *GV = GA->getGlobal();
1614 ETy =
L->getExtensionType();
1616 ETy =
AL->getExtensionType();
1622void SystemZDAGToDAGISel::Select(SDNode *Node) {
1624 if (
Node->isMachineOpcode()) {
1626 Node->setNodeId(-1);
1630 unsigned Opcode =
Node->getOpcode();
1634 if (tryRxSBG(Node, SystemZ::ROSBG))
1640 if (tryRxSBG(Node, SystemZ::RXSBG))
1647 if (
Node->getValueType(0) == MVT::i64 &&
1650 uint64_t Val = Op1->getZExtValue();
1653 if (Subtarget->hasMiscellaneousExtensions3()) {
1654 unsigned ChildOpcode =
Node->getOperand(0).getOpcode();
1663 auto Op0 =
Node->getOperand(0);
1665 if (Op0Op1->getZExtValue() == (
uint64_t)-1)
1670 if (Opcode ==
ISD::XOR && Op1->isAllOnes())
1673 splitLargeImmediate(Opcode, Node,
Node->getOperand(0),
1674 Val - uint32_t(Val), uint32_t(Val));
1682 if (tryRxSBG(Node, SystemZ::RNSBG))
1686 if (
Node->getValueType(0) == MVT::i64 &&
1688 SDValue
Input =
Node->getOperand(0)->getOperand(0);
1692 EVT VecVT =
Input->getOperand(0)->getValueType(0);
1705 if (tryRISBGZero(Node))
1710 if (
Node->getValueType(0) == MVT::i128) {
1712 SDValue Src =
Node->getOperand(0);
1715 uint64_t Bytes[2] = { 0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL };
1716 SDNode *
Mask = loadPoolVectorConstant(APInt(128, Bytes), MVT::v16i8,
DL);
1717 SDValue
Ops[] = { Src, Src, SDValue(Mask, 0) };
1718 SDValue Res = SDValue(CurDAG->getMachineNode(SystemZ::VPERM,
DL,
1719 MVT::v16i8,
Ops), 0);
1722 SDNode *ResNode = Res.
getNode();
1723 ReplaceNode(Node, ResNode);
1724 SelectCode(Src.getNode());
1725 SelectCode(ResNode);
1733 if (
Node->getValueType(0) == MVT::i64) {
1736 splitLargeImmediate(
ISD::OR, Node, SDValue(), Val - uint32_t(Val),
1741 if (
Node->getValueType(0) == MVT::i128) {
1742 const APInt &Val =
Node->getAsAPIntVal();
1743 SystemZVectorConstantInfo VCI(Val);
1745 loadVectorConstant(VCI, Node);
1749 SDNode *ResNode = loadPoolVectorConstant(Val, MVT::i128, SDLoc(Node));
1750 ReplaceNode(Node, ResNode);
1755 case SystemZISD::SELECT_CCMASK: {
1756 SDValue Op0 =
Node->getOperand(0);
1757 SDValue Op1 =
Node->getOperand(1);
1761 (Subtarget->hasLoadStoreOnCond2() &&
1762 Node->getValueType(0).isInteger() &&
1763 Node->getValueType(0).getSizeInBits() <= 64 &&
1768 SDValue CCValid =
Node->getOperand(2);
1769 SDValue CCMask =
Node->getOperand(3);
1773 CCMask = CurDAG->getTargetConstant(ConstCCValid ^ ConstCCMask,
1775 SDValue Op4 =
Node->getOperand(4);
1776 SDNode *UpdatedNode =
1777 CurDAG->UpdateNodeOperands(Node, Op1, Op0, CCValid, CCMask, Op4);
1778 if (UpdatedNode != Node) {
1780 ReplaceNode(Node, UpdatedNode);
1788 EVT VT =
Node->getValueType(0);
1790 if (ElemBitSize == 32) {
1791 if (tryGather(Node, SystemZ::VGEF))
1793 }
else if (ElemBitSize == 64) {
1794 if (tryGather(Node, SystemZ::VGEG))
1801 if (!Subtarget->hasVector())
1804 SystemZVectorConstantInfo VCI(BVN);
1806 loadVectorConstant(VCI, Node);
1814 if (
Imm.isZero() ||
Imm.isNegZero())
1816 SystemZVectorConstantInfo VCI(
Imm);
1819 loadVectorConstant(VCI, Node);
1824 if (tryFoldLoadStoreIntoMemOperand(Node))
1827 unsigned ElemBitSize =
Store->getValue().getValueSizeInBits();
1828 if (ElemBitSize == 32) {
1829 if (tryScatter(
Store, SystemZ::VSCEF))
1831 }
else if (ElemBitSize == 64) {
1832 if (tryScatter(
Store, SystemZ::VSCEG))
1844 AtomOp->getChain(), SDLoc(AtomOp), AtomOp->getVal(),
1845 AtomOp->getBasePtr(), AtomOp->getMemoryVT(), AtomOp->getMemOperand()));
1846 assert(St->getMemOperand()->isAtomic() &&
"Broken MMO.");
1850 if (AtomOp->getSuccessOrdering() == AtomicOrdering::SequentiallyConsistent)
1851 Chain = CurDAG->getMachineNode(SystemZ::Serialize, SDLoc(AtomOp),
1852 MVT::Other, SDValue(Chain, 0));
1853 ReplaceNode(Node, Chain);
1862bool SystemZDAGToDAGISel::SelectInlineAsmMemoryOperand(
1864 std::vector<SDValue> &OutOps) {
1865 SystemZAddressingMode::AddrForm
Form;
1866 SystemZAddressingMode::DispRange DispRange;
1869 switch(ConstraintID) {
1872 case InlineAsm::ConstraintCode::i:
1873 case InlineAsm::ConstraintCode::Q:
1874 case InlineAsm::ConstraintCode::ZQ:
1876 Form = SystemZAddressingMode::FormBD;
1877 DispRange = SystemZAddressingMode::Disp12Only;
1879 case InlineAsm::ConstraintCode::R:
1880 case InlineAsm::ConstraintCode::ZR:
1882 Form = SystemZAddressingMode::FormBDXNormal;
1883 DispRange = SystemZAddressingMode::Disp12Only;
1885 case InlineAsm::ConstraintCode::S:
1886 case InlineAsm::ConstraintCode::ZS:
1888 Form = SystemZAddressingMode::FormBD;
1889 DispRange = SystemZAddressingMode::Disp20Only;
1891 case InlineAsm::ConstraintCode::T:
1892 case InlineAsm::ConstraintCode::m:
1893 case InlineAsm::ConstraintCode::o:
1894 case InlineAsm::ConstraintCode::p:
1895 case InlineAsm::ConstraintCode::ZT:
1900 Form = SystemZAddressingMode::FormBDXNormal;
1901 DispRange = SystemZAddressingMode::Disp20Only;
1905 if (selectBDXAddr(Form, DispRange,
Op,
Base, Disp, Index)) {
1910 SDValue RC = CurDAG->getTargetConstant(TRC->
getID(),
DL, MVT::i32);
1917 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
1925 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
1930 OutOps.push_back(
Base);
1931 OutOps.push_back(Disp);
1932 OutOps.push_back(Index);
1942SystemZDAGToDAGISel::IsProfitableToFold(SDValue
N, SDNode *U,
1943 SDNode *Root)
const {
1946 if (
N.getOpcode() ==
ISD::LOAD &&
U->getOpcode() == SystemZISD::ICMP) {
1947 if (!
N.hasOneUse() || !
U->hasOneUse())
1954 SDNode *CCUser = *
U->user_begin();
1955 SDNode *CCRegUser =
nullptr;
1958 for (
auto *U : CCUser->
users()) {
1959 if (CCRegUser ==
nullptr)
1961 else if (CCRegUser != U)
1965 if (CCRegUser ==
nullptr)
1978 if (!IsLegalToFold(
N, U, CCRegUser, OptLevel,
false))
1988struct IPMConversion {
1989 IPMConversion(
unsigned xorValue, int64_t addValue,
unsigned bit)
1990 : XORValue(xorValue), AddValue(addValue), Bit(bit) {}
2065SDValue SystemZDAGToDAGISel::expandSelectBoolean(SDNode *Node) {
2068 if (!TrueOp || !FalseOp)
2070 if (FalseOp->getZExtValue() != 0)
2072 if (TrueOp->getSExtValue() != 1 && TrueOp->getSExtValue() != -1)
2077 if (!CCValidOp || !CCMaskOp)
2079 int CCValid = CCValidOp->getZExtValue();
2080 int CCMask = CCMaskOp->getZExtValue();
2083 SDValue CCReg =
Node->getOperand(4);
2085 SDValue
Result = CurDAG->getNode(SystemZISD::IPM,
DL, MVT::i32, CCReg);
2089 CurDAG->getConstant(IPM.XORValue,
DL, MVT::i32));
2093 CurDAG->getNode(
ISD::ADD,
DL, MVT::i32, Result,
2094 CurDAG->getSignedConstant(IPM.AddValue,
DL, MVT::i32));
2096 EVT VT =
Node->getValueType(0);
2097 if (VT == MVT::i32 && IPM.Bit == 31) {
2099 Result = CurDAG->getNode(ShiftOp,
DL, MVT::i32, Result,
2100 CurDAG->getConstant(IPM.Bit,
DL, MVT::i32));
2105 if (TrueOp->getSExtValue() == 1) {
2108 CurDAG->getConstant(IPM.Bit,
DL, MVT::i32));
2110 CurDAG->getConstant(1,
DL, VT));
2116 CurDAG->getConstant(ShlAmt,
DL, MVT::i32));
2118 CurDAG->getConstant(SraAmt,
DL, MVT::i32));
2125bool SystemZDAGToDAGISel::shouldSelectForReassoc(SDNode *
N)
const {
2126 EVT VT =
N->getValueType(0);
2128 return N->getFlags().hasAllowReassociation() &&
2129 N->getFlags().hasNoSignedZeros() && Subtarget->hasVector() &&
2130 (VT != MVT::f32 || Subtarget->hasVectorEnhancements1()) &&
2131 !
N->isStrictFPOpcode();
2134void SystemZDAGToDAGISel::PreprocessISelDAG() {
2137 if (Subtarget->hasLoadStoreOnCond2())
2140 bool MadeChange =
false;
2143 E = CurDAG->allnodes_end();
2150 switch (
N->getOpcode()) {
2152 case SystemZISD::SELECT_CCMASK:
2153 Res = expandSelectBoolean(
N);
2158 LLVM_DEBUG(
dbgs() <<
"SystemZ DAG preprocessing replacing:\nOld: ");
2164 CurDAG->ReplaceAllUsesOfValueWith(SDValue(
N, 0), Res);
2170 CurDAG->RemoveDeadNodes();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
AMDGPU Register Bank Select
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const HexagonInstrInfo * TII
Module.h This file contains the declarations for the Module class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static void changeComponent(SystemZAddressingMode &AM, bool IsBase, SDValue Value)
static IPMConversion getIPMConversion(unsigned CCValid, unsigned CCMask)
static bool selectDisp(SystemZAddressingMode::DispRange DR, int64_t Val)
static bool expandAdjDynAlloc(SystemZAddressingMode &AM, bool IsBase, SDValue Value)
static bool isFusableLoadOpStorePattern(StoreSDNode *StoreNode, SDValue StoredVal, SelectionDAG *CurDAG, LoadSDNode *&LoadNode, SDValue &InputChain)
static bool isValidDisp(SystemZAddressingMode::DispRange DR, int64_t Val)
static bool expandIndex(SystemZAddressingMode &AM, SDValue Base, SDValue Index)
static bool maskMatters(RxSBGOperands &RxSBG, uint64_t Mask)
static bool expandDisp(SystemZAddressingMode &AM, bool IsBase, SDValue Op0, uint64_t Op1)
static bool shouldUseLA(SDNode *Base, int64_t Disp, SDNode *Index)
static void insertDAGNode(SelectionDAG *DAG, SDNode *Pos, SDValue N)
static uint64_t allOnes(unsigned int Count)
Class for arbitrary precision integers.
FunctionPass class - This class is used to implement most global optimizations.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
const SDValue & getOffset() const
unsigned getID() const
getID() - Return the register class ID number.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
const PseudoSourceValue * getPseudoValue() const
@ MOLoad
The memory access reads data.
int64_t getOffset() const
For normal values, this is a byte offset added to the base address.
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getChain() const
bool isNonTemporal() const
EVT getMemoryVT() const
Return the type of the in-memory value.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.
int getNodeId() const
Return the unique node id.
LLVM_ABI void dump() const
Dump this node, for debugging.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
static bool hasPredecessorHelper(const SDNode *N, SmallPtrSetImpl< const SDNode * > &Visited, SmallVectorImpl< const SDNode * > &Worklist, unsigned int MaxSteps=0, bool TopologicalPrune=false)
Returns true if N is a predecessor of any node in Worklist.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
const SDValue & getOperand(unsigned Num) const
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
iterator_range< user_iterator > users()
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
EVT getValueType() const
Return the ValueType of the referenced return value.
const SDValue & getOperand(unsigned i) const
unsigned getResNo() const
get the index which selects a specific result in the SDNode
unsigned getOpcode() const
unsigned getNumOperands() const
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
static int getUninvalidatedNodeId(SDNode *N)
virtual bool runOnMachineFunction(MachineFunction &mf)
static void InvalidateNodeId(SDNode *N)
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
void RepositionNode(allnodes_iterator Position, SDNode *N)
Move node N in the AllNodes list to be immediately before the given iterator Position.
ilist< SDNode >::iterator allnodes_iterator
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getOffset() const
const TargetRegisterClass * getInlineAsmMemoryOperandRegClass(InlineAsm::ConstraintCode C) const override
const SystemZInstrInfo * getInstrInfo() const override
Target - Wrapper for Target specific information.
LLVM Value Representation.
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BSWAP
Byte Swap and Counting operators.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ SIGN_EXTEND
Conversion operators.
@ SHL
Shift and rotation operations.
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
bool isPCREL(unsigned Opcode)
static bool isImmHF(uint64_t Val)
static bool isImmLF(uint64_t Val)
NodeAddr< NodeBase * > Node
std::pair< Instruction *, SmallVector< Value * > > convertTo(Instruction *I, const InstructionsState &S)
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
FunctionPass * createSystemZISelDag(SystemZTargetMachine &TM, CodeGenOptLevel OptLevel)
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
@ Known
Known to have no common set bits.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
CodeGenOptLevel
Code generation optimization level.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Or
Bitwise or logical OR of integers.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
@ End
Run the machine verifier once, at the end of the pipeline.
MCRegisterClass TargetRegisterClass
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
SmallVector< unsigned, 2 > OpVals
bool isVectorConstantLegal(const SystemZSubtarget &Subtarget)