LLVM 24.0.0git
SystemZISelDAGToDAG.cpp
Go to the documentation of this file.
1//===-- SystemZISelDAGToDAG.cpp - A dag to dag inst selector for SystemZ --===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines an instruction selector for the SystemZ target.
10//
11//===----------------------------------------------------------------------===//
12
13#include "SystemZISelLowering.h"
17#include "llvm/IR/Module.h"
18#include "llvm/Support/Debug.h"
21
22using namespace llvm;
23
24#define DEBUG_TYPE "systemz-isel"
25#define PASS_NAME "SystemZ DAG->DAG Pattern Instruction Selection"
26
27namespace {
28// Used to build addressing modes.
29struct SystemZAddressingMode {
30 // The shape of the address.
31 enum AddrForm {
32 // base+displacement
33 FormBD,
34
35 // base+displacement+index for load and store operands
36 FormBDXNormal,
37
38 // base+displacement+index for load address operands
39 FormBDXLA,
40
41 // base+displacement+index+ADJDYNALLOC
42 FormBDXDynAlloc
43 };
44 AddrForm Form;
45
46 // The type of displacement. The enum names here correspond directly
47 // to the definitions in SystemZOperand.td. We could split them into
48 // flags -- single/pair, 128-bit, etc. -- but it hardly seems worth it.
49 enum DispRange {
50 Disp12Only,
51 Disp12Pair,
52 Disp20Only,
53 Disp20Only128,
54 Disp20Pair
55 };
56 DispRange DR;
57
58 // The parts of the address. The address is equivalent to:
59 //
60 // Base + Disp + Index + (IncludesDynAlloc ? ADJDYNALLOC : 0)
62 int64_t Disp;
63 SDValue Index;
64 bool IncludesDynAlloc;
65
66 SystemZAddressingMode(AddrForm form, DispRange dr)
67 : Form(form), DR(dr), Disp(0), IncludesDynAlloc(false) {}
68
69 // True if the address can have an index register.
70 bool hasIndexField() { return Form != FormBD; }
71
72 // True if the address can (and must) include ADJDYNALLOC.
73 bool isDynAlloc() { return Form == FormBDXDynAlloc; }
74
75 void dump(const llvm::SelectionDAG *DAG) {
76 errs() << "SystemZAddressingMode " << this << '\n';
77
78 errs() << " Base ";
79 if (Base.getNode())
80 Base.getNode()->dump(DAG);
81 else
82 errs() << "null\n";
83
84 if (hasIndexField()) {
85 errs() << " Index ";
86 if (Index.getNode())
87 Index.getNode()->dump(DAG);
88 else
89 errs() << "null\n";
90 }
91
92 errs() << " Disp " << Disp;
93 if (IncludesDynAlloc)
94 errs() << " + ADJDYNALLOC";
95 errs() << '\n';
96 }
97};
98
99// Return a mask with Count low bits set.
100static uint64_t allOnes(unsigned int Count) {
101 assert(Count <= 64);
102 if (Count > 63)
103 return UINT64_MAX;
104 return (uint64_t(1) << Count) - 1;
105}
106
107// Represents operands 2 to 5 of the ROTATE AND ... SELECTED BITS operation
108// given by Opcode. The operands are: Input (R2), Start (I3), End (I4) and
109// Rotate (I5). The combined operand value is effectively:
110//
111// (or (rotl Input, Rotate), ~Mask)
112//
113// for RNSBG and:
114//
115// (and (rotl Input, Rotate), Mask)
116//
117// otherwise. The output value has BitSize bits, although Input may be
118// narrower (in which case the upper bits are don't care), or wider (in which
119// case the result will be truncated as part of the operation).
120struct RxSBGOperands {
121 RxSBGOperands(unsigned Op, SDValue N)
122 : Opcode(Op), BitSize(N.getValueSizeInBits()),
123 Mask(allOnes(BitSize)), Input(N), Start(64 - BitSize), End(63),
124 Rotate(0) {}
125
126 unsigned Opcode;
127 unsigned BitSize;
128 uint64_t Mask;
130 unsigned Start;
131 unsigned End;
132 unsigned Rotate;
133};
134
135class SystemZDAGToDAGISel : public SelectionDAGISel {
136 const SystemZSubtarget *Subtarget;
137
138 // Used by SystemZOperands.td to create integer constants.
139 inline SDValue getImm(const SDNode *Node, uint64_t Imm) const {
140 return CurDAG->getTargetConstant(Imm, SDLoc(Node), Node->getValueType(0));
141 }
142
143 const SystemZTargetMachine &getTargetMachine() const {
144 return static_cast<const SystemZTargetMachine &>(TM);
145 }
146
147 const SystemZInstrInfo *getInstrInfo() const {
148 return Subtarget->getInstrInfo();
149 }
150
151 // Try to fold more of the base or index of AM into AM, where IsBase
152 // selects between the base and index.
153 bool expandAddress(SystemZAddressingMode &AM, bool IsBase) const;
154
155 // Try to describe N in AM, returning true on success.
156 bool selectAddress(SDValue N, SystemZAddressingMode &AM) const;
157
158 // Extract individual target operands from matched address AM.
159 void getAddressOperands(const SystemZAddressingMode &AM, EVT VT,
160 SDValue &Base, SDValue &Disp) const;
161 void getAddressOperands(const SystemZAddressingMode &AM, EVT VT,
162 SDValue &Base, SDValue &Disp, SDValue &Index) const;
163
164 // Try to match Addr as a FormBD address with displacement type DR.
165 // Return true on success, storing the base and displacement in
166 // Base and Disp respectively.
167 bool selectBDAddr(SystemZAddressingMode::DispRange DR, SDValue Addr,
168 SDValue &Base, SDValue &Disp, int64_t Offset = 0) const;
169
170 // Try to match Addr as a FormBDX address with displacement type DR.
171 // Return true on success and if the result had no index. Store the
172 // base and displacement in Base and Disp respectively.
173 bool selectMVIAddr(SystemZAddressingMode::DispRange DR, SDValue Addr,
174 SDValue &Base, SDValue &Disp) const;
175
176 // Try to match Addr as a FormBDX* address of form Form with
177 // displacement type DR. Return true on success, storing the base,
178 // displacement and index in Base, Disp and Index respectively.
179 bool selectBDXAddr(SystemZAddressingMode::AddrForm Form,
180 SystemZAddressingMode::DispRange DR, SDValue Addr,
181 SDValue &Base, SDValue &Disp, SDValue &Index) const;
182
183 // PC-relative address matching routines used by SystemZOperands.td.
184 bool selectPCRelAddress(SDValue Addr, SDValue &Target) const {
185 if (SystemZISD::isPCREL(Addr.getOpcode())) {
186 Target = Addr.getOperand(0);
187 return true;
188 }
189 return false;
190 }
191
192 // BD matching routines used by SystemZOperands.td.
193 bool selectBDAddr12Only(SDValue Addr, SDValue &Base, SDValue &Disp) const {
194 return selectBDAddr(SystemZAddressingMode::Disp12Only, Addr, Base, Disp);
195 }
196 bool selectBDAddr12Pair(SDValue Addr, SDValue &Base, SDValue &Disp) const {
197 return selectBDAddr(SystemZAddressingMode::Disp12Pair, Addr, Base, Disp);
198 }
199 bool selectBDAddr20Only(SDValue Addr, SDValue &Base, SDValue &Disp) const {
200 return selectBDAddr(SystemZAddressingMode::Disp20Only, Addr, Base, Disp);
201 }
202 bool selectBDAddr20Pair(SDValue Addr, SDValue &Base, SDValue &Disp) const {
203 return selectBDAddr(SystemZAddressingMode::Disp20Pair, Addr, Base, Disp);
204 }
205
206 // MVI matching routines used by SystemZOperands.td.
207 bool selectMVIAddr12Pair(SDValue Addr, SDValue &Base, SDValue &Disp) const {
208 return selectMVIAddr(SystemZAddressingMode::Disp12Pair, Addr, Base, Disp);
209 }
210 bool selectMVIAddr20Pair(SDValue Addr, SDValue &Base, SDValue &Disp) const {
211 return selectMVIAddr(SystemZAddressingMode::Disp20Pair, Addr, Base, Disp);
212 }
213
214 // BDX matching routines used by SystemZOperands.td.
215 bool selectBDXAddr12Only(SDValue Addr, SDValue &Base, SDValue &Disp,
216 SDValue &Index) const {
217 return selectBDXAddr(SystemZAddressingMode::FormBDXNormal,
218 SystemZAddressingMode::Disp12Only,
219 Addr, Base, Disp, Index);
220 }
221 bool selectBDXAddr12Pair(SDValue Addr, SDValue &Base, SDValue &Disp,
222 SDValue &Index) const {
223 return selectBDXAddr(SystemZAddressingMode::FormBDXNormal,
224 SystemZAddressingMode::Disp12Pair,
225 Addr, Base, Disp, Index);
226 }
227 bool selectDynAlloc12Only(SDValue Addr, SDValue &Base, SDValue &Disp,
228 SDValue &Index) const {
229 return selectBDXAddr(SystemZAddressingMode::FormBDXDynAlloc,
230 SystemZAddressingMode::Disp12Only,
231 Addr, Base, Disp, Index);
232 }
233 bool selectBDXAddr20Only(SDValue Addr, SDValue &Base, SDValue &Disp,
234 SDValue &Index) const {
235 return selectBDXAddr(SystemZAddressingMode::FormBDXNormal,
236 SystemZAddressingMode::Disp20Only,
237 Addr, Base, Disp, Index);
238 }
239 bool selectBDXAddr20Only128(SDValue Addr, SDValue &Base, SDValue &Disp,
240 SDValue &Index) const {
241 return selectBDXAddr(SystemZAddressingMode::FormBDXNormal,
242 SystemZAddressingMode::Disp20Only128,
243 Addr, Base, Disp, Index);
244 }
245 bool selectBDXAddr20Pair(SDValue Addr, SDValue &Base, SDValue &Disp,
246 SDValue &Index) const {
247 return selectBDXAddr(SystemZAddressingMode::FormBDXNormal,
248 SystemZAddressingMode::Disp20Pair,
249 Addr, Base, Disp, Index);
250 }
251 bool selectLAAddr12Pair(SDValue Addr, SDValue &Base, SDValue &Disp,
252 SDValue &Index) const {
253 return selectBDXAddr(SystemZAddressingMode::FormBDXLA,
254 SystemZAddressingMode::Disp12Pair,
255 Addr, Base, Disp, Index);
256 }
257 bool selectLAAddr20Pair(SDValue Addr, SDValue &Base, SDValue &Disp,
258 SDValue &Index) const {
259 return selectBDXAddr(SystemZAddressingMode::FormBDXLA,
260 SystemZAddressingMode::Disp20Pair,
261 Addr, Base, Disp, Index);
262 }
263
264 // Try to match Addr as an address with a base, 12-bit displacement
265 // and index, where the index is element Elem of a vector.
266 // Return true on success, storing the base, displacement and vector
267 // in Base, Disp and Index respectively.
268 bool selectBDVAddr12Only(SDValue Addr, SDValue Elem, SDValue &Base,
269 SDValue &Disp, SDValue &Index) const;
270 // Wrapper functions for LSB access on big-endian multi-byte types.
271 // Selects a Base + Displacement address and applies a fixed byte Offset.
272 // Offsets: i16 LSB = +1, i32 LSB = +3, i64 LSB = +7.
273 bool selectBDAddr12off1(SDValue Addr, SDValue &Base, SDValue &Disp) const;
274 bool selectBDAddr12off3(SDValue Addr, SDValue &Base, SDValue &Disp) const;
275 bool selectBDAddr12off7(SDValue Addr, SDValue &Base, SDValue &Disp) const;
276 bool selectBDAddr20off1(SDValue Addr, SDValue &Base, SDValue &Disp) const;
277 bool selectBDAddr20off3(SDValue Addr, SDValue &Base, SDValue &Disp) const;
278 bool selectBDAddr20off7(SDValue Addr, SDValue &Base, SDValue &Disp) const;
279
280 // Check whether (or Op (and X InsertMask)) is effectively an insertion
281 // of X into bits InsertMask of some Y != Op. Return true if so and
282 // set Op to that Y.
283 bool detectOrAndInsertion(SDValue &Op, uint64_t InsertMask) const;
284
285 // Try to update RxSBG so that only the bits of RxSBG.Input in Mask are used.
286 // Return true on success.
287 bool refineRxSBGMask(RxSBGOperands &RxSBG, uint64_t Mask) const;
288
289 // Try to fold some of RxSBG.Input into other fields of RxSBG.
290 // Return true on success.
291 bool expandRxSBG(RxSBGOperands &RxSBG) const;
292
293 // Return an undefined value of type VT.
294 SDValue getUNDEF(const SDLoc &DL, EVT VT) const;
295
296 // Convert N to VT, if it isn't already.
297 SDValue convertTo(const SDLoc &DL, EVT VT, SDValue N) const;
298
299 // Try to implement AND or shift node N using RISBG with the zero flag set.
300 // Return the selected node on success, otherwise return null.
301 bool tryRISBGZero(SDNode *N);
302
303 // Try to use RISBG or Opcode to implement OR or XOR node N.
304 // Return the selected node on success, otherwise return null.
305 bool tryRxSBG(SDNode *N, unsigned Opcode);
306
307 // If Op0 is null, then Node is a constant that can be loaded using:
308 //
309 // (Opcode UpperVal LowerVal)
310 //
311 // If Op0 is nonnull, then Node can be implemented using:
312 //
313 // (Opcode (Opcode Op0 UpperVal) LowerVal)
314 void splitLargeImmediate(unsigned Opcode, SDNode *Node, SDValue Op0,
315 uint64_t UpperVal, uint64_t LowerVal);
316
317 void loadVectorConstant(const SystemZVectorConstantInfo &VCI,
318 SDNode *Node);
319
320 SDNode *loadPoolVectorConstant(APInt Val, EVT VT, SDLoc DL);
321
322 // Try to use gather instruction Opcode to implement vector insertion N.
323 bool tryGather(SDNode *N, unsigned Opcode);
324
325 // Try to use scatter instruction Opcode to implement store Store.
326 bool tryScatter(StoreSDNode *Store, unsigned Opcode);
327
328 // Change a chain of {load; op; store} of the same value into a simple op
329 // through memory of that value, if the uses of the modified value and its
330 // address are suitable.
331 bool tryFoldLoadStoreIntoMemOperand(SDNode *Node);
332
333 // Return true if Load and Store are loads and stores of the same size
334 // and are guaranteed not to overlap. Such operations can be implemented
335 // using block (SS-format) instructions.
336 //
337 // Partial overlap would lead to incorrect code, since the block operations
338 // are logically bytewise, even though they have a fast path for the
339 // non-overlapping case. We also need to avoid full overlap (i.e. two
340 // addresses that might be equal at run time) because although that case
341 // would be handled correctly, it might be implemented by millicode.
342 bool canUseBlockOperation(StoreSDNode *Store, LoadSDNode *Load) const;
343
344 // N is a (store (load Y), X) pattern. Return true if it can use an MVC
345 // from Y to X.
346 bool storeLoadCanUseMVC(SDNode *N) const;
347
348 // N is a (store (op (load A[0]), (load A[1])), X) pattern. Return true
349 // if A[1 - I] == X and if N can use a block operation like NC from A[I]
350 // to X.
351 bool storeLoadCanUseBlockBinary(SDNode *N, unsigned I) const;
352
353 // Return true if N (a load or a store) fullfills the alignment
354 // requirements for a PC-relative access.
355 bool storeLoadIsAligned(SDNode *N) const;
356
357 // Return the load extension type of a load or atomic load.
358 ISD::LoadExtType getLoadExtType(SDNode *N) const;
359
360 // Try to expand a boolean SELECT_CCMASK using an IPM sequence.
361 SDValue expandSelectBoolean(SDNode *Node);
362
363 // Return true if the flags of N and the subtarget allows for
364 // reassociation, in which case a reg/reg opcode is needed as input to the
365 // MachineCombiner.
366 bool shouldSelectForReassoc(SDNode *N) const;
367
368public:
369 SystemZDAGToDAGISel() = delete;
370
371 SystemZDAGToDAGISel(SystemZTargetMachine &TM, CodeGenOptLevel OptLevel)
372 : SelectionDAGISel(TM, OptLevel) {}
373
374 bool runOnMachineFunction(MachineFunction &MF) override {
375 const Function &F = MF.getFunction();
376 if (F.getParent()->getStackProtectorGuard() != "global") {
377 if (F.getParent()->hasStackProtectorGuardRecord())
378 report_fatal_error("mstack-protector-guard-record only supported with "
379 "mstack-protector-guard=global");
380 }
381 Subtarget = &MF.getSubtarget<SystemZSubtarget>();
383 }
384
385 // Override SelectionDAGISel.
386 void Select(SDNode *Node) override;
387 bool SelectInlineAsmMemoryOperand(const SDValue &Op,
388 InlineAsm::ConstraintCode ConstraintID,
389 std::vector<SDValue> &OutOps) override;
390 bool IsProfitableToFold(SDValue N, SDNode *U, SDNode *Root) const override;
391 void PreprocessISelDAG() override;
392
393 // Include the pieces autogenerated from the target description.
394 #include "SystemZGenDAGISel.inc"
395};
396
397class SystemZDAGToDAGISelLegacy : public SelectionDAGISelLegacy {
398public:
399 static char ID;
400 explicit SystemZDAGToDAGISelLegacy(SystemZTargetMachine &TM,
401 CodeGenOptLevel OptLevel)
403 ID, std::make_unique<SystemZDAGToDAGISel>(TM, OptLevel)) {}
404};
405} // end anonymous namespace
406
407char SystemZDAGToDAGISelLegacy::ID = 0;
408
409INITIALIZE_PASS(SystemZDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false)
410
412 CodeGenOptLevel OptLevel) {
413 return new SystemZDAGToDAGISelLegacy(TM, OptLevel);
414}
415
416// Return true if Val should be selected as a displacement for an address
417// with range DR. Here we're interested in the range of both the instruction
418// described by DR and of any pairing instruction.
419static bool selectDisp(SystemZAddressingMode::DispRange DR, int64_t Val) {
420 switch (DR) {
421 case SystemZAddressingMode::Disp12Only:
422 return isUInt<12>(Val);
423
424 case SystemZAddressingMode::Disp12Pair:
425 case SystemZAddressingMode::Disp20Only:
426 case SystemZAddressingMode::Disp20Pair:
427 return isInt<20>(Val);
428
429 case SystemZAddressingMode::Disp20Only128:
430 return isInt<20>(Val) && isInt<20>(Val + 8);
431 }
432 llvm_unreachable("Unhandled displacement range");
433}
434
435// Change the base or index in AM to Value, where IsBase selects
436// between the base and index.
437static void changeComponent(SystemZAddressingMode &AM, bool IsBase,
438 SDValue Value) {
439 if (IsBase)
440 AM.Base = Value;
441 else
442 AM.Index = Value;
443}
444
445// The base or index of AM is equivalent to Value + ADJDYNALLOC,
446// where IsBase selects between the base and index. Try to fold the
447// ADJDYNALLOC into AM.
448static bool expandAdjDynAlloc(SystemZAddressingMode &AM, bool IsBase,
449 SDValue Value) {
450 if (AM.isDynAlloc() && !AM.IncludesDynAlloc) {
451 changeComponent(AM, IsBase, Value);
452 AM.IncludesDynAlloc = true;
453 return true;
454 }
455 return false;
456}
457
458// The base of AM is equivalent to Base + Index. Try to use Index as
459// the index register.
460static bool expandIndex(SystemZAddressingMode &AM, SDValue Base,
461 SDValue Index) {
462 if (AM.hasIndexField() && !AM.Index.getNode()) {
463 AM.Base = Base;
464 AM.Index = Index;
465 return true;
466 }
467 return false;
468}
469
470// The base or index of AM is equivalent to Op0 + Op1, where IsBase selects
471// between the base and index. Try to fold Op1 into AM's displacement.
472static bool expandDisp(SystemZAddressingMode &AM, bool IsBase,
473 SDValue Op0, uint64_t Op1) {
474 // First try adjusting the displacement.
475 int64_t TestDisp = AM.Disp + Op1;
476 if (selectDisp(AM.DR, TestDisp)) {
477 changeComponent(AM, IsBase, Op0);
478 AM.Disp = TestDisp;
479 return true;
480 }
481
482 // We could consider forcing the displacement into a register and
483 // using it as an index, but it would need to be carefully tuned.
484 return false;
485}
486
487bool SystemZDAGToDAGISel::expandAddress(SystemZAddressingMode &AM,
488 bool IsBase) const {
489 SDValue N = IsBase ? AM.Base : AM.Index;
490 unsigned Opcode = N.getOpcode();
491 // Look through no-op truncations.
492 if (Opcode == ISD::TRUNCATE && N.getOperand(0).getValueSizeInBits() <= 64) {
493 N = N.getOperand(0);
494 Opcode = N.getOpcode();
495 }
496 if (Opcode == ISD::ADD || CurDAG->isBaseWithConstantOffset(N)) {
497 SDValue Op0 = N.getOperand(0);
498 SDValue Op1 = N.getOperand(1);
499
500 unsigned Op0Code = Op0->getOpcode();
501 unsigned Op1Code = Op1->getOpcode();
502
503 if (Op0Code == SystemZISD::ADJDYNALLOC)
504 return expandAdjDynAlloc(AM, IsBase, Op1);
505 if (Op1Code == SystemZISD::ADJDYNALLOC)
506 return expandAdjDynAlloc(AM, IsBase, Op0);
507
508 if (Op0Code == ISD::Constant)
509 return expandDisp(AM, IsBase, Op1,
510 cast<ConstantSDNode>(Op0)->getSExtValue());
511 if (Op1Code == ISD::Constant)
512 return expandDisp(AM, IsBase, Op0,
513 cast<ConstantSDNode>(Op1)->getSExtValue());
514
515 if (IsBase && expandIndex(AM, Op0, Op1))
516 return true;
517 }
518 if (Opcode == SystemZISD::PCREL_OFFSET) {
519 SDValue Full = N.getOperand(0);
520 SDValue Base = N.getOperand(1);
521 SDValue Anchor = Base.getOperand(0);
523 cast<GlobalAddressSDNode>(Anchor)->getOffset());
524 return expandDisp(AM, IsBase, Base, Offset);
525 }
526 return false;
527}
528
529// Return true if an instruction with displacement range DR should be
530// used for displacement value Val. selectDisp(DR, Val) must already hold.
531static bool isValidDisp(SystemZAddressingMode::DispRange DR, int64_t Val) {
532 assert(selectDisp(DR, Val) && "Invalid displacement");
533 switch (DR) {
534 case SystemZAddressingMode::Disp12Only:
535 case SystemZAddressingMode::Disp20Only:
536 case SystemZAddressingMode::Disp20Only128:
537 return true;
538
539 case SystemZAddressingMode::Disp12Pair:
540 // Use the other instruction if the displacement is too large.
541 return isUInt<12>(Val);
542
543 case SystemZAddressingMode::Disp20Pair:
544 // Use the other instruction if the displacement is small enough.
545 return !isUInt<12>(Val);
546 }
547 llvm_unreachable("Unhandled displacement range");
548}
549
550// Return true if Base + Disp + Index should be performed by LA(Y).
551static bool shouldUseLA(SDNode *Base, int64_t Disp, SDNode *Index) {
552 // Don't use LA(Y) for constants.
553 if (!Base)
554 return false;
555
556 // Always use LA(Y) for frame addresses, since we know that the destination
557 // register is almost always (perhaps always) going to be different from
558 // the frame register.
559 if (Base->getOpcode() == ISD::FrameIndex)
560 return true;
561
562 if (Disp) {
563 // Always use LA(Y) if there is a base, displacement and index.
564 if (Index)
565 return true;
566
567 // Always use LA if the displacement is small enough. It should always
568 // be no worse than AGHI (and better if it avoids a move).
569 if (isUInt<12>(Disp))
570 return true;
571
572 // For similar reasons, always use LAY if the constant is too big for AGHI.
573 // LAY should be no worse than AGFI.
574 if (!isInt<16>(Disp))
575 return true;
576 } else {
577 // Don't use LA for plain registers.
578 if (!Index)
579 return false;
580
581 // Don't use LA for plain addition if the index operand is only used
582 // once. It should be a natural two-operand addition in that case.
583 if (Index->hasOneUse())
584 return false;
585
586 // Prefer addition if the second operation is sign-extended, in the
587 // hope of using AGF.
588 unsigned IndexOpcode = Index->getOpcode();
589 if (IndexOpcode == ISD::SIGN_EXTEND ||
590 IndexOpcode == ISD::SIGN_EXTEND_INREG)
591 return false;
592 }
593
594 // Don't use LA for two-operand addition if either operand is only
595 // used once. The addition instructions are better in that case.
596 if (Base->hasOneUse())
597 return false;
598
599 return true;
600}
601
602// Return true if Addr is suitable for AM, updating AM if so.
603bool SystemZDAGToDAGISel::selectAddress(SDValue Addr,
604 SystemZAddressingMode &AM) const {
605 // Start out assuming that the address will need to be loaded separately,
606 // then try to extend it as much as we can.
607 AM.Base = Addr;
608
609 // First try treating the address as a constant.
610 if (Addr.getOpcode() == ISD::Constant &&
611 expandDisp(AM, true, SDValue(),
612 cast<ConstantSDNode>(Addr)->getSExtValue()))
613 ;
614 // Also see if it's a bare ADJDYNALLOC.
615 else if (Addr.getOpcode() == SystemZISD::ADJDYNALLOC &&
616 expandAdjDynAlloc(AM, true, SDValue()))
617 ;
618 else
619 // Otherwise try expanding each component.
620 while (expandAddress(AM, true) ||
621 (AM.Index.getNode() && expandAddress(AM, false)))
622 continue;
623
624 // Reject cases where it isn't profitable to use LA(Y).
625 if (AM.Form == SystemZAddressingMode::FormBDXLA &&
626 !shouldUseLA(AM.Base.getNode(), AM.Disp, AM.Index.getNode()))
627 return false;
628
629 // Reject cases where the other instruction in a pair should be used.
630 if (!isValidDisp(AM.DR, AM.Disp))
631 return false;
632
633 // Make sure that ADJDYNALLOC is included where necessary.
634 if (AM.isDynAlloc() && !AM.IncludesDynAlloc)
635 return false;
636
637 LLVM_DEBUG(AM.dump(CurDAG));
638 return true;
639}
640
641// Insert a node into the DAG at least before Pos. This will reposition
642// the node as needed, and will assign it a node ID that is <= Pos's ID.
643// Note that this does *not* preserve the uniqueness of node IDs!
644// The selection DAG must no longer depend on their uniqueness when this
645// function is used.
646static void insertDAGNode(SelectionDAG *DAG, SDNode *Pos, SDValue N) {
647 if (N->getNodeId() == -1 ||
650 DAG->RepositionNode(Pos->getIterator(), N.getNode());
651 // Mark Node as invalid for pruning as after this it may be a successor to a
652 // selected node but otherwise be in the same position of Pos.
653 // Conservatively mark it with the same -abs(Id) to assure node id
654 // invariant is preserved.
655 N->setNodeId(Pos->getNodeId());
657 }
658}
659
660void SystemZDAGToDAGISel::getAddressOperands(const SystemZAddressingMode &AM,
661 EVT VT, SDValue &Base,
662 SDValue &Disp) const {
663 Base = AM.Base;
664 if (!Base.getNode())
665 // Register 0 means "no base". This is mostly useful for shifts.
666 Base = CurDAG->getRegister(0, VT);
667 else if (Base.getOpcode() == ISD::FrameIndex) {
668 // Lower a FrameIndex to a TargetFrameIndex.
669 int64_t FrameIndex = cast<FrameIndexSDNode>(Base)->getIndex();
670 Base = CurDAG->getTargetFrameIndex(FrameIndex, VT);
671 } else if (Base.getValueType() != VT) {
672 // Truncate values from i64 to i32, for shifts.
673 assert(VT == MVT::i32 && Base.getValueType() == MVT::i64 &&
674 "Unexpected truncation");
675 SDLoc DL(Base);
676 SDValue Trunc = CurDAG->getNode(ISD::TRUNCATE, DL, VT, Base);
677 insertDAGNode(CurDAG, Base.getNode(), Trunc);
678 Base = Trunc;
679 }
680
681 // Lower the displacement to a TargetConstant.
682 Disp = CurDAG->getSignedTargetConstant(AM.Disp, SDLoc(Base), VT);
683}
684
685void SystemZDAGToDAGISel::getAddressOperands(const SystemZAddressingMode &AM,
686 EVT VT, SDValue &Base,
687 SDValue &Disp,
688 SDValue &Index) const {
689 getAddressOperands(AM, VT, Base, Disp);
690
691 Index = AM.Index;
692 if (!Index.getNode())
693 // Register 0 means "no index".
694 Index = CurDAG->getRegister(0, VT);
695}
696
697bool SystemZDAGToDAGISel::selectBDAddr(SystemZAddressingMode::DispRange DR,
698 SDValue Addr, SDValue &Base,
699 SDValue &Disp, int64_t Offset) const {
700 SystemZAddressingMode AM(SystemZAddressingMode::FormBD, DR);
701 AM.Disp += Offset;
702 if (!selectAddress(Addr, AM))
703 return false;
704
705 getAddressOperands(AM, Addr.getValueType(), Base, Disp);
706 return true;
707}
708
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())
714 return false;
715
716 getAddressOperands(AM, Addr.getValueType(), Base, Disp);
717 return true;
718}
719
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))
726 return false;
727
728 getAddressOperands(AM, Addr.getValueType(), Base, Disp, Index);
729 return true;
730}
731
732bool SystemZDAGToDAGISel::selectBDVAddr12Only(SDValue Addr, SDValue Elem,
733 SDValue &Base,
734 SDValue &Disp,
735 SDValue &Index) const {
736 SDValue Regs[2];
737 if (selectBDXAddr12Only(Addr, Regs[0], Disp, Regs[1]) &&
738 Regs[0].getNode() && Regs[1].getNode()) {
739 for (unsigned int I = 0; I < 2; ++I) {
740 Base = Regs[I];
741 Index = Regs[1 - I];
742 // We can't tell here whether the index vector has the right type
743 // for the access; the caller needs to do that instead.
744 if (Index.getOpcode() == ISD::ZERO_EXTEND)
745 Index = Index.getOperand(0);
746 if (Index.getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
747 Index.getOperand(1) == Elem) {
748 Index = Index.getOperand(0);
749 return true;
750 }
751 }
752 }
753 return false;
754}
755
756bool SystemZDAGToDAGISel::selectBDAddr12off1(SDValue A, SDValue &B,
757 SDValue &D) const {
758 return selectBDAddr(SystemZAddressingMode::Disp12Pair, A, B, D, 1);
759}
760bool SystemZDAGToDAGISel::selectBDAddr12off3(SDValue A, SDValue &B,
761 SDValue &D) const {
762 return selectBDAddr(SystemZAddressingMode::Disp12Pair, A, B, D, 3);
763}
764bool SystemZDAGToDAGISel::selectBDAddr12off7(SDValue A, SDValue &B,
765 SDValue &D) const {
766 return selectBDAddr(SystemZAddressingMode::Disp12Pair, A, B, D, 7);
767}
768
769bool SystemZDAGToDAGISel::selectBDAddr20off1(SDValue A, SDValue &B,
770 SDValue &D) const {
771 return selectBDAddr(SystemZAddressingMode::Disp20Pair, A, B, D, 1);
772}
773bool SystemZDAGToDAGISel::selectBDAddr20off3(SDValue A, SDValue &B,
774 SDValue &D) const {
775 return selectBDAddr(SystemZAddressingMode::Disp20Pair, A, B, D, 3);
776}
777bool SystemZDAGToDAGISel::selectBDAddr20off7(SDValue A, SDValue &B,
778 SDValue &D) const {
779 return selectBDAddr(SystemZAddressingMode::Disp20Pair, A, B, D, 7);
780}
781
782bool SystemZDAGToDAGISel::detectOrAndInsertion(SDValue &Op,
783 uint64_t InsertMask) const {
784 // We're only interested in cases where the insertion is into some operand
785 // of Op, rather than into Op itself. The only useful case is an AND.
786 if (Op.getOpcode() != ISD::AND)
787 return false;
788
789 // We need a constant mask.
790 auto *MaskNode = dyn_cast<ConstantSDNode>(Op.getOperand(1).getNode());
791 if (!MaskNode)
792 return false;
793
794 // It's not an insertion of Op.getOperand(0) if the two masks overlap.
795 uint64_t AndMask = MaskNode->getZExtValue();
796 if (InsertMask & AndMask)
797 return false;
798
799 // It's only an insertion if all bits are covered or are known to be zero.
800 // The inner check covers all cases but is more expensive.
801 uint64_t Used = allOnes(Op.getValueSizeInBits());
802 if (Used != (AndMask | InsertMask)) {
803 KnownBits Known = CurDAG->computeKnownBits(Op.getOperand(0));
804 if (Used != (AndMask | InsertMask | Known.Zero.getZExtValue()))
805 return false;
806 }
807
808 Op = Op.getOperand(0);
809 return true;
810}
811
812bool SystemZDAGToDAGISel::refineRxSBGMask(RxSBGOperands &RxSBG,
813 uint64_t Mask) const {
814 const SystemZInstrInfo *TII = getInstrInfo();
815 if (RxSBG.Rotate != 0)
816 Mask = (Mask << RxSBG.Rotate) | (Mask >> (64 - RxSBG.Rotate));
817 Mask &= RxSBG.Mask;
818 if (TII->isRxSBGMask(Mask, RxSBG.BitSize, RxSBG.Start, RxSBG.End)) {
819 RxSBG.Mask = Mask;
820 return true;
821 }
822 return false;
823}
824
825// Return true if any bits of (RxSBG.Input & Mask) are significant.
826static bool maskMatters(RxSBGOperands &RxSBG, uint64_t Mask) {
827 // Rotate the mask in the same way as RxSBG.Input is rotated.
828 if (RxSBG.Rotate != 0)
829 Mask = ((Mask << RxSBG.Rotate) | (Mask >> (64 - RxSBG.Rotate)));
830 return (Mask & RxSBG.Mask) != 0;
831}
832
833bool SystemZDAGToDAGISel::expandRxSBG(RxSBGOperands &RxSBG) const {
834 SDValue N = RxSBG.Input;
835 unsigned Opcode = N.getOpcode();
836 switch (Opcode) {
837 case ISD::TRUNCATE: {
838 if (RxSBG.Opcode == SystemZ::RNSBG)
839 return false;
840 if (N.getOperand(0).getValueSizeInBits() > 64)
841 return false;
842 uint64_t BitSize = N.getValueSizeInBits();
843 uint64_t Mask = allOnes(BitSize);
844 if (!refineRxSBGMask(RxSBG, Mask))
845 return false;
846 RxSBG.Input = N.getOperand(0);
847 return true;
848 }
849 case ISD::AND: {
850 if (RxSBG.Opcode == SystemZ::RNSBG)
851 return false;
852
853 auto *MaskNode = dyn_cast<ConstantSDNode>(N.getOperand(1).getNode());
854 if (!MaskNode)
855 return false;
856
857 SDValue Input = N.getOperand(0);
858 uint64_t Mask = MaskNode->getZExtValue();
859 if (!refineRxSBGMask(RxSBG, Mask)) {
860 // If some bits of Input are already known zeros, those bits will have
861 // been removed from the mask. See if adding them back in makes the
862 // mask suitable.
863 KnownBits Known = CurDAG->computeKnownBits(Input);
864 Mask |= Known.Zero.getZExtValue();
865 if (!refineRxSBGMask(RxSBG, Mask))
866 return false;
867 }
868 RxSBG.Input = Input;
869 return true;
870 }
871
872 case ISD::OR: {
873 if (RxSBG.Opcode != SystemZ::RNSBG)
874 return false;
875
876 auto *MaskNode = dyn_cast<ConstantSDNode>(N.getOperand(1).getNode());
877 if (!MaskNode)
878 return false;
879
880 SDValue Input = N.getOperand(0);
881 uint64_t Mask = ~MaskNode->getZExtValue();
882 if (!refineRxSBGMask(RxSBG, Mask)) {
883 // If some bits of Input are already known ones, those bits will have
884 // been removed from the mask. See if adding them back in makes the
885 // mask suitable.
886 KnownBits Known = CurDAG->computeKnownBits(Input);
887 Mask &= ~Known.One.getZExtValue();
888 if (!refineRxSBGMask(RxSBG, Mask))
889 return false;
890 }
891 RxSBG.Input = Input;
892 return true;
893 }
894
895 case ISD::ROTL: {
896 // Any 64-bit rotate left can be merged into the RxSBG.
897 if (RxSBG.BitSize != 64 || N.getValueType() != MVT::i64)
898 return false;
899 auto *CountNode = dyn_cast<ConstantSDNode>(N.getOperand(1).getNode());
900 if (!CountNode)
901 return false;
902
903 RxSBG.Rotate = (RxSBG.Rotate + CountNode->getZExtValue()) & 63;
904 RxSBG.Input = N.getOperand(0);
905 return true;
906 }
907
908 case ISD::ANY_EXTEND:
909 // Bits above the extended operand are don't-care.
910 RxSBG.Input = N.getOperand(0);
911 return true;
912
913 case ISD::ZERO_EXTEND:
914 if (RxSBG.Opcode != SystemZ::RNSBG) {
915 // Restrict the mask to the extended operand.
916 unsigned InnerBitSize = N.getOperand(0).getValueSizeInBits();
917 if (!refineRxSBGMask(RxSBG, allOnes(InnerBitSize)))
918 return false;
919
920 RxSBG.Input = N.getOperand(0);
921 return true;
922 }
923 [[fallthrough]];
924
925 case ISD::SIGN_EXTEND: {
926 // Check that the extension bits are don't-care (i.e. are masked out
927 // by the final mask).
928 unsigned BitSize = N.getValueSizeInBits();
929 unsigned InnerBitSize = N.getOperand(0).getValueSizeInBits();
930 if (maskMatters(RxSBG, allOnes(BitSize) - allOnes(InnerBitSize))) {
931 // In the case where only the sign bit is active, increase Rotate with
932 // the extension width.
933 if (RxSBG.Mask == 1 && RxSBG.Rotate == 1)
934 RxSBG.Rotate += (BitSize - InnerBitSize);
935 else
936 return false;
937 }
938
939 RxSBG.Input = N.getOperand(0);
940 return true;
941 }
942
943 case ISD::SHL: {
944 auto *CountNode = dyn_cast<ConstantSDNode>(N.getOperand(1).getNode());
945 if (!CountNode)
946 return false;
947
948 uint64_t Count = CountNode->getZExtValue();
949 unsigned BitSize = N.getValueSizeInBits();
950 if (Count < 1 || Count >= BitSize)
951 return false;
952
953 if (RxSBG.Opcode == SystemZ::RNSBG) {
954 // Treat (shl X, count) as (rotl X, size-count) as long as the bottom
955 // count bits from RxSBG.Input are ignored.
956 if (maskMatters(RxSBG, allOnes(Count)))
957 return false;
958 } else {
959 // Treat (shl X, count) as (and (rotl X, count), ~0<<count).
960 if (!refineRxSBGMask(RxSBG, allOnes(BitSize - Count) << Count))
961 return false;
962 }
963
964 RxSBG.Rotate = (RxSBG.Rotate + Count) & 63;
965 RxSBG.Input = N.getOperand(0);
966 return true;
967 }
968
969 case ISD::SRL:
970 case ISD::SRA: {
971 auto *CountNode = dyn_cast<ConstantSDNode>(N.getOperand(1).getNode());
972 if (!CountNode)
973 return false;
974
975 uint64_t Count = CountNode->getZExtValue();
976 unsigned BitSize = N.getValueSizeInBits();
977 if (Count < 1 || Count >= BitSize)
978 return false;
979
980 if (RxSBG.Opcode == SystemZ::RNSBG || Opcode == ISD::SRA) {
981 // Treat (srl|sra X, count) as (rotl X, size-count) as long as the top
982 // count bits from RxSBG.Input are ignored.
983 if (maskMatters(RxSBG, allOnes(Count) << (BitSize - Count)))
984 return false;
985 } else {
986 // Treat (srl X, count), mask) as (and (rotl X, size-count), ~0>>count),
987 // which is similar to SLL above.
988 if (!refineRxSBGMask(RxSBG, allOnes(BitSize - Count)))
989 return false;
990 }
991
992 RxSBG.Rotate = (RxSBG.Rotate - Count) & 63;
993 RxSBG.Input = N.getOperand(0);
994 return true;
995 }
996 default:
997 return false;
998 }
999}
1000
1001SDValue SystemZDAGToDAGISel::getUNDEF(const SDLoc &DL, EVT VT) const {
1002 SDNode *N = CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, VT);
1003 return SDValue(N, 0);
1004}
1005
1006SDValue SystemZDAGToDAGISel::convertTo(const SDLoc &DL, EVT VT,
1007 SDValue N) const {
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");
1014 return N;
1015}
1016
1017bool SystemZDAGToDAGISel::tryRISBGZero(SDNode *N) {
1018 SDLoc DL(N);
1019 EVT VT = N->getValueType(0);
1020 if (!VT.isInteger() || VT.getSizeInBits() > 64)
1021 return false;
1022 RxSBGOperands RISBG(SystemZ::RISBG, SDValue(N, 0));
1023 unsigned Count = 0;
1024 while (expandRxSBG(RISBG))
1025 // The widening or narrowing is expected to be free.
1026 // Counting widening or narrowing as a saved operation will result in
1027 // preferring an R*SBG over a simple shift/logical instruction.
1028 if (RISBG.Input.getOpcode() != ISD::ANY_EXTEND &&
1029 RISBG.Input.getOpcode() != ISD::TRUNCATE)
1030 Count += 1;
1031 if (Count == 0 || isa<ConstantSDNode>(RISBG.Input))
1032 return false;
1033
1034 // Prefer to use normal shift instructions over RISBG, since they can handle
1035 // all cases and are sometimes shorter.
1036 if (Count == 1 && N->getOpcode() != ISD::AND)
1037 return false;
1038
1039 // Prefer LOAD LOGICAL INDEXED ADDRESS over RISBG in the case where we
1040 // can use its displacement to pull in an addition.
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)
1045 if (auto *C = dyn_cast<ConstantSDNode>(RISBG.Input.getOperand(1)))
1046 if (isInt<20>(C->getSExtValue()))
1047 return false;
1048
1049 // Prefer register extensions like LLC over RISBG. Also prefer to start
1050 // out with normal ANDs if one instruction would be enough. We can convert
1051 // these ANDs into an RISBG later if a three-address instruction is useful.
1052 if (RISBG.Rotate == 0) {
1053 bool PreferAnd = false;
1054 // Prefer AND for any 32-bit and-immediate operation.
1055 if (VT == MVT::i32)
1056 PreferAnd = true;
1057 // As well as for any 64-bit operation that can be implemented via LLC(R),
1058 // LLH(R), LLGT(R), or one of the and-immediate instructions.
1059 else if (RISBG.Mask == 0xff ||
1060 RISBG.Mask == 0xffff ||
1061 RISBG.Mask == 0x7fffffff ||
1062 SystemZ::isImmLF(~RISBG.Mask) ||
1063 SystemZ::isImmHF(~RISBG.Mask))
1064 PreferAnd = true;
1065 // And likewise for the LLZRGF instruction, which doesn't have a register
1066 // to register version.
1067 else if (auto *Load = dyn_cast<LoadSDNode>(RISBG.Input)) {
1068 if (Load->getMemoryVT() == MVT::i32 &&
1069 (Load->getExtensionType() == ISD::EXTLOAD ||
1070 Load->getExtensionType() == ISD::ZEXTLOAD) &&
1071 RISBG.Mask == 0xffffff00 &&
1072 Subtarget->hasLoadAndZeroRightmostByte())
1073 PreferAnd = true;
1074 }
1075 if (PreferAnd) {
1076 // Replace the current node with an AND. Note that the current node
1077 // might already be that same AND, in which case it is already CSE'd
1078 // with it, and we must not call ReplaceNode.
1079 SDValue In = convertTo(DL, VT, RISBG.Input);
1080 SDValue Mask = CurDAG->getConstant(RISBG.Mask, DL, VT);
1081 SDValue New = CurDAG->getNode(ISD::AND, DL, VT, In, Mask);
1082 if (N != New.getNode()) {
1083 insertDAGNode(CurDAG, N, Mask);
1084 insertDAGNode(CurDAG, N, New);
1085 ReplaceNode(N, New.getNode());
1086 N = New.getNode();
1087 }
1088 // Now, select the machine opcode to implement this operation.
1089 if (!N->isMachineOpcode())
1090 SelectCode(N);
1091 return true;
1092 }
1093 }
1094
1095 unsigned Opcode = SystemZ::RISBG;
1096 // Prefer RISBGN if available, since it does not clobber CC.
1097 if (Subtarget->hasMiscellaneousExtensions())
1098 Opcode = SystemZ::RISBGN;
1099 EVT OpcodeVT = MVT::i64;
1100 if (VT == MVT::i32 && Subtarget->hasHighWord() &&
1101 // We can only use the 32-bit instructions if all source bits are
1102 // in the low 32 bits without wrapping, both after rotation (because
1103 // of the smaller range for Start and End) and before rotation
1104 // (because the input value is truncated).
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;
1111 RISBG.Start &= 31;
1112 RISBG.End &= 31;
1113 }
1114 SDValue Ops[5] = {
1115 getUNDEF(DL, OpcodeVT),
1116 convertTo(DL, OpcodeVT, RISBG.Input),
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)
1120 };
1121 SDValue New = convertTo(
1122 DL, VT, SDValue(CurDAG->getMachineNode(Opcode, DL, OpcodeVT, Ops), 0));
1123 ReplaceNode(N, New.getNode());
1124 return true;
1125}
1126
1127bool SystemZDAGToDAGISel::tryRxSBG(SDNode *N, unsigned Opcode) {
1128 SDLoc DL(N);
1129 EVT VT = N->getValueType(0);
1130 if (!VT.isInteger() || VT.getSizeInBits() > 64)
1131 return false;
1132 // Try treating each operand of N as the second operand of the RxSBG
1133 // and see which goes deepest.
1134 RxSBGOperands RxSBG[] = {
1135 RxSBGOperands(Opcode, N->getOperand(0)),
1136 RxSBGOperands(Opcode, N->getOperand(1))
1137 };
1138 unsigned Count[] = { 0, 0 };
1139 for (unsigned I = 0; I < 2; ++I)
1140 while (RxSBG[I].Input->hasOneUse() && expandRxSBG(RxSBG[I]))
1141 // In cases of multiple users it seems better to keep the simple
1142 // instruction as they are one cycle faster, and it also helps in cases
1143 // where both inputs share a common node.
1144 // The widening or narrowing is expected to be free. Counting widening
1145 // or narrowing as a saved operation will result in preferring an R*SBG
1146 // over a simple shift/logical instruction.
1147 if (RxSBG[I].Input.getOpcode() != ISD::ANY_EXTEND &&
1148 RxSBG[I].Input.getOpcode() != ISD::TRUNCATE)
1149 Count[I] += 1;
1150
1151 // Do nothing if neither operand is suitable.
1152 if (Count[0] == 0 && Count[1] == 0)
1153 return false;
1154
1155 // Pick the deepest second operand.
1156 unsigned I = Count[0] > Count[1] ? 0 : 1;
1157 SDValue Op0 = N->getOperand(I ^ 1);
1158
1159 // Prefer IC for character insertions from memory.
1160 if (Opcode == SystemZ::ROSBG && (RxSBG[I].Mask & 0xff) == 0)
1161 if (auto *Load = dyn_cast<LoadSDNode>(Op0.getNode()))
1162 if (Load->getMemoryVT() == MVT::i8)
1163 return false;
1164
1165 // See whether we can avoid an AND in the first operand by converting
1166 // ROSBG to RISBG.
1167 if (Opcode == SystemZ::ROSBG && detectOrAndInsertion(Op0, RxSBG[I].Mask)) {
1168 Opcode = SystemZ::RISBG;
1169 // Prefer RISBGN if available, since it does not clobber CC.
1170 if (Subtarget->hasMiscellaneousExtensions())
1171 Opcode = SystemZ::RISBGN;
1172 }
1173
1174 SDValue Ops[5] = {
1175 convertTo(DL, MVT::i64, Op0),
1176 convertTo(DL, MVT::i64, RxSBG[I].Input),
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)
1180 };
1181 SDValue New = convertTo(
1182 DL, VT, SDValue(CurDAG->getMachineNode(Opcode, DL, MVT::i64, Ops), 0));
1183 ReplaceNode(N, New.getNode());
1184 return true;
1185}
1186
1187void SystemZDAGToDAGISel::splitLargeImmediate(unsigned Opcode, SDNode *Node,
1188 SDValue Op0, uint64_t UpperVal,
1189 uint64_t LowerVal) {
1190 EVT VT = Node->getValueType(0);
1191 SDLoc DL(Node);
1192 SDValue Upper = CurDAG->getConstant(UpperVal, DL, VT);
1193 if (Op0.getNode())
1194 Upper = CurDAG->getNode(Opcode, DL, VT, Op0, Upper);
1195
1196 {
1197 // When we haven't passed in Op0, Upper will be a constant. In order to
1198 // prevent folding back to the large immediate in `Or = getNode(...)` we run
1199 // SelectCode first and end up with an opaque machine node. This means that
1200 // we need to use a handle to keep track of Upper in case it gets CSE'd by
1201 // SelectCode.
1202 //
1203 // Note that in the case where Op0 is passed in we could just call
1204 // SelectCode(Upper) later, along with the SelectCode(Or), and avoid needing
1205 // the handle at all, but it's fine to do it here.
1206 //
1207 // TODO: This is a pretty hacky way to do this. Can we do something that
1208 // doesn't require a two paragraph explanation?
1209 HandleSDNode Handle(Upper);
1210 SelectCode(Upper.getNode());
1211 Upper = Handle.getValue();
1212 }
1213
1214 SDValue Lower = CurDAG->getConstant(LowerVal, DL, VT);
1215 SDValue Or = CurDAG->getNode(Opcode, DL, VT, Upper, Lower);
1216
1217 ReplaceNode(Node, Or.getNode());
1218
1219 SelectCode(Or.getNode());
1220}
1221
1222void SystemZDAGToDAGISel::loadVectorConstant(
1223 const SystemZVectorConstantInfo &VCI, SDNode *Node) {
1224 assert((VCI.Opcode == SystemZISD::BYTE_MASK ||
1225 VCI.Opcode == SystemZISD::REPLICATE ||
1226 VCI.Opcode == SystemZISD::ROTATE_MASK) &&
1227 "Bad opcode!");
1228 assert(VCI.VecVT.getSizeInBits() == 128 && "Expected a vector type");
1229 EVT VT = Node->getValueType(0);
1230 SDLoc DL(Node);
1232 for (unsigned OpVal : VCI.OpVals)
1233 Ops.push_back(CurDAG->getTargetConstant(OpVal, DL, MVT::i32));
1234 SDValue Op = CurDAG->getNode(VCI.Opcode, DL, VCI.VecVT, Ops);
1235
1236 if (VCI.VecVT == VT.getSimpleVT())
1237 ReplaceNode(Node, Op.getNode());
1238 else if (VT.getSizeInBits() == 128) {
1239 SDValue BitCast = CurDAG->getNode(ISD::BITCAST, DL, VT, Op);
1240 ReplaceNode(Node, BitCast.getNode());
1241 SelectCode(BitCast.getNode());
1242 } else { // half, float or double
1243 unsigned SubRegIdx = (VT.getSizeInBits() == 16 ? SystemZ::subreg_h16
1244 : VT.getSizeInBits() == 32 ? SystemZ::subreg_h32
1245 : SystemZ::subreg_h64);
1246 ReplaceNode(
1247 Node, CurDAG->getTargetExtractSubreg(SubRegIdx, DL, VT, Op).getNode());
1248 }
1249 SelectCode(Op.getNode());
1250}
1251
1252SDNode *SystemZDAGToDAGISel::loadPoolVectorConstant(APInt Val, EVT VT, SDLoc DL) {
1253 SDNode *ResNode;
1254 assert (VT.getSizeInBits() == 128);
1255
1256 SDValue CP = CurDAG->getTargetConstantPool(
1257 ConstantInt::get(Type::getInt128Ty(*CurDAG->getContext()), Val),
1258 TLI->getPointerTy(CurDAG->getDataLayout()));
1259
1260 EVT PtrVT = CP.getValueType();
1261 SDValue Ops[] = {
1262 SDValue(CurDAG->getMachineNode(SystemZ::LARL, DL, PtrVT, CP), 0),
1263 CurDAG->getTargetConstant(0, DL, PtrVT),
1264 CurDAG->getRegister(0, PtrVT),
1265 CurDAG->getEntryNode()
1266 };
1267 ResNode = CurDAG->getMachineNode(SystemZ::VL, DL, VT, MVT::Other, Ops);
1268
1269 // Annotate ResNode with memory operand information so that MachineInstr
1270 // queries work properly. This e.g. gives the register allocation the
1271 // required information for rematerialization.
1272 MachineFunction& MF = CurDAG->getMachineFunction();
1273 MachineMemOperand *MemOp =
1276
1277 CurDAG->setNodeMemRefs(cast<MachineSDNode>(ResNode), {MemOp});
1278 return ResNode;
1279}
1280
1281bool SystemZDAGToDAGISel::tryGather(SDNode *N, unsigned Opcode) {
1282 SDValue ElemV = N->getOperand(2);
1283 auto *ElemN = dyn_cast<ConstantSDNode>(ElemV);
1284 if (!ElemN)
1285 return false;
1286
1287 unsigned Elem = ElemN->getZExtValue();
1288 EVT VT = N->getValueType(0);
1289 if (Elem >= VT.getVectorNumElements())
1290 return false;
1291
1292 auto *Load = dyn_cast<LoadSDNode>(N->getOperand(1));
1293 if (!Load || !Load->hasNUsesOfValue(1, 0))
1294 return false;
1295 if (Load->getMemoryVT().getSizeInBits() !=
1296 Load->getValueType(0).getSizeInBits())
1297 return false;
1298
1299 SDValue Base, Disp, Index;
1300 if (!selectBDVAddr12Only(Load->getBasePtr(), ElemV, Base, Disp, Index) ||
1301 Index.getValueType() != VT.changeVectorElementTypeToInteger())
1302 return false;
1303
1304 SDLoc DL(Load);
1305 SDValue Ops[] = {
1306 N->getOperand(0), Base, Disp, Index,
1307 CurDAG->getTargetConstant(Elem, DL, MVT::i32), Load->getChain()
1308 };
1309 SDNode *Res = CurDAG->getMachineNode(Opcode, DL, VT, MVT::Other, Ops);
1310 ReplaceUses(SDValue(Load, 1), SDValue(Res, 1));
1311 ReplaceNode(N, Res);
1312 return true;
1313}
1314
1315bool SystemZDAGToDAGISel::tryScatter(StoreSDNode *Store, unsigned Opcode) {
1316 SDValue Value = Store->getValue();
1317 if (Value.getOpcode() != ISD::EXTRACT_VECTOR_ELT)
1318 return false;
1319 if (Store->getMemoryVT().getSizeInBits() != Value.getValueSizeInBits())
1320 return false;
1321
1322 SDValue ElemV = Value.getOperand(1);
1323 auto *ElemN = dyn_cast<ConstantSDNode>(ElemV);
1324 if (!ElemN)
1325 return false;
1326
1327 SDValue Vec = Value.getOperand(0);
1328 EVT VT = Vec.getValueType();
1329 unsigned Elem = ElemN->getZExtValue();
1330 if (Elem >= VT.getVectorNumElements())
1331 return false;
1332
1333 SDValue Base, Disp, Index;
1334 if (!selectBDVAddr12Only(Store->getBasePtr(), ElemV, Base, Disp, Index) ||
1335 Index.getValueType() != VT.changeVectorElementTypeToInteger())
1336 return false;
1337
1338 SDLoc DL(Store);
1339 SDValue Ops[] = {
1340 Vec, Base, Disp, Index, CurDAG->getTargetConstant(Elem, DL, MVT::i32),
1341 Store->getChain()
1342 };
1343 ReplaceNode(Store, CurDAG->getMachineNode(Opcode, DL, MVT::Other, Ops));
1344 return true;
1345}
1346
1347// Check whether or not the chain ending in StoreNode is suitable for doing
1348// the {load; op; store} to modify transformation.
1350 SDValue StoredVal, SelectionDAG *CurDAG,
1351 LoadSDNode *&LoadNode,
1352 SDValue &InputChain) {
1353 // Is the stored value result 0 of the operation?
1354 if (StoredVal.getResNo() != 0)
1355 return false;
1356
1357 // Are there other uses of the loaded value than the operation?
1358 if (!StoredVal.getNode()->hasNUsesOfValue(1, 0))
1359 return false;
1360
1361 // Is the store non-extending and non-indexed?
1362 if (!ISD::isNormalStore(StoreNode) || StoreNode->isNonTemporal())
1363 return false;
1364
1365 SDValue Load = StoredVal->getOperand(0);
1366 // Is the stored value a non-extending and non-indexed load?
1367 if (!ISD::isNormalLoad(Load.getNode()))
1368 return false;
1369
1370 // Return LoadNode by reference.
1371 LoadNode = cast<LoadSDNode>(Load);
1372
1373 // Is store the only read of the loaded value?
1374 if (!Load.hasOneUse())
1375 return false;
1376
1377 // Is the address of the store the same as the load?
1378 if (LoadNode->getBasePtr() != StoreNode->getBasePtr() ||
1379 LoadNode->getOffset() != StoreNode->getOffset())
1380 return false;
1381
1382 // Check if the chain is produced by the load or is a TokenFactor with
1383 // the load output chain as an operand. Return InputChain by reference.
1384 SDValue Chain = StoreNode->getChain();
1385
1386 bool ChainCheck = false;
1387 if (Chain == Load.getValue(1)) {
1388 ChainCheck = true;
1389 InputChain = LoadNode->getChain();
1390 } else if (Chain.getOpcode() == ISD::TokenFactor) {
1391 SmallVector<SDValue, 4> ChainOps;
1392 SmallVector<const SDNode *, 4> LoopWorklist;
1394 const unsigned int Max = 1024;
1395 for (unsigned i = 0, e = Chain.getNumOperands(); i != e; ++i) {
1396 SDValue Op = Chain.getOperand(i);
1397 if (Op == Load.getValue(1)) {
1398 ChainCheck = true;
1399 // Drop Load, but keep its chain. No cycle check necessary.
1400 ChainOps.push_back(Load.getOperand(0));
1401 continue;
1402 }
1403 LoopWorklist.push_back(Op.getNode());
1404 ChainOps.push_back(Op);
1405 }
1406
1407 if (ChainCheck) {
1408 // Add the other operand of StoredVal to worklist.
1409 for (SDValue Op : StoredVal->ops())
1410 if (Op.getNode() != LoadNode)
1411 LoopWorklist.push_back(Op.getNode());
1412
1413 // Check if Load is reachable from any of the nodes in the worklist.
1414 if (SDNode::hasPredecessorHelper(Load.getNode(), Visited, LoopWorklist, Max,
1415 true))
1416 return false;
1417
1418 // Make a new TokenFactor with all the other input chains except
1419 // for the load.
1420 InputChain = CurDAG->getNode(ISD::TokenFactor, SDLoc(Chain),
1421 MVT::Other, ChainOps);
1422 }
1423 }
1424 if (!ChainCheck)
1425 return false;
1426
1427 return true;
1428}
1429
1430// Change a chain of {load; op; store} of the same value into a simple op
1431// through memory of that value, if the uses of the modified value and its
1432// address are suitable.
1433//
1434// The tablegen pattern memory operand pattern is currently not able to match
1435// the case where the CC on the original operation are used.
1436//
1437// See the equivalent routine in X86ISelDAGToDAG for further comments.
1438bool SystemZDAGToDAGISel::tryFoldLoadStoreIntoMemOperand(SDNode *Node) {
1439 StoreSDNode *StoreNode = cast<StoreSDNode>(Node);
1440 SDValue StoredVal = StoreNode->getOperand(1);
1441 unsigned Opc = StoredVal->getOpcode();
1442 SDLoc DL(StoreNode);
1443
1444 // Before we try to select anything, make sure this is memory operand size
1445 // and opcode we can handle. Note that this must match the code below that
1446 // actually lowers the opcodes.
1447 EVT MemVT = StoreNode->getMemoryVT();
1448 unsigned NewOpc = 0;
1449 bool NegateOperand = false;
1450 switch (Opc) {
1451 default:
1452 return false;
1453 case SystemZISD::SSUBO:
1454 NegateOperand = true;
1455 [[fallthrough]];
1456 case SystemZISD::SADDO:
1457 if (MemVT == MVT::i32)
1458 NewOpc = SystemZ::ASI;
1459 else if (MemVT == MVT::i64)
1460 NewOpc = SystemZ::AGSI;
1461 else
1462 return false;
1463 break;
1464 case SystemZISD::USUBO:
1465 NegateOperand = true;
1466 [[fallthrough]];
1467 case SystemZISD::UADDO:
1468 if (MemVT == MVT::i32)
1469 NewOpc = SystemZ::ALSI;
1470 else if (MemVT == MVT::i64)
1471 NewOpc = SystemZ::ALGSI;
1472 else
1473 return false;
1474 break;
1475 }
1476
1477 LoadSDNode *LoadNode = nullptr;
1478 SDValue InputChain;
1479 if (!isFusableLoadOpStorePattern(StoreNode, StoredVal, CurDAG, LoadNode,
1480 InputChain))
1481 return false;
1482
1483 SDValue Operand = StoredVal.getOperand(1);
1484 auto *OperandC = dyn_cast<ConstantSDNode>(Operand);
1485 if (!OperandC)
1486 return false;
1487 auto OperandV = OperandC->getAPIntValue();
1488 if (NegateOperand)
1489 OperandV = -OperandV;
1490 if (OperandV.getSignificantBits() > 8)
1491 return false;
1492 Operand = CurDAG->getTargetConstant(OperandV, DL, MemVT);
1493
1494 SDValue Base, Disp;
1495 if (!selectBDAddr20Only(StoreNode->getBasePtr(), Base, Disp))
1496 return false;
1497
1498 SDValue Ops[] = { Base, Disp, Operand, InputChain };
1499 MachineSDNode *Result =
1500 CurDAG->getMachineNode(NewOpc, DL, MVT::i32, MVT::Other, Ops);
1501 CurDAG->setNodeMemRefs(
1502 Result, {StoreNode->getMemOperand(), LoadNode->getMemOperand()});
1503
1504 ReplaceUses(SDValue(StoreNode, 0), SDValue(Result, 1));
1505 ReplaceUses(SDValue(StoredVal.getNode(), 1), SDValue(Result, 0));
1506 CurDAG->RemoveDeadNode(Node);
1507 return true;
1508}
1509
1510bool SystemZDAGToDAGISel::canUseBlockOperation(StoreSDNode *Store,
1511 LoadSDNode *Load) const {
1512 // Check that the two memory operands have the same size.
1513 if (Load->getMemoryVT() != Store->getMemoryVT())
1514 return false;
1515
1516 // Volatility stops an access from being decomposed.
1517 if (Load->isVolatile() || Store->isVolatile())
1518 return false;
1519
1520 // There's no chance of overlap if the load is invariant.
1521 if (Load->isInvariant() && Load->isDereferenceable())
1522 return true;
1523
1524 // Otherwise we need to check whether there's an alias.
1525 const Value *V1 = Load->getMemOperand()->getValue();
1526 const Value *V2 = Store->getMemOperand()->getValue();
1527 if (!V1 || !V2)
1528 return false;
1529
1530 // Reject equality.
1531 uint64_t Size = Load->getMemoryVT().getStoreSize();
1532 int64_t End1 = Load->getSrcValueOffset() + Size;
1533 int64_t End2 = Store->getSrcValueOffset() + Size;
1534 if (V1 == V2 && End1 == End2)
1535 return false;
1536
1537 return BatchAA->isNoAlias(MemoryLocation(V1, End1, Load->getAAInfo()),
1538 MemoryLocation(V2, End2, Store->getAAInfo()));
1539}
1540
1541bool SystemZDAGToDAGISel::storeLoadCanUseMVC(SDNode *N) const {
1542 auto *Store = cast<StoreSDNode>(N);
1543 auto *Load = cast<LoadSDNode>(Store->getValue());
1544
1545 // Prefer not to use MVC if either address can use ... RELATIVE LONG
1546 // instructions.
1547 uint64_t Size = Load->getMemoryVT().getStoreSize();
1548 if (Size > 1 && Size <= 8) {
1549 // Prefer LHRL, LRL and LGRL.
1550 if (SystemZISD::isPCREL(Load->getBasePtr().getOpcode()))
1551 return false;
1552 // Prefer STHRL, STRL and STGRL.
1553 if (SystemZISD::isPCREL(Store->getBasePtr().getOpcode()))
1554 return false;
1555 }
1556
1557 return canUseBlockOperation(Store, Load);
1558}
1559
1560bool SystemZDAGToDAGISel::storeLoadCanUseBlockBinary(SDNode *N,
1561 unsigned I) const {
1562 auto *StoreA = cast<StoreSDNode>(N);
1563 auto *LoadA = cast<LoadSDNode>(StoreA->getValue().getOperand(1 - I));
1564 auto *LoadB = cast<LoadSDNode>(StoreA->getValue().getOperand(I));
1565 return !LoadA->isVolatile() && LoadA->getMemoryVT() == LoadB->getMemoryVT() &&
1566 canUseBlockOperation(StoreA, LoadB);
1567}
1568
1569bool SystemZDAGToDAGISel::storeLoadIsAligned(SDNode *N) const {
1570
1571 auto *MemAccess = cast<MemSDNode>(N);
1572 auto *LdSt = dyn_cast<LSBaseSDNode>(MemAccess);
1573 TypeSize StoreSize = MemAccess->getMemoryVT().getStoreSize();
1574 SDValue BasePtr = MemAccess->getBasePtr();
1575 MachineMemOperand *MMO = MemAccess->getMemOperand();
1576 assert(MMO && "Expected a memory operand.");
1577
1578 // The memory access must have a proper alignment and no index register.
1579 // Only load and store nodes have the offset operand (atomic loads do not).
1580 if (MemAccess->getAlign().value() < StoreSize ||
1581 (LdSt && !LdSt->getOffset().isUndef()))
1582 return false;
1583
1584 // The MMO must not have an unaligned offset.
1585 if (MMO->getOffset() % StoreSize != 0)
1586 return false;
1587
1588 // An access to GOT or the Constant Pool is aligned.
1589 if (const PseudoSourceValue *PSV = MMO->getPseudoValue())
1590 if ((PSV->isGOT() || PSV->isConstantPool()))
1591 return true;
1592
1593 // Check the alignment of a Global Address.
1594 if (BasePtr.getNumOperands())
1595 if (GlobalAddressSDNode *GA =
1596 dyn_cast<GlobalAddressSDNode>(BasePtr.getOperand(0))) {
1597 // The immediate offset must be aligned.
1598 if (GA->getOffset() % StoreSize != 0)
1599 return false;
1600
1601 // The alignment of the symbol itself must be at least the store size.
1602 const GlobalValue *GV = GA->getGlobal();
1603 const DataLayout &DL = GV->getDataLayout();
1604 if (GV->getPointerAlignment(DL).value() < StoreSize)
1605 return false;
1606 }
1607
1608 return true;
1609}
1610
1611ISD::LoadExtType SystemZDAGToDAGISel::getLoadExtType(SDNode *N) const {
1612 ISD::LoadExtType ETy;
1613 if (auto *L = dyn_cast<LoadSDNode>(N))
1614 ETy = L->getExtensionType();
1615 else if (auto *AL = dyn_cast<AtomicSDNode>(N))
1616 ETy = AL->getExtensionType();
1617 else
1618 llvm_unreachable("Unkown load node type.");
1619 return ETy;
1620}
1621
1622void SystemZDAGToDAGISel::Select(SDNode *Node) {
1623 // If we have a custom node, we already have selected!
1624 if (Node->isMachineOpcode()) {
1625 LLVM_DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n");
1626 Node->setNodeId(-1);
1627 return;
1628 }
1629
1630 unsigned Opcode = Node->getOpcode();
1631 switch (Opcode) {
1632 case ISD::OR:
1633 if (Node->getOperand(1).getOpcode() != ISD::Constant)
1634 if (tryRxSBG(Node, SystemZ::ROSBG))
1635 return;
1636 goto or_xor;
1637
1638 case ISD::XOR:
1639 if (Node->getOperand(1).getOpcode() != ISD::Constant)
1640 if (tryRxSBG(Node, SystemZ::RXSBG))
1641 return;
1642 // Fall through.
1643 or_xor:
1644 // If this is a 64-bit operation in which both 32-bit halves are nonzero,
1645 // split the operation into two. If both operands here happen to be
1646 // constant, leave this to common code to optimize.
1647 if (Node->getValueType(0) == MVT::i64 &&
1648 Node->getOperand(0).getOpcode() != ISD::Constant)
1649 if (auto *Op1 = dyn_cast<ConstantSDNode>(Node->getOperand(1))) {
1650 uint64_t Val = Op1->getZExtValue();
1651 // Don't split the operation if we can match one of the combined
1652 // logical operations provided by miscellaneous-extensions-3.
1653 if (Subtarget->hasMiscellaneousExtensions3()) {
1654 unsigned ChildOpcode = Node->getOperand(0).getOpcode();
1655 // Check whether this expression matches NAND/NOR/NXOR.
1656 if (Val == (uint64_t)-1 && Opcode == ISD::XOR)
1657 if (ChildOpcode == ISD::AND || ChildOpcode == ISD::OR ||
1658 ChildOpcode == ISD::XOR)
1659 break;
1660 // Check whether this expression matches OR-with-complement
1661 // (or matches an alternate pattern for NXOR).
1662 if (ChildOpcode == ISD::XOR) {
1663 auto Op0 = Node->getOperand(0);
1664 if (auto *Op0Op1 = dyn_cast<ConstantSDNode>(Op0->getOperand(1)))
1665 if (Op0Op1->getZExtValue() == (uint64_t)-1)
1666 break;
1667 }
1668 }
1669 // Don't split an XOR with -1 as LCGR/AGHI is more compact.
1670 if (Opcode == ISD::XOR && Op1->isAllOnes())
1671 break;
1672 if (!SystemZ::isImmLF(Val) && !SystemZ::isImmHF(Val)) {
1673 splitLargeImmediate(Opcode, Node, Node->getOperand(0),
1674 Val - uint32_t(Val), uint32_t(Val));
1675 return;
1676 }
1677 }
1678 break;
1679
1680 case ISD::AND:
1681 if (Node->getOperand(1).getOpcode() != ISD::Constant) {
1682 if (tryRxSBG(Node, SystemZ::RNSBG))
1683 return;
1684 } else {
1685 // Use patterns for zero-extending of vector element extraction.
1686 if (Node->getValueType(0) == MVT::i64 &&
1687 Node->getOperand(0)->getOpcode() == ISD::ANY_EXTEND) {
1688 SDValue Input = Node->getOperand(0)->getOperand(0);
1689 uint64_t Mask =
1690 cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
1691 if (Input->getOpcode() == ISD::EXTRACT_VECTOR_ELT) {
1692 EVT VecVT = Input->getOperand(0)->getValueType(0);
1693 unsigned EltBits = VecVT.getScalarSizeInBits();
1694 if (allOnes(EltBits) == Mask)
1695 break;
1696 }
1697 }
1698 }
1699
1700 [[fallthrough]];
1701 case ISD::ROTL:
1702 case ISD::SHL:
1703 case ISD::SRL:
1704 case ISD::ZERO_EXTEND:
1705 if (tryRISBGZero(Node))
1706 return;
1707 break;
1708
1709 case ISD::BSWAP:
1710 if (Node->getValueType(0) == MVT::i128) {
1711 SDLoc DL(Node);
1712 SDValue Src = Node->getOperand(0);
1713 Src = CurDAG->getNode(ISD::BITCAST, DL, MVT::v16i8, Src);
1714
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);
1720
1721 Res = CurDAG->getNode(ISD::BITCAST, DL, MVT::i128, Res);
1722 SDNode *ResNode = Res.getNode();
1723 ReplaceNode(Node, ResNode);
1724 SelectCode(Src.getNode());
1725 SelectCode(ResNode);
1726 return;
1727 }
1728 break;
1729
1730 case ISD::Constant:
1731 // If this is a 64-bit constant that is out of the range of LLILF,
1732 // LLIHF and LGFI, split it into two 32-bit pieces.
1733 if (Node->getValueType(0) == MVT::i64) {
1734 uint64_t Val = Node->getAsZExtVal();
1735 if (!SystemZ::isImmLF(Val) && !SystemZ::isImmHF(Val) && !isInt<32>(Val)) {
1736 splitLargeImmediate(ISD::OR, Node, SDValue(), Val - uint32_t(Val),
1737 uint32_t(Val));
1738 return;
1739 }
1740 }
1741 if (Node->getValueType(0) == MVT::i128) {
1742 const APInt &Val = Node->getAsAPIntVal();
1743 SystemZVectorConstantInfo VCI(Val);
1744 if (VCI.isVectorConstantLegal(*Subtarget)) {
1745 loadVectorConstant(VCI, Node);
1746 return;
1747 }
1748 // If we can't materialize the constant we need to use a literal pool.
1749 SDNode *ResNode = loadPoolVectorConstant(Val, MVT::i128, SDLoc(Node));
1750 ReplaceNode(Node, ResNode);
1751 return;
1752 }
1753 break;
1754
1755 case SystemZISD::SELECT_CCMASK: {
1756 SDValue Op0 = Node->getOperand(0);
1757 SDValue Op1 = Node->getOperand(1);
1758 // Prefer to put any load first, so that it can be matched as a
1759 // conditional load. Likewise for constants in range for LOCHI.
1760 if ((Op1.getOpcode() == ISD::LOAD && Op0.getOpcode() != ISD::LOAD) ||
1761 (Subtarget->hasLoadStoreOnCond2() &&
1762 Node->getValueType(0).isInteger() &&
1763 Node->getValueType(0).getSizeInBits() <= 64 &&
1764 Op1.getOpcode() == ISD::Constant &&
1765 isInt<16>(cast<ConstantSDNode>(Op1)->getSExtValue()) &&
1766 !(Op0.getOpcode() == ISD::Constant &&
1767 isInt<16>(cast<ConstantSDNode>(Op0)->getSExtValue())))) {
1768 SDValue CCValid = Node->getOperand(2);
1769 SDValue CCMask = Node->getOperand(3);
1770 uint64_t ConstCCValid = CCValid.getNode()->getAsZExtVal();
1771 uint64_t ConstCCMask = CCMask.getNode()->getAsZExtVal();
1772 // Invert the condition.
1773 CCMask = CurDAG->getTargetConstant(ConstCCValid ^ ConstCCMask,
1774 SDLoc(Node), CCMask.getValueType());
1775 SDValue Op4 = Node->getOperand(4);
1776 SDNode *UpdatedNode =
1777 CurDAG->UpdateNodeOperands(Node, Op1, Op0, CCValid, CCMask, Op4);
1778 if (UpdatedNode != Node) {
1779 // In case this node already exists then replace Node with it.
1780 ReplaceNode(Node, UpdatedNode);
1781 Node = UpdatedNode;
1782 }
1783 }
1784 break;
1785 }
1786
1788 EVT VT = Node->getValueType(0);
1789 unsigned ElemBitSize = VT.getScalarSizeInBits();
1790 if (ElemBitSize == 32) {
1791 if (tryGather(Node, SystemZ::VGEF))
1792 return;
1793 } else if (ElemBitSize == 64) {
1794 if (tryGather(Node, SystemZ::VGEG))
1795 return;
1796 }
1797 break;
1798 }
1799
1800 case ISD::BUILD_VECTOR: {
1801 if (!Subtarget->hasVector())
1802 break;
1803 auto *BVN = cast<BuildVectorSDNode>(Node);
1804 SystemZVectorConstantInfo VCI(BVN);
1805 if (VCI.isVectorConstantLegal(*Subtarget)) {
1806 loadVectorConstant(VCI, Node);
1807 return;
1808 }
1809 break;
1810 }
1811
1812 case ISD::ConstantFP: {
1813 APFloat Imm = cast<ConstantFPSDNode>(Node)->getValueAPF();
1814 if (Imm.isZero() || Imm.isNegZero())
1815 break;
1816 SystemZVectorConstantInfo VCI(Imm);
1817 bool Success = VCI.isVectorConstantLegal(*Subtarget); (void)Success;
1818 assert(Success && "Expected legal FP immediate");
1819 loadVectorConstant(VCI, Node);
1820 return;
1821 }
1822
1823 case ISD::STORE: {
1824 if (tryFoldLoadStoreIntoMemOperand(Node))
1825 return;
1826 auto *Store = cast<StoreSDNode>(Node);
1827 unsigned ElemBitSize = Store->getValue().getValueSizeInBits();
1828 if (ElemBitSize == 32) {
1829 if (tryScatter(Store, SystemZ::VSCEF))
1830 return;
1831 } else if (ElemBitSize == 64) {
1832 if (tryScatter(Store, SystemZ::VSCEG))
1833 return;
1834 }
1835 break;
1836 }
1837
1838 case ISD::ATOMIC_STORE: {
1839 auto *AtomOp = cast<AtomicSDNode>(Node);
1840 // Replace the atomic_store with a regular store and select it. This is
1841 // ok since we know all store instructions <= 8 bytes are atomic, and the
1842 // 16 byte case is already handled during lowering.
1843 StoreSDNode *St = cast<StoreSDNode>(CurDAG->getTruncStore(
1844 AtomOp->getChain(), SDLoc(AtomOp), AtomOp->getVal(),
1845 AtomOp->getBasePtr(), AtomOp->getMemoryVT(), AtomOp->getMemOperand()));
1846 assert(St->getMemOperand()->isAtomic() && "Broken MMO.");
1847 SDNode *Chain = St;
1848 // We have to enforce sequential consistency by performing a
1849 // serialization operation after the store.
1850 if (AtomOp->getSuccessOrdering() == AtomicOrdering::SequentiallyConsistent)
1851 Chain = CurDAG->getMachineNode(SystemZ::Serialize, SDLoc(AtomOp),
1852 MVT::Other, SDValue(Chain, 0));
1853 ReplaceNode(Node, Chain);
1854 SelectCode(St);
1855 return;
1856 }
1857 }
1858
1859 SelectCode(Node);
1860}
1861
1862bool SystemZDAGToDAGISel::SelectInlineAsmMemoryOperand(
1863 const SDValue &Op, InlineAsm::ConstraintCode ConstraintID,
1864 std::vector<SDValue> &OutOps) {
1865 SystemZAddressingMode::AddrForm Form;
1866 SystemZAddressingMode::DispRange DispRange;
1867 SDValue Base, Disp, Index;
1868
1869 switch(ConstraintID) {
1870 default:
1871 llvm_unreachable("Unexpected asm memory constraint");
1872 case InlineAsm::ConstraintCode::i:
1873 case InlineAsm::ConstraintCode::Q:
1874 case InlineAsm::ConstraintCode::ZQ:
1875 // Accept an address with a short displacement, but no index.
1876 Form = SystemZAddressingMode::FormBD;
1877 DispRange = SystemZAddressingMode::Disp12Only;
1878 break;
1879 case InlineAsm::ConstraintCode::R:
1880 case InlineAsm::ConstraintCode::ZR:
1881 // Accept an address with a short displacement and an index.
1882 Form = SystemZAddressingMode::FormBDXNormal;
1883 DispRange = SystemZAddressingMode::Disp12Only;
1884 break;
1885 case InlineAsm::ConstraintCode::S:
1886 case InlineAsm::ConstraintCode::ZS:
1887 // Accept an address with a long displacement, but no index.
1888 Form = SystemZAddressingMode::FormBD;
1889 DispRange = SystemZAddressingMode::Disp20Only;
1890 break;
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:
1896 // Accept an address with a long displacement and an index.
1897 // m works the same as T, as this is the most general case.
1898 // We don't really have any special handling of "offsettable"
1899 // memory addresses, so just treat o the same as m.
1900 Form = SystemZAddressingMode::FormBDXNormal;
1901 DispRange = SystemZAddressingMode::Disp20Only;
1902 break;
1903 }
1904
1905 if (selectBDXAddr(Form, DispRange, Op, Base, Disp, Index)) {
1906 const TargetRegisterClass *TRC =
1908 ConstraintID);
1909 SDLoc DL(Base);
1910 SDValue RC = CurDAG->getTargetConstant(TRC->getID(), DL, MVT::i32);
1911
1912 // Make sure that the base address doesn't go into %r0.
1913 // If it's a TargetFrameIndex or a fixed register, we shouldn't do anything.
1914 if (Base.getOpcode() != ISD::TargetFrameIndex &&
1915 Base.getOpcode() != ISD::Register) {
1916 Base =
1917 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
1918 DL, Base.getValueType(),
1919 Base, RC), 0);
1920 }
1921
1922 // Make sure that the index register isn't assigned to %r0 either.
1923 if (Index.getOpcode() != ISD::Register) {
1924 Index =
1925 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS,
1926 DL, Index.getValueType(),
1927 Index, RC), 0);
1928 }
1929
1930 OutOps.push_back(Base);
1931 OutOps.push_back(Disp);
1932 OutOps.push_back(Index);
1933 return false;
1934 }
1935
1936 return true;
1937}
1938
1939// IsProfitableToFold - Returns true if is profitable to fold the specific
1940// operand node N of U during instruction selection that starts at Root.
1941bool
1942SystemZDAGToDAGISel::IsProfitableToFold(SDValue N, SDNode *U,
1943 SDNode *Root) const {
1944 // We want to avoid folding a LOAD into an ICMP node if as a result
1945 // we would be forced to spill the condition code into a GPR.
1946 if (N.getOpcode() == ISD::LOAD && U->getOpcode() == SystemZISD::ICMP) {
1947 if (!N.hasOneUse() || !U->hasOneUse())
1948 return false;
1949
1950 // The user of the CC value will usually be a CopyToReg into the
1951 // physical CC register, which in turn is glued and chained to the
1952 // actual instruction that uses the CC value. Bail out if we have
1953 // anything else than that.
1954 SDNode *CCUser = *U->user_begin();
1955 SDNode *CCRegUser = nullptr;
1956 if (CCUser->getOpcode() == ISD::CopyToReg ||
1957 cast<RegisterSDNode>(CCUser->getOperand(1))->getReg() == SystemZ::CC) {
1958 for (auto *U : CCUser->users()) {
1959 if (CCRegUser == nullptr)
1960 CCRegUser = U;
1961 else if (CCRegUser != U)
1962 return false;
1963 }
1964 }
1965 if (CCRegUser == nullptr)
1966 return false;
1967
1968 // If the actual instruction is a branch, the only thing that remains to be
1969 // checked is whether the CCUser chain is a predecessor of the load.
1970 if (CCRegUser->isMachineOpcode() &&
1971 CCRegUser->getMachineOpcode() == SystemZ::BRC)
1972 return !N->isPredecessorOf(CCUser->getOperand(0).getNode());
1973
1974 // Otherwise, the instruction may have multiple operands, and we need to
1975 // verify that none of them are a predecessor of the load. This is exactly
1976 // the same check that would be done by common code if the CC setter were
1977 // glued to the CC user, so simply invoke that check here.
1978 if (!IsLegalToFold(N, U, CCRegUser, OptLevel, false))
1979 return false;
1980 }
1981
1982 return true;
1983}
1984
1985namespace {
1986// Represents a sequence for extracting a 0/1 value from an IPM result:
1987// (((X ^ XORValue) + AddValue) >> Bit)
1988struct IPMConversion {
1989 IPMConversion(unsigned xorValue, int64_t addValue, unsigned bit)
1990 : XORValue(xorValue), AddValue(addValue), Bit(bit) {}
1991
1992 int64_t XORValue;
1993 int64_t AddValue;
1994 unsigned Bit;
1995};
1996} // end anonymous namespace
1997
1998// Return a sequence for getting a 1 from an IPM result when CC has a
1999// value in CCMask and a 0 when CC has a value in CCValid & ~CCMask.
2000// The handling of CC values outside CCValid doesn't matter.
2001static IPMConversion getIPMConversion(unsigned CCValid, unsigned CCMask) {
2002 // Deal with cases where the result can be taken directly from a bit
2003 // of the IPM result.
2004 if (CCMask == (CCValid & (SystemZ::CCMASK_1 | SystemZ::CCMASK_3)))
2005 return IPMConversion(0, 0, SystemZ::IPM_CC);
2006 if (CCMask == (CCValid & (SystemZ::CCMASK_2 | SystemZ::CCMASK_3)))
2007 return IPMConversion(0, 0, SystemZ::IPM_CC + 1);
2008
2009 // Deal with cases where we can add a value to force the sign bit
2010 // to contain the right value. Putting the bit in 31 means we can
2011 // use SRL rather than RISBG(L), and also makes it easier to get a
2012 // 0/-1 value, so it has priority over the other tests below.
2013 //
2014 // These sequences rely on the fact that the upper two bits of the
2015 // IPM result are zero.
2016 uint64_t TopBit = uint64_t(1) << 31;
2017 if (CCMask == (CCValid & SystemZ::CCMASK_0))
2018 return IPMConversion(0, -(1 << SystemZ::IPM_CC), 31);
2019 if (CCMask == (CCValid & (SystemZ::CCMASK_0 | SystemZ::CCMASK_1)))
2020 return IPMConversion(0, -(2 << SystemZ::IPM_CC), 31);
2021 if (CCMask == (CCValid & (SystemZ::CCMASK_0
2024 return IPMConversion(0, -(3 << SystemZ::IPM_CC), 31);
2025 if (CCMask == (CCValid & SystemZ::CCMASK_3))
2026 return IPMConversion(0, TopBit - (3 << SystemZ::IPM_CC), 31);
2027 if (CCMask == (CCValid & (SystemZ::CCMASK_1
2030 return IPMConversion(0, TopBit - (1 << SystemZ::IPM_CC), 31);
2031
2032 // Next try inverting the value and testing a bit. 0/1 could be
2033 // handled this way too, but we dealt with that case above.
2034 if (CCMask == (CCValid & (SystemZ::CCMASK_0 | SystemZ::CCMASK_2)))
2035 return IPMConversion(-1, 0, SystemZ::IPM_CC);
2036
2037 // Handle cases where adding a value forces a non-sign bit to contain
2038 // the right value.
2039 if (CCMask == (CCValid & (SystemZ::CCMASK_1 | SystemZ::CCMASK_2)))
2040 return IPMConversion(0, 1 << SystemZ::IPM_CC, SystemZ::IPM_CC + 1);
2041 if (CCMask == (CCValid & (SystemZ::CCMASK_0 | SystemZ::CCMASK_3)))
2042 return IPMConversion(0, -(1 << SystemZ::IPM_CC), SystemZ::IPM_CC + 1);
2043
2044 // The remaining cases are 1, 2, 0/1/3 and 0/2/3. All these are
2045 // can be done by inverting the low CC bit and applying one of the
2046 // sign-based extractions above.
2047 if (CCMask == (CCValid & SystemZ::CCMASK_1))
2048 return IPMConversion(1 << SystemZ::IPM_CC, -(1 << SystemZ::IPM_CC), 31);
2049 if (CCMask == (CCValid & SystemZ::CCMASK_2))
2050 return IPMConversion(1 << SystemZ::IPM_CC,
2051 TopBit - (3 << SystemZ::IPM_CC), 31);
2052 if (CCMask == (CCValid & (SystemZ::CCMASK_0
2055 return IPMConversion(1 << SystemZ::IPM_CC, -(3 << SystemZ::IPM_CC), 31);
2056 if (CCMask == (CCValid & (SystemZ::CCMASK_0
2059 return IPMConversion(1 << SystemZ::IPM_CC,
2060 TopBit - (1 << SystemZ::IPM_CC), 31);
2061
2062 llvm_unreachable("Unexpected CC combination");
2063}
2064
2065SDValue SystemZDAGToDAGISel::expandSelectBoolean(SDNode *Node) {
2066 auto *TrueOp = dyn_cast<ConstantSDNode>(Node->getOperand(0));
2067 auto *FalseOp = dyn_cast<ConstantSDNode>(Node->getOperand(1));
2068 if (!TrueOp || !FalseOp)
2069 return SDValue();
2070 if (FalseOp->getZExtValue() != 0)
2071 return SDValue();
2072 if (TrueOp->getSExtValue() != 1 && TrueOp->getSExtValue() != -1)
2073 return SDValue();
2074
2075 auto *CCValidOp = dyn_cast<ConstantSDNode>(Node->getOperand(2));
2076 auto *CCMaskOp = dyn_cast<ConstantSDNode>(Node->getOperand(3));
2077 if (!CCValidOp || !CCMaskOp)
2078 return SDValue();
2079 int CCValid = CCValidOp->getZExtValue();
2080 int CCMask = CCMaskOp->getZExtValue();
2081
2082 SDLoc DL(Node);
2083 SDValue CCReg = Node->getOperand(4);
2084 IPMConversion IPM = getIPMConversion(CCValid, CCMask);
2085 SDValue Result = CurDAG->getNode(SystemZISD::IPM, DL, MVT::i32, CCReg);
2086
2087 if (IPM.XORValue)
2088 Result = CurDAG->getNode(ISD::XOR, DL, MVT::i32, Result,
2089 CurDAG->getConstant(IPM.XORValue, DL, MVT::i32));
2090
2091 if (IPM.AddValue)
2092 Result =
2093 CurDAG->getNode(ISD::ADD, DL, MVT::i32, Result,
2094 CurDAG->getSignedConstant(IPM.AddValue, DL, MVT::i32));
2095
2096 EVT VT = Node->getValueType(0);
2097 if (VT == MVT::i32 && IPM.Bit == 31) {
2098 unsigned ShiftOp = TrueOp->getSExtValue() == 1 ? ISD::SRL : ISD::SRA;
2099 Result = CurDAG->getNode(ShiftOp, DL, MVT::i32, Result,
2100 CurDAG->getConstant(IPM.Bit, DL, MVT::i32));
2101 } else {
2102 if (VT != MVT::i32)
2103 Result = CurDAG->getNode(ISD::ANY_EXTEND, DL, VT, Result);
2104
2105 if (TrueOp->getSExtValue() == 1) {
2106 // The SHR/AND sequence should get optimized to an RISBG.
2107 Result = CurDAG->getNode(ISD::SRL, DL, VT, Result,
2108 CurDAG->getConstant(IPM.Bit, DL, MVT::i32));
2109 Result = CurDAG->getNode(ISD::AND, DL, VT, Result,
2110 CurDAG->getConstant(1, DL, VT));
2111 } else {
2112 // Sign-extend from IPM.Bit using a pair of shifts.
2113 int ShlAmt = VT.getSizeInBits() - 1 - IPM.Bit;
2114 int SraAmt = VT.getSizeInBits() - 1;
2115 Result = CurDAG->getNode(ISD::SHL, DL, VT, Result,
2116 CurDAG->getConstant(ShlAmt, DL, MVT::i32));
2117 Result = CurDAG->getNode(ISD::SRA, DL, VT, Result,
2118 CurDAG->getConstant(SraAmt, DL, MVT::i32));
2119 }
2120 }
2121
2122 return Result;
2123}
2124
2125bool SystemZDAGToDAGISel::shouldSelectForReassoc(SDNode *N) const {
2126 EVT VT = N->getValueType(0);
2127 assert(VT.isFloatingPoint() && "Expected FP SDNode");
2128 return N->getFlags().hasAllowReassociation() &&
2129 N->getFlags().hasNoSignedZeros() && Subtarget->hasVector() &&
2130 (VT != MVT::f32 || Subtarget->hasVectorEnhancements1()) &&
2131 !N->isStrictFPOpcode();
2132}
2133
2134void SystemZDAGToDAGISel::PreprocessISelDAG() {
2135 // If we have conditional immediate loads, we always prefer
2136 // using those over an IPM sequence.
2137 if (Subtarget->hasLoadStoreOnCond2())
2138 return;
2139
2140 bool MadeChange = false;
2141
2142 for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(),
2143 E = CurDAG->allnodes_end();
2144 I != E;) {
2145 SDNode *N = &*I++;
2146 if (N->use_empty())
2147 continue;
2148
2149 SDValue Res;
2150 switch (N->getOpcode()) {
2151 default: break;
2152 case SystemZISD::SELECT_CCMASK:
2153 Res = expandSelectBoolean(N);
2154 break;
2155 }
2156
2157 if (Res) {
2158 LLVM_DEBUG(dbgs() << "SystemZ DAG preprocessing replacing:\nOld: ");
2159 LLVM_DEBUG(N->dump(CurDAG));
2160 LLVM_DEBUG(dbgs() << "\nNew: ");
2161 LLVM_DEBUG(Res.getNode()->dump(CurDAG));
2162 LLVM_DEBUG(dbgs() << "\n");
2163
2164 CurDAG->ReplaceAllUsesOfValueWith(SDValue(N, 0), Res);
2165 MadeChange = true;
2166 }
2167 }
2168
2169 if (MadeChange)
2170 CurDAG->RemoveDeadNodes();
2171}
#define Success
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
uint64_t uint64_t
uint64_t Imm
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")
#define DEBUG_TYPE
const HexagonInstrInfo * TII
Module.h This file contains the declarations for the Module class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
#define LLVM_DEBUG(...)
Definition Debug.h:119
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)
#define PASS_NAME
The Input class is used to parse a yaml document into in-memory structs and vectors.
Class for arbitrary precision integers.
Definition APInt.h:78
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:312
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
Definition Globals.cpp:205
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.
Definition Value.h:75
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
Definition Value.cpp:986
self_iterator getIterator()
Definition ilist_node.h:123
#define UINT64_MAX
Definition DataTypes.h:77
#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.
Definition ISDOpcodes.h:805
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:266
@ 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.
Definition ISDOpcodes.h:879
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:870
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:787
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
Definition ISDOpcodes.h:581
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
Definition ISDOpcodes.h:226
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:876
@ TargetFrameIndex
Definition ISDOpcodes.h:189
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition ISDOpcodes.h:914
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:757
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
Definition ISDOpcodes.h:570
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition ISDOpcodes.h:55
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:882
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition ISDOpcodes.h:561
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)
const unsigned CCMASK_0
Definition SystemZ.h:29
const unsigned CCMASK_1
Definition SystemZ.h:30
const unsigned IPM_CC
Definition SystemZ.h:114
static bool isImmHF(uint64_t Val)
Definition SystemZ.h:188
const unsigned CCMASK_3
Definition SystemZ.h:32
static bool isImmLF(uint64_t Val)
Definition SystemZ.h:183
const unsigned CCMASK_2
Definition SystemZ.h:31
NodeAddr< NodeBase * > Node
Definition RDFGraph.h:381
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)
@ Offset
Definition DWP.cpp:577
FunctionPass * createSystemZISelDag(SystemZTargetMachine &TM, CodeGenOptLevel OptLevel)
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
@ 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.
Definition Casting.h:643
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
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.
Definition Debug.cpp:209
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
CodeGenOptLevel
Code generation optimization level.
Definition CodeGen.h:280
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...
Definition Casting.h:547
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
Definition InstrProf.h:145
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:320
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
#define N
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:82
Extended Value Type.
Definition ValueTypes.h:35
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
Definition ValueTypes.h:90
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
Definition ValueTypes.h:155
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:396
uint64_t getScalarSizeInBits() const
Definition ValueTypes.h:408
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:339
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Definition ValueTypes.h:359
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition ValueTypes.h:160
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)