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)
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);
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))
1802 SystemZVectorConstantInfo VCI(BVN);
1804 loadVectorConstant(VCI, Node);
1812 if (
Imm.isZero() ||
Imm.isNegZero())
1814 SystemZVectorConstantInfo VCI(
Imm);
1817 loadVectorConstant(VCI, Node);
1822 if (tryFoldLoadStoreIntoMemOperand(Node))
1825 unsigned ElemBitSize =
Store->getValue().getValueSizeInBits();
1826 if (ElemBitSize == 32) {
1827 if (tryScatter(
Store, SystemZ::VSCEF))
1829 }
else if (ElemBitSize == 64) {
1830 if (tryScatter(
Store, SystemZ::VSCEG))
1842 AtomOp->getChain(), SDLoc(AtomOp), AtomOp->getVal(),
1843 AtomOp->getBasePtr(), AtomOp->getMemoryVT(), AtomOp->getMemOperand()));
1844 assert(St->getMemOperand()->isAtomic() &&
"Broken MMO.");
1848 if (AtomOp->getSuccessOrdering() == AtomicOrdering::SequentiallyConsistent)
1849 Chain = CurDAG->getMachineNode(SystemZ::Serialize, SDLoc(AtomOp),
1850 MVT::Other, SDValue(Chain, 0));
1851 ReplaceNode(Node, Chain);
1860bool SystemZDAGToDAGISel::SelectInlineAsmMemoryOperand(
1862 std::vector<SDValue> &OutOps) {
1863 SystemZAddressingMode::AddrForm
Form;
1864 SystemZAddressingMode::DispRange DispRange;
1867 switch(ConstraintID) {
1870 case InlineAsm::ConstraintCode::i:
1871 case InlineAsm::ConstraintCode::Q:
1872 case InlineAsm::ConstraintCode::ZQ:
1874 Form = SystemZAddressingMode::FormBD;
1875 DispRange = SystemZAddressingMode::Disp12Only;
1877 case InlineAsm::ConstraintCode::R:
1878 case InlineAsm::ConstraintCode::ZR:
1880 Form = SystemZAddressingMode::FormBDXNormal;
1881 DispRange = SystemZAddressingMode::Disp12Only;
1883 case InlineAsm::ConstraintCode::S:
1884 case InlineAsm::ConstraintCode::ZS:
1886 Form = SystemZAddressingMode::FormBD;
1887 DispRange = SystemZAddressingMode::Disp20Only;
1889 case InlineAsm::ConstraintCode::T:
1890 case InlineAsm::ConstraintCode::m:
1891 case InlineAsm::ConstraintCode::o:
1892 case InlineAsm::ConstraintCode::p:
1893 case InlineAsm::ConstraintCode::ZT:
1898 Form = SystemZAddressingMode::FormBDXNormal;
1899 DispRange = SystemZAddressingMode::Disp20Only;
1903 if (selectBDXAddr(Form, DispRange,
Op,
Base, Disp, Index)) {
1908 SDValue RC = CurDAG->getTargetConstant(TRC->
getID(),
DL, MVT::i32);
1915 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
1923 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
1928 OutOps.push_back(
Base);
1929 OutOps.push_back(Disp);
1930 OutOps.push_back(Index);
1940SystemZDAGToDAGISel::IsProfitableToFold(SDValue
N, SDNode *U,
1941 SDNode *Root)
const {
1944 if (
N.getOpcode() ==
ISD::LOAD &&
U->getOpcode() == SystemZISD::ICMP) {
1945 if (!
N.hasOneUse() || !
U->hasOneUse())
1952 SDNode *CCUser = *
U->user_begin();
1953 SDNode *CCRegUser =
nullptr;
1956 for (
auto *U : CCUser->
users()) {
1957 if (CCRegUser ==
nullptr)
1959 else if (CCRegUser != U)
1963 if (CCRegUser ==
nullptr)
1976 if (!IsLegalToFold(
N, U, CCRegUser, OptLevel,
false))
1986struct IPMConversion {
1987 IPMConversion(
unsigned xorValue, int64_t addValue,
unsigned bit)
1988 : XORValue(xorValue), AddValue(addValue), Bit(bit) {}
2063SDValue SystemZDAGToDAGISel::expandSelectBoolean(SDNode *Node) {
2066 if (!TrueOp || !FalseOp)
2068 if (FalseOp->getZExtValue() != 0)
2070 if (TrueOp->getSExtValue() != 1 && TrueOp->getSExtValue() != -1)
2075 if (!CCValidOp || !CCMaskOp)
2077 int CCValid = CCValidOp->getZExtValue();
2078 int CCMask = CCMaskOp->getZExtValue();
2081 SDValue CCReg =
Node->getOperand(4);
2083 SDValue
Result = CurDAG->getNode(SystemZISD::IPM,
DL, MVT::i32, CCReg);
2087 CurDAG->getConstant(IPM.XORValue,
DL, MVT::i32));
2091 CurDAG->getNode(
ISD::ADD,
DL, MVT::i32, Result,
2092 CurDAG->getSignedConstant(IPM.AddValue,
DL, MVT::i32));
2094 EVT VT =
Node->getValueType(0);
2095 if (VT == MVT::i32 && IPM.Bit == 31) {
2097 Result = CurDAG->getNode(ShiftOp,
DL, MVT::i32, Result,
2098 CurDAG->getConstant(IPM.Bit,
DL, MVT::i32));
2103 if (TrueOp->getSExtValue() == 1) {
2106 CurDAG->getConstant(IPM.Bit,
DL, MVT::i32));
2108 CurDAG->getConstant(1,
DL, VT));
2114 CurDAG->getConstant(ShlAmt,
DL, MVT::i32));
2116 CurDAG->getConstant(SraAmt,
DL, MVT::i32));
2123bool SystemZDAGToDAGISel::shouldSelectForReassoc(SDNode *
N)
const {
2124 EVT VT =
N->getValueType(0);
2126 return N->getFlags().hasAllowReassociation() &&
2127 N->getFlags().hasNoSignedZeros() && Subtarget->hasVector() &&
2128 (VT != MVT::f32 || Subtarget->hasVectorEnhancements1()) &&
2129 !
N->isStrictFPOpcode();
2132void SystemZDAGToDAGISel::PreprocessISelDAG() {
2135 if (Subtarget->hasLoadStoreOnCond2())
2138 bool MadeChange =
false;
2141 E = CurDAG->allnodes_end();
2148 switch (
N->getOpcode()) {
2150 case SystemZISD::SELECT_CCMASK:
2151 Res = expandSelectBoolean(
N);
2156 LLVM_DEBUG(
dbgs() <<
"SystemZ DAG preprocessing replacing:\nOld: ");
2162 CurDAG->ReplaceAllUsesOfValueWith(SDValue(
N, 0), Res);
2168 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.
bool hasOneUse() const
Return true if there is exactly one use of 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.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
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)