LLVM 24.0.0git
SIInstrInfo.cpp
Go to the documentation of this file.
1//===- SIInstrInfo.cpp - SI Instruction Information ----------------------===//
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/// \file
10/// SI Implementation of TargetInstrInfo.
11//
12//===----------------------------------------------------------------------===//
13
14#include "SIInstrInfo.h"
15#include "AMDGPU.h"
16#include "AMDGPUInstrInfo.h"
17#include "AMDGPULaneMaskUtils.h"
18#include "GCNHazardRecognizer.h"
19#include "GCNSubtarget.h"
22#include "llvm/ADT/STLExtras.h"
34#include "llvm/IR/IntrinsicsAMDGPU.h"
35#include "llvm/MC/MCContext.h"
38#include <tuple>
39
40using namespace llvm;
41
42#define DEBUG_TYPE "si-instr-info"
43
44#define GET_INSTRINFO_CTOR_DTOR
45#include "AMDGPUGenInstrInfo.inc"
46
47namespace llvm::AMDGPU {
48#define GET_D16ImageDimIntrinsics_IMPL
49#define GET_ImageDimIntrinsicTable_IMPL
50#define GET_RsrcIntrinsics_IMPL
51#include "AMDGPUGenSearchableTables.inc"
52} // namespace llvm::AMDGPU
53
54// Must be at least 4 to be able to branch over minimum unconditional branch
55// code. This is only for making it possible to write reasonably small tests for
56// long branches.
58BranchOffsetBits("amdgpu-s-branch-bits", cl::ReallyHidden, cl::init(16),
59 cl::desc("Restrict range of branch instructions (DEBUG)"));
60
62 "amdgpu-fix-16-bit-physreg-copies",
63 cl::desc("Fix copies between 32 and 16 bit registers by extending to 32 bit"),
64 cl::init(true),
66
68 : AMDGPUGenInstrInfo(ST, RI, AMDGPU::ADJCALLSTACKUP,
69 AMDGPU::ADJCALLSTACKDOWN),
70 RI(ST), ST(ST) {
71 SchedModel.init(&ST);
72}
73
74//===----------------------------------------------------------------------===//
75// TargetInstrInfo callbacks
76//===----------------------------------------------------------------------===//
77
78static unsigned getNumOperandsNoGlue(SDNode *Node) {
79 unsigned N = Node->getNumOperands();
80 while (N && Node->getOperand(N - 1).getValueType() == MVT::Glue)
81 --N;
82 return N;
83}
84
85/// Returns true if both nodes have the same value for the given
86/// operand \p Op, or if both nodes do not have this operand.
88 AMDGPU::OpName OpName) {
89 unsigned Opc0 = N0->getMachineOpcode();
90 unsigned Opc1 = N1->getMachineOpcode();
91
92 int Op0Idx = AMDGPU::getNamedOperandIdx(Opc0, OpName);
93 int Op1Idx = AMDGPU::getNamedOperandIdx(Opc1, OpName);
94
95 if (Op0Idx == -1 && Op1Idx == -1)
96 return true;
97
98
99 if ((Op0Idx == -1 && Op1Idx != -1) ||
100 (Op1Idx == -1 && Op0Idx != -1))
101 return false;
102
103 // getNamedOperandIdx returns the index for the MachineInstr's operands,
104 // which includes the result as the first operand. We are indexing into the
105 // MachineSDNode's operands, so we need to skip the result operand to get
106 // the real index.
107 --Op0Idx;
108 --Op1Idx;
109
110 return N0->getOperand(Op0Idx) == N1->getOperand(Op1Idx);
111}
112
113static bool canRemat(const MachineInstr &MI) {
114
118 return true;
119
120 if (SIInstrInfo::isSMRD(MI)) {
121 return !MI.memoperands_empty() &&
122 llvm::all_of(MI.memoperands(), [](const MachineMemOperand *MMO) {
123 return MMO->isLoad() && MMO->isInvariant();
124 });
125 }
126
127 return false;
128}
129
130// Split relocation flags for 64-bit global-address materialization into a
131// common base and the hi/lo relocation variants.
132static std::tuple<unsigned, unsigned, unsigned>
134 const MachineOperand &SrcOp) {
135 const unsigned BaseFlags = SrcOp.getTargetFlags() & ~SIInstrInfo::MO_MASK;
136 const unsigned Reloc = SrcOp.getTargetFlags() & SIInstrInfo::MO_MASK;
137
138 // Infer the relocation type from the existing flags on the global operand.
139 // The relocation type should have been determined earlier in the pipeline.
140 unsigned LoReloc, HiReloc;
141 switch (Reloc) {
145 LoReloc = SIInstrInfo::MO_REL32_LO;
146 HiReloc = SIInstrInfo::MO_REL32_HI;
147 break;
152 break;
155 // For 64-bit GOT-relative, use the 64-bit relocation.
158 break;
162 LoReloc = SIInstrInfo::MO_ABS32_LO;
163 HiReloc = SIInstrInfo::MO_ABS32_HI;
164 break;
165 default:
166 llvm_unreachable("unknown relocation type for global address");
167 break;
168 }
169
170 return {BaseFlags, LoReloc, HiReloc};
171}
172
174 const MachineInstr &MI) const {
175
176 if (canRemat(MI)) {
177 // Normally VALU use of exec would block the rematerialization, but that
178 // is OK in this case to have an implicit exec read as all VALU do.
179 // We really want all of the generic logic for this except for this.
180
181 // Another potential implicit use is mode register. The core logic of
182 // the RA will not attempt rematerialization if mode is set anywhere
183 // in the function, otherwise it is safe since mode is not changed.
184
185 // There is difference to generic method which does not allow
186 // rematerialization if there are virtual register uses. We allow this,
187 // therefore this method includes SOP instructions as well.
188 if (!MI.hasImplicitDef() &&
189 MI.getNumImplicitOperands() == MI.getDesc().implicit_uses().size() &&
190 !MI.mayRaiseFPException())
191 return true;
192 }
193
194 // Everything below copied from TargetInstrInfo::isReMaterializableImpl. The
195 // only difference is that we allow operations that perform read-modify-write
196 // on sub-registers.
197
198 // Remat clients assume operand 0 is the defined register.
199 if (!MI.getNumOperands() || !MI.getOperand(0).isReg())
200 return false;
201 Register DefReg = MI.getOperand(0).getReg();
202
203 const MachineFunction &MF = *MI.getMF();
204
205 // A load from a fixed stack slot can be rematerialized. This may be
206 // redundant with subsequent checks, but it's target-independent,
207 // simple, and a common case.
208 int FrameIdx = 0;
209 if (isLoadFromStackSlot(MI, FrameIdx) &&
211 return true;
212
213 // Avoid instructions obviously unsafe for remat.
214 if (MI.isNotDuplicable() || MI.mayStore() || MI.mayRaiseFPException() ||
215 MI.hasUnmodeledSideEffects())
216 return false;
217
218 // Don't remat inline asm. We have no idea how expensive it is
219 // even if it's side effect free.
220 if (MI.isInlineAsm())
221 return false;
222
223 // Avoid instructions which load from potentially varying memory.
224 if (MI.mayLoad() && !MI.isDereferenceableInvariantLoad())
225 return false;
226
227 const MachineRegisterInfo &MRI = MF.getRegInfo();
228
229 // If any of the registers accessed are non-constant, conservatively assume
230 // the instruction is not rematerializable.
231 for (const MachineOperand &MO : MI.operands()) {
232 if (!MO.isReg())
233 continue;
234 Register Reg = MO.getReg();
235 if (Reg == 0)
236 continue;
237
238 // Check for a well-behaved physical register.
239 if (Reg.isPhysical()) {
240 if (MO.isUse()) {
241 // If the physreg has no defs anywhere, it's just an ambient register
242 // and we can freely move its uses. Alternatively, if it's allocatable,
243 // it could get allocated to something with a def during allocation.
244 if (!MRI.isConstantPhysReg(Reg))
245 return false;
246 } else {
247 // A physreg def. We can't remat it.
248 return false;
249 }
250 continue;
251 }
252
253 // Only allow one virtual-register def. There may be multiple defs of the
254 // same virtual register, though.
255 if (MO.isDef() && Reg != DefReg)
256 return false;
257 }
258
259 return true;
260}
261
262// Returns true if the result of a VALU instruction depends on exec.
263bool SIInstrInfo::resultDependsOnExec(const MachineInstr &MI) const {
264 assert(isVALU(MI, /*AllowLDSDMA=*/true));
265
266 // If it is convergent it depends on EXEC.
267 if (MI.isConvergent())
268 return true;
269
270 // If it defines an SGPR it depends on EXEC, unless it's dead.
271 const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
272 for (const MachineOperand &Def : MI.defs()) {
273 if (Def.isDead())
274 continue;
275
276 Register Reg = Def.getReg();
277 if (Reg && RI.isSGPRReg(MRI, Reg))
278 return true;
279 }
280
281 return false;
282}
283
285 // Any implicit use of exec by VALU is not a real register read.
286 return MO.getReg() == AMDGPU::EXEC && MO.isImplicit() &&
287 isVALU(*MO.getParent(), /*AllowLDSDMA=*/true) &&
288 !resultDependsOnExec(*MO.getParent());
289}
290
292 MachineBasicBlock *SuccToSinkTo,
293 MachineCycleInfo *CI) const {
294 // Allow sinking if MI edits lane mask (divergent i1 in sgpr).
295 if (MI.getOpcode() == AMDGPU::SI_IF_BREAK)
296 return true;
297
298 MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
299 // Check if sinking of MI would create temporal divergent use.
300 for (auto Op : MI.uses()) {
301 if (Op.isReg() && Op.getReg().isVirtual() &&
302 RI.isSGPRClass(MRI.getRegClass(Op.getReg()))) {
303 MachineInstr *SgprDef = MRI.getVRegDef(Op.getReg());
304 if (!SgprDef)
305 continue;
306
307 // SgprDef defined inside cycle
308 CycleRef FromCycle = CI->getCycle(SgprDef->getParent());
309 if (!FromCycle)
310 continue;
311
312 CycleRef ToCycle = CI->getCycle(SuccToSinkTo);
313 // Check if there is a FromCycle that contains SgprDef's basic block but
314 // does not contain SuccToSinkTo and also has divergent exit condition.
315 while (FromCycle && !(ToCycle && CI->contains(FromCycle, ToCycle))) {
317 CI->getExitingBlocks(FromCycle, ExitingBlocks);
318
319 // FromCycle has divergent exit condition.
320 for (MachineBasicBlock *ExitingBlock : ExitingBlocks) {
321 if (hasDivergentBranch(ExitingBlock))
322 return false;
323 }
324
325 FromCycle = CI->getParentCycle(FromCycle);
326 }
327 }
328 }
329
330 return true;
331}
332
334 int64_t &Offset0,
335 int64_t &Offset1) const {
336 if (!Load0->isMachineOpcode() || !Load1->isMachineOpcode())
337 return false;
338
339 unsigned Opc0 = Load0->getMachineOpcode();
340 unsigned Opc1 = Load1->getMachineOpcode();
341
342 // Make sure both are actually loads.
343 if (!get(Opc0).mayLoad() || !get(Opc1).mayLoad())
344 return false;
345
346 // A mayLoad instruction without a def is not a load. Likely a prefetch.
347 if (!get(Opc0).getNumDefs() || !get(Opc1).getNumDefs())
348 return false;
349
350 if (isDS(Opc0) && isDS(Opc1)) {
351
352 // FIXME: Handle this case:
353 if (getNumOperandsNoGlue(Load0) != getNumOperandsNoGlue(Load1))
354 return false;
355
356 // Check base reg.
357 if (Load0->getOperand(0) != Load1->getOperand(0))
358 return false;
359
360 // Skip read2 / write2 variants for simplicity.
361 // TODO: We should report true if the used offsets are adjacent (excluded
362 // st64 versions).
363 int Offset0Idx = AMDGPU::getNamedOperandIdx(Opc0, AMDGPU::OpName::offset);
364 int Offset1Idx = AMDGPU::getNamedOperandIdx(Opc1, AMDGPU::OpName::offset);
365 if (Offset0Idx == -1 || Offset1Idx == -1)
366 return false;
367
368 // XXX - be careful of dataless loads
369 // getNamedOperandIdx returns the index for MachineInstrs. Since they
370 // include the output in the operand list, but SDNodes don't, we need to
371 // subtract the index by one.
372 Offset0Idx -= get(Opc0).NumDefs;
373 Offset1Idx -= get(Opc1).NumDefs;
374 Offset0 = Load0->getConstantOperandVal(Offset0Idx);
375 Offset1 = Load1->getConstantOperandVal(Offset1Idx);
376 return true;
377 }
378
379 if (isSMRD(Opc0) && isSMRD(Opc1)) {
380 // Skip time and cache invalidation instructions.
381 if (!AMDGPU::hasNamedOperand(Opc0, AMDGPU::OpName::sbase) ||
382 !AMDGPU::hasNamedOperand(Opc1, AMDGPU::OpName::sbase))
383 return false;
384
385 unsigned NumOps = getNumOperandsNoGlue(Load0);
386 if (NumOps != getNumOperandsNoGlue(Load1))
387 return false;
388
389 // Check base reg.
390 if (Load0->getOperand(0) != Load1->getOperand(0))
391 return false;
392
393 // Match register offsets, if both register and immediate offsets present.
394 assert(NumOps == 4 || NumOps == 5);
395 if (NumOps == 5 && Load0->getOperand(1) != Load1->getOperand(1))
396 return false;
397
398 const ConstantSDNode *Load0Offset =
400 const ConstantSDNode *Load1Offset =
402
403 if (!Load0Offset || !Load1Offset)
404 return false;
405
406 Offset0 = Load0Offset->getZExtValue();
407 Offset1 = Load1Offset->getZExtValue();
408 return true;
409 }
410
411 // MUBUF and MTBUF can access the same addresses.
412 if ((isMUBUF(Opc0) || isMTBUF(Opc0)) && (isMUBUF(Opc1) || isMTBUF(Opc1))) {
413
414 // MUBUF and MTBUF have vaddr at different indices.
415 if (!nodesHaveSameOperandValue(Load0, Load1, AMDGPU::OpName::soffset) ||
416 !nodesHaveSameOperandValue(Load0, Load1, AMDGPU::OpName::vaddr) ||
417 !nodesHaveSameOperandValue(Load0, Load1, AMDGPU::OpName::srsrc))
418 return false;
419
420 int OffIdx0 = AMDGPU::getNamedOperandIdx(Opc0, AMDGPU::OpName::offset);
421 int OffIdx1 = AMDGPU::getNamedOperandIdx(Opc1, AMDGPU::OpName::offset);
422
423 if (OffIdx0 == -1 || OffIdx1 == -1)
424 return false;
425
426 // getNamedOperandIdx returns the index for MachineInstrs. Since they
427 // include the output in the operand list, but SDNodes don't, we need to
428 // subtract the index by one.
429 OffIdx0 -= get(Opc0).NumDefs;
430 OffIdx1 -= get(Opc1).NumDefs;
431
432 SDValue Off0 = Load0->getOperand(OffIdx0);
433 SDValue Off1 = Load1->getOperand(OffIdx1);
434
435 // The offset might be a FrameIndexSDNode.
436 if (!isa<ConstantSDNode>(Off0) || !isa<ConstantSDNode>(Off1))
437 return false;
438
439 Offset0 = Off0->getAsZExtVal();
440 Offset1 = Off1->getAsZExtVal();
441 return true;
442 }
443
444 return false;
445}
446
447static bool isStride64(unsigned Opc) {
448 switch (Opc) {
449 case AMDGPU::DS_READ2ST64_B32:
450 case AMDGPU::DS_READ2ST64_B64:
451 case AMDGPU::DS_WRITE2ST64_B32:
452 case AMDGPU::DS_WRITE2ST64_B64:
453 return true;
454 default:
455 return false;
456 }
457}
458
461 int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width,
462 const TargetRegisterInfo *TRI) const {
463 if (!LdSt.mayLoadOrStore())
464 return false;
465
466 unsigned Opc = LdSt.getOpcode();
467 OffsetIsScalable = false;
468 const MachineOperand *BaseOp, *OffsetOp;
469 int DataOpIdx;
470
471 if (isDS(LdSt)) {
472 BaseOp = getNamedOperand(LdSt, AMDGPU::OpName::addr);
473 OffsetOp = getNamedOperand(LdSt, AMDGPU::OpName::offset);
474 if (OffsetOp) {
475 // Normal, single offset LDS instruction.
476 if (!BaseOp) {
477 // DS_CONSUME/DS_APPEND use M0 for the base address.
478 // TODO: find the implicit use operand for M0 and use that as BaseOp?
479 return false;
480 }
481 BaseOps.push_back(BaseOp);
482 Offset = OffsetOp->getImm();
483 // Get appropriate operand, and compute width accordingly.
484 DataOpIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::vdst);
485 if (DataOpIdx == -1)
486 DataOpIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::data0);
487 if (Opc == AMDGPU::DS_ATOMIC_ASYNC_BARRIER_ARRIVE_B64)
488 Width = LocationSize::precise(64);
489 else
490 Width = LocationSize::precise(getOpSize(LdSt, DataOpIdx));
491 } else {
492 // The 2 offset instructions use offset0 and offset1 instead. We can treat
493 // these as a load with a single offset if the 2 offsets are consecutive.
494 // We will use this for some partially aligned loads.
495 const MachineOperand *Offset0Op =
496 getNamedOperand(LdSt, AMDGPU::OpName::offset0);
497 const MachineOperand *Offset1Op =
498 getNamedOperand(LdSt, AMDGPU::OpName::offset1);
499
500 unsigned Offset0 = Offset0Op->getImm() & 0xff;
501 unsigned Offset1 = Offset1Op->getImm() & 0xff;
502 if (Offset0 + 1 != Offset1)
503 return false;
504
505 // Each of these offsets is in element sized units, so we need to convert
506 // to bytes of the individual reads.
507
508 unsigned EltSize;
509 if (LdSt.mayLoad())
510 EltSize = TRI->getRegSizeInBits(*getOpRegClass(LdSt, 0)) / 16;
511 else {
512 assert(LdSt.mayStore());
513 int Data0Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::data0);
514 EltSize = TRI->getRegSizeInBits(*getOpRegClass(LdSt, Data0Idx)) / 8;
515 }
516
517 if (isStride64(Opc))
518 EltSize *= 64;
519
520 BaseOps.push_back(BaseOp);
521 Offset = EltSize * Offset0;
522 // Get appropriate operand(s), and compute width accordingly.
523 DataOpIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::vdst);
524 if (DataOpIdx == -1) {
525 DataOpIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::data0);
526 Width = LocationSize::precise(getOpSize(LdSt, DataOpIdx));
527 DataOpIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::data1);
528 Width = LocationSize::precise(
529 Width.getValue() + TypeSize::getFixed(getOpSize(LdSt, DataOpIdx)));
530 } else {
531 Width = LocationSize::precise(getOpSize(LdSt, DataOpIdx));
532 }
533 }
534 return true;
535 }
536
537 if (isMUBUF(LdSt) || isMTBUF(LdSt)) {
538 const MachineOperand *RSrc = getNamedOperand(LdSt, AMDGPU::OpName::srsrc);
539 if (!RSrc) // e.g. BUFFER_WBINVL1_VOL
540 return false;
541 BaseOps.push_back(RSrc);
542 BaseOp = getNamedOperand(LdSt, AMDGPU::OpName::vaddr);
543 if (BaseOp && !BaseOp->isFI())
544 BaseOps.push_back(BaseOp);
545 const MachineOperand *OffsetImm =
546 getNamedOperand(LdSt, AMDGPU::OpName::offset);
547 Offset = OffsetImm->getImm();
548 const MachineOperand *SOffset =
549 getNamedOperand(LdSt, AMDGPU::OpName::soffset);
550 if (SOffset) {
551 if (SOffset->isReg())
552 BaseOps.push_back(SOffset);
553 else
554 Offset += SOffset->getImm();
555 }
556 // Get appropriate operand, and compute width accordingly.
557 DataOpIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::vdst);
558 if (DataOpIdx == -1)
559 DataOpIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::vdata);
560 if (DataOpIdx == -1) // LDS DMA
561 return false;
562 Width = LocationSize::precise(getOpSize(LdSt, DataOpIdx));
563 return true;
564 }
565
566 if (isImage(LdSt)) {
567 auto RsrcOpName =
568 isMIMG(LdSt) ? AMDGPU::OpName::srsrc : AMDGPU::OpName::rsrc;
569 int SRsrcIdx = AMDGPU::getNamedOperandIdx(Opc, RsrcOpName);
570 BaseOps.push_back(&LdSt.getOperand(SRsrcIdx));
571 int VAddr0Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::vaddr0);
572 if (VAddr0Idx >= 0) {
573 // GFX10 possible NSA encoding.
574 for (int I = VAddr0Idx; I < SRsrcIdx; ++I)
575 BaseOps.push_back(&LdSt.getOperand(I));
576 } else {
577 BaseOps.push_back(getNamedOperand(LdSt, AMDGPU::OpName::vaddr));
578 }
579 Offset = 0;
580 // Get appropriate operand, and compute width accordingly.
581 DataOpIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::vdata);
582 if (DataOpIdx == -1)
583 return false; // no return sampler
584 Width = LocationSize::precise(getOpSize(LdSt, DataOpIdx));
585 return true;
586 }
587
588 if (isSMRD(LdSt)) {
589 BaseOp = getNamedOperand(LdSt, AMDGPU::OpName::sbase);
590 if (!BaseOp) // e.g. S_MEMTIME
591 return false;
592 BaseOps.push_back(BaseOp);
593 OffsetOp = getNamedOperand(LdSt, AMDGPU::OpName::offset);
594 Offset = OffsetOp ? OffsetOp->getImm() : 0;
595 // Get appropriate operand, and compute width accordingly.
596 DataOpIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::sdst);
597 if (DataOpIdx == -1)
598 return false;
599 Width = LocationSize::precise(getOpSize(LdSt, DataOpIdx));
600 return true;
601 }
602
603 if (isFLAT(LdSt)) {
604 // Instructions have either vaddr or saddr or both or none.
605 BaseOp = getNamedOperand(LdSt, AMDGPU::OpName::vaddr);
606 if (BaseOp)
607 BaseOps.push_back(BaseOp);
608 BaseOp = getNamedOperand(LdSt, AMDGPU::OpName::saddr);
609 if (BaseOp)
610 BaseOps.push_back(BaseOp);
611 Offset = getNamedOperand(LdSt, AMDGPU::OpName::offset)->getImm();
612 // Get appropriate operand, and compute width accordingly.
613 DataOpIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::vdst);
614 if (DataOpIdx == -1)
615 DataOpIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::vdata);
616 if (DataOpIdx == -1) // LDS DMA
617 return false;
618 Width = LocationSize::precise(getOpSize(LdSt, DataOpIdx));
619 return true;
620 }
621
622 return false;
623}
624
625static bool memOpsHaveSameBasePtr(const MachineInstr &MI1,
627 const MachineInstr &MI2,
629 // Only examine the first "base" operand of each instruction, on the
630 // assumption that it represents the real base address of the memory access.
631 // Other operands are typically offsets or indices from this base address.
632 if (BaseOps1.front()->isIdenticalTo(*BaseOps2.front()))
633 return true;
634
635 if (!MI1.hasOneMemOperand() || !MI2.hasOneMemOperand())
636 return false;
637
638 auto *MO1 = *MI1.memoperands_begin();
639 auto *MO2 = *MI2.memoperands_begin();
640 if (MO1->getAddrSpace() != MO2->getAddrSpace())
641 return false;
642
643 const auto *Base1 = MO1->getValue();
644 const auto *Base2 = MO2->getValue();
645 if (!Base1 || !Base2)
646 return false;
647 Base1 = getUnderlyingObject(Base1);
648 Base2 = getUnderlyingObject(Base2);
649
650 if (isa<UndefValue>(Base1) || isa<UndefValue>(Base2))
651 return false;
652
653 return Base1 == Base2;
654}
655
657 int64_t Offset1, bool OffsetIsScalable1,
659 int64_t Offset2, bool OffsetIsScalable2,
660 unsigned ClusterSize,
661 unsigned NumBytes) const {
662 // If the mem ops (to be clustered) do not have the same base ptr, then they
663 // should not be clustered
664 unsigned MaxMemoryClusterDWords = DefaultMemoryClusterDWordsLimit;
665 if (!BaseOps1.empty() && !BaseOps2.empty()) {
666 const MachineInstr &FirstLdSt = *BaseOps1.front()->getParent();
667 const MachineInstr &SecondLdSt = *BaseOps2.front()->getParent();
668 if (!memOpsHaveSameBasePtr(FirstLdSt, BaseOps1, SecondLdSt, BaseOps2))
669 return false;
670
671 const SIMachineFunctionInfo *MFI =
672 FirstLdSt.getMF()->getInfo<SIMachineFunctionInfo>();
673 MaxMemoryClusterDWords = MFI->getMaxMemoryClusterDWords();
674 } else if (!BaseOps1.empty() || !BaseOps2.empty()) {
675 // If only one base op is empty, they do not have the same base ptr
676 return false;
677 }
678
679 // In order to avoid register pressure, on an average, the number of DWORDS
680 // loaded together by all clustered mem ops should not exceed
681 // MaxMemoryClusterDWords. This is an empirical value based on certain
682 // observations and performance related experiments.
683 // The good thing about this heuristic is - it avoids clustering of too many
684 // sub-word loads, and also avoids clustering of wide loads. Below is the
685 // brief summary of how the heuristic behaves for various `LoadSize` when
686 // MaxMemoryClusterDWords is 8.
687 //
688 // (1) 1 <= LoadSize <= 4: cluster at max 8 mem ops
689 // (2) 5 <= LoadSize <= 8: cluster at max 4 mem ops
690 // (3) 9 <= LoadSize <= 12: cluster at max 2 mem ops
691 // (4) 13 <= LoadSize <= 16: cluster at max 2 mem ops
692 // (5) LoadSize >= 17: do not cluster
693 const unsigned LoadSize = NumBytes / ClusterSize;
694 const unsigned NumDWords = ((LoadSize + 3) / 4) * ClusterSize;
695 return NumDWords <= MaxMemoryClusterDWords;
696}
697
698// FIXME: This behaves strangely. If, for example, you have 32 load + stores,
699// the first 16 loads will be interleaved with the stores, and the next 16 will
700// be clustered as expected. It should really split into 2 16 store batches.
701//
702// Loads are clustered until this returns false, rather than trying to schedule
703// groups of stores. This also means we have to deal with saying different
704// address space loads should be clustered, and ones which might cause bank
705// conflicts.
706//
707// This might be deprecated so it might not be worth that much effort to fix.
709 int64_t Offset0, int64_t Offset1,
710 unsigned NumLoads) const {
711 assert(Offset1 > Offset0 &&
712 "Second offset should be larger than first offset!");
713 // If we have less than 16 loads in a row, and the offsets are within 64
714 // bytes, then schedule together.
715
716 // A cacheline is 64 bytes (for global memory).
717 return (NumLoads <= 16 && (Offset1 - Offset0) < 64);
718}
719
722 const DebugLoc &DL, MCRegister DestReg,
723 MCRegister SrcReg, bool KillSrc,
724 const char *Msg = "illegal VGPR to SGPR copy") {
725 MachineFunction *MF = MBB.getParent();
726
729
730 BuildMI(MBB, MI, DL, TII->get(AMDGPU::SI_ILLEGAL_COPY), DestReg)
731 .addReg(SrcReg, getKillRegState(KillSrc));
732}
733
734/// Handle copying from SGPR to AGPR, or from AGPR to AGPR on GFX908. It is not
735/// possible to have a direct copy in these cases on GFX908, so an intermediate
736/// VGPR copy is required.
739 const DebugLoc &DL, MCRegister DestReg,
740 MCRegister SrcReg, bool KillSrc,
741 RegScavenger &RS, bool RegsOverlap,
742 Register ImpUseSuperReg = Register()) {
743 assert((TII.getSubtarget().hasMAIInsts() &&
744 !TII.getSubtarget().hasGFX90AInsts()) &&
745 "Expected GFX908 subtarget.");
746
747 assert((AMDGPU::SReg_32RegClass.contains(SrcReg) ||
748 AMDGPU::AGPR_32RegClass.contains(SrcReg)) &&
749 "Source register of the copy should be either an SGPR or an AGPR.");
750
751 assert(AMDGPU::AGPR_32RegClass.contains(DestReg) &&
752 "Destination register of the copy should be an AGPR.");
753
754 const SIRegisterInfo &RI = TII.getRegisterInfo();
755
756 // First try to find defining accvgpr_write to avoid temporary registers.
757 // In the case of copies of overlapping AGPRs, we conservatively do not
758 // reuse previous accvgpr_writes. Otherwise, we may incorrectly pick up
759 // an accvgpr_write used for this same copy due to implicit-defs
760 if (!RegsOverlap) {
761 for (auto Def = MI, E = MBB.begin(); Def != E; ) {
762 --Def;
763
764 if (!Def->modifiesRegister(SrcReg, &RI))
765 continue;
766
767 if (Def->getOpcode() != AMDGPU::V_ACCVGPR_WRITE_B32_e64 ||
768 Def->getOperand(0).getReg() != SrcReg)
769 break;
770
771 MachineOperand &DefOp = Def->getOperand(1);
772 assert(DefOp.isReg() || DefOp.isImm());
773
774 if (DefOp.isReg()) {
775 bool SafeToPropagate = true;
776 // Check that register source operand is not clobbered before MI.
777 // Immediate operands are always safe to propagate.
778 for (auto I = Def; I != MI && SafeToPropagate; ++I)
779 if (I->modifiesRegister(DefOp.getReg(), &RI))
780 SafeToPropagate = false;
781
782 if (!SafeToPropagate)
783 break;
784
785 for (auto I = Def; I != MI; ++I)
786 I->clearRegisterKills(DefOp.getReg(), &RI);
787 }
788
789 MachineInstrBuilder Builder =
790 BuildMI(MBB, MI, DL, TII.get(AMDGPU::V_ACCVGPR_WRITE_B32_e64),
791 DestReg)
792 .add(DefOp);
793
794 if (ImpUseSuperReg) {
795 Builder.addReg(ImpUseSuperReg,
797 }
798
799 return;
800 }
801 }
802
803 RS.enterBasicBlockEnd(MBB);
804 RS.backward(std::next(MI));
805
806 // Ideally we want to have three registers for a long reg_sequence copy
807 // to hide 2 waitstates between v_mov_b32 and accvgpr_write.
808 unsigned MaxVGPRs = RI.getRegPressureLimit(&AMDGPU::VGPR_32RegClass,
809 *MBB.getParent());
810
811 // Registers in the sequence are allocated contiguously so we can just
812 // use register number to pick one of three round-robin temps.
813 unsigned RegNo = (DestReg - AMDGPU::AGPR0) % 3;
814 Register Tmp =
815 MBB.getParent()->getInfo<SIMachineFunctionInfo>()->getVGPRForAGPRCopy();
816 assert(MBB.getParent()->getRegInfo().isReserved(Tmp) &&
817 "VGPR used for an intermediate copy should have been reserved.");
818
819 // Only loop through if there are any free registers left. We don't want to
820 // spill.
821 while (RegNo--) {
822 Register Tmp2 = RS.scavengeRegisterBackwards(AMDGPU::VGPR_32RegClass, MI,
823 /* RestoreAfter */ false, 0,
824 /* AllowSpill */ false);
825 if (!Tmp2 || RI.getHWRegIndex(Tmp2) >= MaxVGPRs)
826 break;
827 Tmp = Tmp2;
828 RS.setRegUsed(Tmp);
829 }
830
831 // Insert copy to temporary VGPR.
832 unsigned TmpCopyOp = AMDGPU::V_MOV_B32_e32;
833 if (AMDGPU::AGPR_32RegClass.contains(SrcReg)) {
834 TmpCopyOp = AMDGPU::V_ACCVGPR_READ_B32_e64;
835 } else {
836 assert(AMDGPU::SReg_32RegClass.contains(SrcReg));
837 }
838
839 MachineInstrBuilder UseBuilder = BuildMI(MBB, MI, DL, TII.get(TmpCopyOp), Tmp)
840 .addReg(SrcReg, getKillRegState(KillSrc));
841 if (ImpUseSuperReg) {
842 UseBuilder.addReg(ImpUseSuperReg,
844 }
845
846 BuildMI(MBB, MI, DL, TII.get(AMDGPU::V_ACCVGPR_WRITE_B32_e64), DestReg)
847 .addReg(Tmp, RegState::Kill);
848}
849
852 MCRegister DestReg, MCRegister SrcReg, bool KillSrc,
853 const TargetRegisterClass *RC, bool Forward) {
854 const SIRegisterInfo &RI = TII.getRegisterInfo();
855 ArrayRef<int16_t> BaseIndices = RI.getRegSplitParts(RC, 4);
857 MachineInstr *FirstMI = nullptr, *LastMI = nullptr;
858
859 for (unsigned Idx = 0; Idx < BaseIndices.size(); ++Idx) {
860 int16_t SubIdx = BaseIndices[Idx];
861 Register DestSubReg = RI.getSubReg(DestReg, SubIdx);
862 Register SrcSubReg = RI.getSubReg(SrcReg, SubIdx);
863 assert(DestSubReg && SrcSubReg && "Failed to find subregs!");
864 unsigned Opcode = AMDGPU::S_MOV_B32;
865
866 // Is SGPR aligned? If so try to combine with next.
867 bool AlignedDest = ((DestSubReg - AMDGPU::SGPR0) % 2) == 0;
868 bool AlignedSrc = ((SrcSubReg - AMDGPU::SGPR0) % 2) == 0;
869 if (AlignedDest && AlignedSrc && (Idx + 1 < BaseIndices.size())) {
870 // Can use SGPR64 copy
871 unsigned Channel = RI.getChannelFromSubReg(SubIdx);
872 SubIdx = RI.getSubRegFromChannel(Channel, 2);
873 DestSubReg = RI.getSubReg(DestReg, SubIdx);
874 SrcSubReg = RI.getSubReg(SrcReg, SubIdx);
875 assert(DestSubReg && SrcSubReg && "Failed to find subregs!");
876 Opcode = AMDGPU::S_MOV_B64;
877 Idx++;
878 }
879
880 LastMI = BuildMI(MBB, I, DL, TII.get(Opcode), DestSubReg)
881 .addReg(SrcSubReg)
882 .addReg(SrcReg, RegState::Implicit);
883
884 if (!FirstMI)
885 FirstMI = LastMI;
886
887 if (!Forward)
888 I--;
889 }
890
891 assert(FirstMI && LastMI);
892 if (!Forward)
893 std::swap(FirstMI, LastMI);
894
895 if (KillSrc)
896 LastMI->addRegisterKilled(SrcReg, &RI);
897}
898
901 const DebugLoc &DL, Register DestReg,
902 Register SrcReg, bool KillSrc, bool RenamableDest,
903 bool RenamableSrc) const {
904 const TargetRegisterClass *RC = RI.getPhysRegBaseClass(DestReg);
905 unsigned Size = RI.getRegSizeInBits(*RC);
906 const TargetRegisterClass *SrcRC = RI.getPhysRegBaseClass(SrcReg);
907 unsigned SrcSize = RI.getRegSizeInBits(*SrcRC);
908
909 // The rest of copyPhysReg assumes Src and Dst size are the same size.
910 // TODO-GFX11_16BIT If all true 16 bit instruction patterns are completed can
911 // we remove Fix16BitCopies and this code block?
912 if (Fix16BitCopies) {
913 if (((Size == 16) != (SrcSize == 16))) {
914 // Non-VGPR Src and Dst will later be expanded back to 32 bits.
915 assert(ST.useRealTrue16Insts());
916 Register &RegToFix = (Size == 32) ? DestReg : SrcReg;
917 MCRegister SubReg = RI.getSubReg(RegToFix, AMDGPU::lo16);
918 RegToFix = SubReg;
919
920 if (DestReg == SrcReg) {
921 // Identity copy. Insert empty bundle since ExpandPostRA expects an
922 // instruction here.
923 BuildMI(MBB, MI, DL, get(AMDGPU::BUNDLE));
924 return;
925 }
926 RC = RI.getPhysRegBaseClass(DestReg);
927 Size = RI.getRegSizeInBits(*RC);
928 SrcRC = RI.getPhysRegBaseClass(SrcReg);
929 SrcSize = RI.getRegSizeInBits(*SrcRC);
930 }
931 }
932
933 if (RC == &AMDGPU::VGPR_32RegClass) {
934 assert(AMDGPU::VGPR_32RegClass.contains(SrcReg) ||
935 AMDGPU::SReg_32RegClass.contains(SrcReg) ||
936 AMDGPU::AGPR_32RegClass.contains(SrcReg));
937 unsigned Opc = AMDGPU::AGPR_32RegClass.contains(SrcReg) ?
938 AMDGPU::V_ACCVGPR_READ_B32_e64 : AMDGPU::V_MOV_B32_e32;
939 BuildMI(MBB, MI, DL, get(Opc), DestReg)
940 .addReg(SrcReg, getKillRegState(KillSrc));
941 return;
942 }
943
944 if (RC == &AMDGPU::SReg_32_XM0RegClass ||
945 RC == &AMDGPU::SReg_32RegClass) {
946 if (SrcReg == AMDGPU::SCC) {
947 BuildMI(MBB, MI, DL, get(AMDGPU::S_CSELECT_B32), DestReg)
948 .addImm(1)
949 .addImm(0);
950 return;
951 }
952
953 if (!AMDGPU::SReg_32RegClass.contains(SrcReg)) {
954 if (DestReg == AMDGPU::VCC_LO) {
955 // FIXME: Hack until VReg_1 removed.
956 assert(AMDGPU::VGPR_32RegClass.contains(SrcReg));
957 BuildMI(MBB, MI, DL, get(AMDGPU::V_CMP_NE_U32_e32))
958 .addImm(0)
959 .addReg(SrcReg, getKillRegState(KillSrc));
960 return;
961 }
962
963 reportIllegalCopy(this, MBB, MI, DL, DestReg, SrcReg, KillSrc);
964 return;
965 }
966
967 BuildMI(MBB, MI, DL, get(AMDGPU::S_MOV_B32), DestReg)
968 .addReg(SrcReg, getKillRegState(KillSrc));
969 return;
970 }
971
972 if (RC == &AMDGPU::SReg_64RegClass) {
973 if (SrcReg == AMDGPU::SCC) {
974 BuildMI(MBB, MI, DL, get(AMDGPU::S_CSELECT_B64), DestReg)
975 .addImm(1)
976 .addImm(0);
977 return;
978 }
979
980 if (!AMDGPU::SReg_64_EncodableRegClass.contains(SrcReg)) {
981 if (DestReg == AMDGPU::VCC) {
982 // FIXME: Hack until VReg_1 removed.
983 assert(AMDGPU::VGPR_32RegClass.contains(SrcReg));
984 BuildMI(MBB, MI, DL, get(AMDGPU::V_CMP_NE_U32_e32))
985 .addImm(0)
986 .addReg(SrcReg, getKillRegState(KillSrc));
987 return;
988 }
989
990 reportIllegalCopy(this, MBB, MI, DL, DestReg, SrcReg, KillSrc);
991 return;
992 }
993
994 BuildMI(MBB, MI, DL, get(AMDGPU::S_MOV_B64), DestReg)
995 .addReg(SrcReg, getKillRegState(KillSrc));
996 return;
997 }
998
999 if (DestReg == AMDGPU::SCC) {
1000 // Copying 64-bit or 32-bit sources to SCC barely makes sense,
1001 // but SelectionDAG emits such copies for i1 sources.
1002 if (AMDGPU::SReg_64RegClass.contains(SrcReg)) {
1003 // This copy can only be produced by patterns
1004 // with explicit SCC, which are known to be enabled
1005 // only for subtargets with S_CMP_LG_U64 present.
1006 assert(ST.hasScalarCompareEq64());
1007 BuildMI(MBB, MI, DL, get(AMDGPU::S_CMP_LG_U64))
1008 .addReg(SrcReg, getKillRegState(KillSrc))
1009 .addImm(0);
1010 } else {
1011 assert(AMDGPU::SReg_32RegClass.contains(SrcReg));
1012 BuildMI(MBB, MI, DL, get(AMDGPU::S_CMP_LG_U32))
1013 .addReg(SrcReg, getKillRegState(KillSrc))
1014 .addImm(0);
1015 }
1016
1017 return;
1018 }
1019
1020 if (RC == &AMDGPU::AGPR_32RegClass) {
1021 if (AMDGPU::VGPR_32RegClass.contains(SrcReg) ||
1022 (ST.hasGFX90AInsts() && AMDGPU::SReg_32RegClass.contains(SrcReg))) {
1023 BuildMI(MBB, MI, DL, get(AMDGPU::V_ACCVGPR_WRITE_B32_e64), DestReg)
1024 .addReg(SrcReg, getKillRegState(KillSrc));
1025 return;
1026 }
1027
1028 if (AMDGPU::AGPR_32RegClass.contains(SrcReg) && ST.hasGFX90AInsts()) {
1029 BuildMI(MBB, MI, DL, get(AMDGPU::V_ACCVGPR_MOV_B32), DestReg)
1030 .addReg(SrcReg, getKillRegState(KillSrc));
1031 return;
1032 }
1033
1034 // FIXME: Pass should maintain scavenger to avoid scan through the block on
1035 // every AGPR spill.
1036 RegScavenger RS;
1037 const bool Overlap = RI.regsOverlap(SrcReg, DestReg);
1038 indirectCopyToAGPR(*this, MBB, MI, DL, DestReg, SrcReg, KillSrc, RS, Overlap);
1039 return;
1040 }
1041
1042 if (Size == 16) {
1043 assert(AMDGPU::VGPR_16RegClass.contains(SrcReg) ||
1044 AMDGPU::SReg_LO16RegClass.contains(SrcReg) ||
1045 AMDGPU::AGPR_LO16RegClass.contains(SrcReg));
1046
1047 bool IsSGPRDst = AMDGPU::SReg_LO16RegClass.contains(DestReg);
1048 bool IsSGPRSrc = AMDGPU::SReg_LO16RegClass.contains(SrcReg);
1049 bool IsAGPRDst = AMDGPU::AGPR_LO16RegClass.contains(DestReg);
1050 bool IsAGPRSrc = AMDGPU::AGPR_LO16RegClass.contains(SrcReg);
1051 bool DstLow = !AMDGPU::isHi16Reg(DestReg, RI);
1052 bool SrcLow = !AMDGPU::isHi16Reg(SrcReg, RI);
1053 MCRegister NewDestReg = RI.get32BitRegister(DestReg);
1054 MCRegister NewSrcReg = RI.get32BitRegister(SrcReg);
1055
1056 if (IsSGPRDst) {
1057 if (!IsSGPRSrc) {
1058 reportIllegalCopy(this, MBB, MI, DL, DestReg, SrcReg, KillSrc);
1059 return;
1060 }
1061
1062 BuildMI(MBB, MI, DL, get(AMDGPU::S_MOV_B32), NewDestReg)
1063 .addReg(NewSrcReg, getKillRegState(KillSrc));
1064 return;
1065 }
1066
1067 if (IsAGPRDst || IsAGPRSrc) {
1068 if (!DstLow || !SrcLow) {
1069 reportIllegalCopy(this, MBB, MI, DL, DestReg, SrcReg, KillSrc,
1070 "Cannot use hi16 subreg with an AGPR!");
1071 }
1072
1073 copyPhysReg(MBB, MI, DL, NewDestReg, NewSrcReg, KillSrc);
1074 return;
1075 }
1076
1077 if (ST.useRealTrue16Insts()) {
1078 if (IsSGPRSrc) {
1079 assert(SrcLow);
1080 SrcReg = NewSrcReg;
1081 }
1082 // Use the smaller instruction encoding if possible.
1083 if (AMDGPU::VGPR_16_Lo128RegClass.contains(DestReg) &&
1084 (IsSGPRSrc || AMDGPU::VGPR_16_Lo128RegClass.contains(SrcReg))) {
1085 BuildMI(MBB, MI, DL, get(AMDGPU::V_MOV_B16_t16_e32), DestReg)
1086 .addReg(SrcReg);
1087 } else {
1088 BuildMI(MBB, MI, DL, get(AMDGPU::V_MOV_B16_t16_e64), DestReg)
1089 .addImm(0) // src0_modifiers
1090 .addReg(SrcReg)
1091 .addImm(0); // op_sel
1092 }
1093 return;
1094 }
1095
1096 if (IsSGPRSrc && !ST.hasSDWAScalar()) {
1097 if (!DstLow || !SrcLow) {
1098 reportIllegalCopy(this, MBB, MI, DL, DestReg, SrcReg, KillSrc,
1099 "Cannot use hi16 subreg on VI!");
1100 }
1101
1102 BuildMI(MBB, MI, DL, get(AMDGPU::V_MOV_B32_e32), NewDestReg)
1103 .addReg(NewSrcReg, getKillRegState(KillSrc));
1104 return;
1105 }
1106
1107 auto MIB = BuildMI(MBB, MI, DL, get(AMDGPU::V_MOV_B32_sdwa), NewDestReg)
1108 .addImm(0) // src0_modifiers
1109 .addReg(NewSrcReg)
1110 .addImm(0) // clamp
1117 // First implicit operand is $exec.
1118 MIB->tieOperands(0, MIB->getNumOperands() - 1);
1119 return;
1120 }
1121
1122 if (RC == RI.getVGPR64Class() && (SrcRC == RC || RI.isSGPRClass(SrcRC))) {
1123 if (ST.hasVMovB64Inst()) {
1124 BuildMI(MBB, MI, DL, get(AMDGPU::V_MOV_B64_e32), DestReg)
1125 .addReg(SrcReg, getKillRegState(KillSrc));
1126 return;
1127 }
1128 if (ST.hasPkMovB32()) {
1129 BuildMI(MBB, MI, DL, get(AMDGPU::V_PK_MOV_B32), DestReg)
1131 .addReg(SrcReg)
1133 .addReg(SrcReg)
1134 .addImm(0) // op_sel_lo
1135 .addImm(0) // op_sel_hi
1136 .addImm(0) // neg_lo
1137 .addImm(0) // neg_hi
1138 .addImm(0) // clamp
1139 .addReg(SrcReg, getKillRegState(KillSrc) | RegState::Implicit);
1140 return;
1141 }
1142 }
1143
1144 const bool Forward = RI.getHWRegIndex(DestReg) <= RI.getHWRegIndex(SrcReg);
1145 if (RI.isSGPRClass(RC)) {
1146 if (!RI.isSGPRClass(SrcRC)) {
1147 reportIllegalCopy(this, MBB, MI, DL, DestReg, SrcReg, KillSrc);
1148 return;
1149 }
1150 const bool CanKillSuperReg = KillSrc && !RI.regsOverlap(SrcReg, DestReg);
1151 expandSGPRCopy(*this, MBB, MI, DL, DestReg, SrcReg, CanKillSuperReg, RC,
1152 Forward);
1153 return;
1154 }
1155
1156 unsigned EltSize = 4;
1157 unsigned Opcode = AMDGPU::V_MOV_B32_e32;
1158 if (RI.isAGPRClass(RC)) {
1159 if (ST.hasGFX90AInsts() && RI.isAGPRClass(SrcRC))
1160 Opcode = AMDGPU::V_ACCVGPR_MOV_B32;
1161 else if (RI.hasVGPRs(SrcRC) ||
1162 (ST.hasGFX90AInsts() && RI.isSGPRClass(SrcRC)))
1163 Opcode = AMDGPU::V_ACCVGPR_WRITE_B32_e64;
1164 else
1165 Opcode = AMDGPU::INSTRUCTION_LIST_END;
1166 } else if (RI.hasVGPRs(RC) && RI.isAGPRClass(SrcRC)) {
1167 Opcode = AMDGPU::V_ACCVGPR_READ_B32_e64;
1168 } else if ((Size % 64 == 0) && RI.hasVGPRs(RC) &&
1169 (RI.isProperlyAlignedRC(*RC) &&
1170 (SrcRC == RC || RI.isSGPRClass(SrcRC)))) {
1171 // TODO: In 96-bit case, could do a 64-bit mov and then a 32-bit mov.
1172 if (ST.hasVMovB64Inst()) {
1173 Opcode = AMDGPU::V_MOV_B64_e32;
1174 EltSize = 8;
1175 } else if (ST.hasPkMovB32()) {
1176 Opcode = AMDGPU::V_PK_MOV_B32;
1177 EltSize = 8;
1178 }
1179 }
1180
1181 // For the cases where we need an intermediate instruction/temporary register
1182 // (destination is an AGPR), we need a scavenger.
1183 //
1184 // FIXME: The pass should maintain this for us so we don't have to re-scan the
1185 // whole block for every handled copy.
1186 std::unique_ptr<RegScavenger> RS;
1187 if (Opcode == AMDGPU::INSTRUCTION_LIST_END)
1188 RS = std::make_unique<RegScavenger>();
1189
1190 ArrayRef<int16_t> SubIndices = RI.getRegSplitParts(RC, EltSize);
1191
1192 // If there is an overlap, we can't kill the super-register on the last
1193 // instruction, since it will also kill the components made live by this def.
1194 const bool Overlap = RI.regsOverlap(SrcReg, DestReg);
1195 const bool CanKillSuperReg = KillSrc && !Overlap;
1196
1197 for (unsigned Idx = 0; Idx < SubIndices.size(); ++Idx) {
1198 unsigned SubIdx;
1199 if (Forward)
1200 SubIdx = SubIndices[Idx];
1201 else
1202 SubIdx = SubIndices[SubIndices.size() - Idx - 1];
1203 Register DestSubReg = RI.getSubReg(DestReg, SubIdx);
1204 Register SrcSubReg = RI.getSubReg(SrcReg, SubIdx);
1205 assert(DestSubReg && SrcSubReg && "Failed to find subregs!");
1206
1207 bool UseKill = CanKillSuperReg && Idx == SubIndices.size() - 1;
1208
1209 if (Opcode == AMDGPU::INSTRUCTION_LIST_END) {
1210 Register ImpUseSuper = SrcReg;
1211 indirectCopyToAGPR(*this, MBB, MI, DL, DestSubReg, SrcSubReg, UseKill,
1212 *RS, Overlap, ImpUseSuper);
1213 } else if (Opcode == AMDGPU::V_PK_MOV_B32) {
1214 BuildMI(MBB, MI, DL, get(AMDGPU::V_PK_MOV_B32), DestSubReg)
1216 .addReg(SrcSubReg)
1218 .addReg(SrcSubReg)
1219 .addImm(0) // op_sel_lo
1220 .addImm(0) // op_sel_hi
1221 .addImm(0) // neg_lo
1222 .addImm(0) // neg_hi
1223 .addImm(0) // clamp
1224 .addReg(SrcReg, getKillRegState(UseKill) | RegState::Implicit);
1225 } else {
1226 MachineInstrBuilder Builder =
1227 BuildMI(MBB, MI, DL, get(Opcode), DestSubReg).addReg(SrcSubReg);
1228
1229 Builder.addReg(SrcReg, getKillRegState(UseKill) | RegState::Implicit);
1230 }
1231 }
1232}
1233
1234int SIInstrInfo::commuteOpcode(unsigned Opcode) const {
1235 int32_t NewOpc;
1236
1237 // Try to map original to commuted opcode
1238 NewOpc = AMDGPU::getCommuteRev(Opcode);
1239 if (NewOpc != -1)
1240 // Check if the commuted (REV) opcode exists on the target.
1241 return pseudoToMCOpcode(NewOpc) != -1 ? NewOpc : -1;
1242
1243 // Try to map commuted to original opcode
1244 NewOpc = AMDGPU::getCommuteOrig(Opcode);
1245 if (NewOpc != -1)
1246 // Check if the original (non-REV) opcode exists on the target.
1247 return pseudoToMCOpcode(NewOpc) != -1 ? NewOpc : -1;
1248
1249 return Opcode;
1250}
1251
1253 const Register Reg,
1254 int64_t &ImmVal) const {
1255 switch (MI.getOpcode()) {
1256 case AMDGPU::V_MOV_B32_e32:
1257 case AMDGPU::S_MOV_B32:
1258 case AMDGPU::S_MOVK_I32:
1259 case AMDGPU::S_MOV_B64:
1260 case AMDGPU::V_MOV_B64_e32:
1261 case AMDGPU::V_ACCVGPR_WRITE_B32_e64:
1262 case AMDGPU::AV_MOV_B32_IMM_PSEUDO:
1263 case AMDGPU::AV_MOV_B64_IMM_PSEUDO:
1264 case AMDGPU::S_MOV_B64_IMM_PSEUDO:
1265 case AMDGPU::V_MOV_B64_PSEUDO:
1266 case AMDGPU::V_MOV_B16_t16_e32: {
1267 const MachineOperand &Src0 = MI.getOperand(1);
1268 if (Src0.isImm()) {
1269 ImmVal = Src0.getImm();
1270 return MI.getOperand(0).getReg() == Reg;
1271 }
1272
1273 return false;
1274 }
1275 case AMDGPU::V_MOV_B16_t16_e64: {
1276 const MachineOperand &Src0 = MI.getOperand(2);
1277 if (Src0.isImm() && !MI.getOperand(1).getImm()) {
1278 ImmVal = Src0.getImm();
1279 return MI.getOperand(0).getReg() == Reg;
1280 }
1281
1282 return false;
1283 }
1284 case AMDGPU::S_BREV_B32:
1285 case AMDGPU::V_BFREV_B32_e32:
1286 case AMDGPU::V_BFREV_B32_e64: {
1287 const MachineOperand &Src0 = MI.getOperand(1);
1288 if (Src0.isImm()) {
1289 ImmVal = static_cast<int64_t>(reverseBits<int32_t>(Src0.getImm()));
1290 return MI.getOperand(0).getReg() == Reg;
1291 }
1292
1293 return false;
1294 }
1295 case AMDGPU::S_NOT_B32:
1296 case AMDGPU::V_NOT_B32_e32:
1297 case AMDGPU::V_NOT_B32_e64: {
1298 const MachineOperand &Src0 = MI.getOperand(1);
1299 if (Src0.isImm()) {
1300 ImmVal = static_cast<int64_t>(~static_cast<int32_t>(Src0.getImm()));
1301 return MI.getOperand(0).getReg() == Reg;
1302 }
1303
1304 return false;
1305 }
1306 default:
1307 return false;
1308 }
1309}
1310
1311std::optional<int64_t>
1313 const MachineOperand &Op,
1314 MachineInstr **DefMI) const {
1315 if (DefMI)
1316 *DefMI = nullptr;
1317
1318 if (Op.isImm())
1319 return Op.getImm();
1320
1321 if (!Op.isReg() || !Op.getReg().isVirtual())
1322 return std::nullopt;
1323 MachineInstr *Def = MRI.getUniqueVRegDef(Op.getReg());
1324 if (Def && Def->isMoveImmediate()) {
1325 const MachineOperand &ImmSrc = Def->getOperand(1);
1326 if (ImmSrc.isImm()) {
1327 if (DefMI)
1328 *DefMI = Def;
1329 return extractSubregFromImm(ImmSrc.getImm(), Op.getSubReg());
1330 }
1331 }
1332
1333 return std::nullopt;
1334}
1335
1336std::optional<int64_t>
1342
1344
1345 if (RI.isAGPRClass(DstRC))
1346 return AMDGPU::COPY;
1347 if (RI.getRegSizeInBits(*DstRC) == 16) {
1348 // Assume hi bits are unneeded. Only _e64 true16 instructions are legal
1349 // before RA.
1350 return RI.isSGPRClass(DstRC) ? AMDGPU::COPY : AMDGPU::V_MOV_B16_t16_e64;
1351 }
1352 if (RI.getRegSizeInBits(*DstRC) == 32)
1353 return RI.isSGPRClass(DstRC) ? AMDGPU::S_MOV_B32 : AMDGPU::V_MOV_B32_e32;
1354 if (RI.getRegSizeInBits(*DstRC) == 64 && RI.isSGPRClass(DstRC))
1355 return AMDGPU::S_MOV_B64;
1356 if (RI.getRegSizeInBits(*DstRC) == 64 && !RI.isSGPRClass(DstRC))
1357 return AMDGPU::V_MOV_B64_PSEUDO;
1358 return AMDGPU::COPY;
1359}
1360
1361const MCInstrDesc &
1363 bool IsIndirectSrc) const {
1364 if (IsIndirectSrc) {
1365 if (VecSize <= 32) // 4 bytes
1366 return get(AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V1);
1367 if (VecSize <= 64) // 8 bytes
1368 return get(AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V2);
1369 if (VecSize <= 96) // 12 bytes
1370 return get(AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V3);
1371 if (VecSize <= 128) // 16 bytes
1372 return get(AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V4);
1373 if (VecSize <= 160) // 20 bytes
1374 return get(AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V5);
1375 if (VecSize <= 192) // 24 bytes
1376 return get(AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V6);
1377 if (VecSize <= 224) // 28 bytes
1378 return get(AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V7);
1379 if (VecSize <= 256) // 32 bytes
1380 return get(AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V8);
1381 if (VecSize <= 288) // 36 bytes
1382 return get(AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V9);
1383 if (VecSize <= 320) // 40 bytes
1384 return get(AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V10);
1385 if (VecSize <= 352) // 44 bytes
1386 return get(AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V11);
1387 if (VecSize <= 384) // 48 bytes
1388 return get(AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V12);
1389 if (VecSize <= 512) // 64 bytes
1390 return get(AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V16);
1391 if (VecSize <= 1024) // 128 bytes
1392 return get(AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V32);
1393
1394 llvm_unreachable("unsupported size for IndirectRegReadGPRIDX pseudos");
1395 }
1396
1397 if (VecSize <= 32) // 4 bytes
1398 return get(AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V1);
1399 if (VecSize <= 64) // 8 bytes
1400 return get(AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V2);
1401 if (VecSize <= 96) // 12 bytes
1402 return get(AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V3);
1403 if (VecSize <= 128) // 16 bytes
1404 return get(AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V4);
1405 if (VecSize <= 160) // 20 bytes
1406 return get(AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V5);
1407 if (VecSize <= 192) // 24 bytes
1408 return get(AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V6);
1409 if (VecSize <= 224) // 28 bytes
1410 return get(AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V7);
1411 if (VecSize <= 256) // 32 bytes
1412 return get(AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V8);
1413 if (VecSize <= 288) // 36 bytes
1414 return get(AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V9);
1415 if (VecSize <= 320) // 40 bytes
1416 return get(AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V10);
1417 if (VecSize <= 352) // 44 bytes
1418 return get(AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V11);
1419 if (VecSize <= 384) // 48 bytes
1420 return get(AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V12);
1421 if (VecSize <= 512) // 64 bytes
1422 return get(AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V16);
1423 if (VecSize <= 1024) // 128 bytes
1424 return get(AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V32);
1425
1426 llvm_unreachable("unsupported size for IndirectRegWriteGPRIDX pseudos");
1427}
1428
1429static unsigned getIndirectVGPRWriteMovRelPseudoOpc(unsigned VecSize) {
1430 if (VecSize <= 32) // 4 bytes
1431 return AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V1;
1432 if (VecSize <= 64) // 8 bytes
1433 return AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V2;
1434 if (VecSize <= 96) // 12 bytes
1435 return AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V3;
1436 if (VecSize <= 128) // 16 bytes
1437 return AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V4;
1438 if (VecSize <= 160) // 20 bytes
1439 return AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V5;
1440 if (VecSize <= 192) // 24 bytes
1441 return AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V6;
1442 if (VecSize <= 224) // 28 bytes
1443 return AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V7;
1444 if (VecSize <= 256) // 32 bytes
1445 return AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V8;
1446 if (VecSize <= 288) // 36 bytes
1447 return AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V9;
1448 if (VecSize <= 320) // 40 bytes
1449 return AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V10;
1450 if (VecSize <= 352) // 44 bytes
1451 return AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V11;
1452 if (VecSize <= 384) // 48 bytes
1453 return AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V12;
1454 if (VecSize <= 512) // 64 bytes
1455 return AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V16;
1456 if (VecSize <= 1024) // 128 bytes
1457 return AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V32;
1458
1459 llvm_unreachable("unsupported size for IndirectRegWrite pseudos");
1460}
1461
1462static unsigned getIndirectSGPRWriteMovRelPseudo32(unsigned VecSize) {
1463 if (VecSize <= 32) // 4 bytes
1464 return AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V1;
1465 if (VecSize <= 64) // 8 bytes
1466 return AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V2;
1467 if (VecSize <= 96) // 12 bytes
1468 return AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V3;
1469 if (VecSize <= 128) // 16 bytes
1470 return AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V4;
1471 if (VecSize <= 160) // 20 bytes
1472 return AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V5;
1473 if (VecSize <= 192) // 24 bytes
1474 return AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V6;
1475 if (VecSize <= 224) // 28 bytes
1476 return AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V7;
1477 if (VecSize <= 256) // 32 bytes
1478 return AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V8;
1479 if (VecSize <= 288) // 36 bytes
1480 return AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V9;
1481 if (VecSize <= 320) // 40 bytes
1482 return AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V10;
1483 if (VecSize <= 352) // 44 bytes
1484 return AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V11;
1485 if (VecSize <= 384) // 48 bytes
1486 return AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V12;
1487 if (VecSize <= 512) // 64 bytes
1488 return AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V16;
1489 if (VecSize <= 1024) // 128 bytes
1490 return AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V32;
1491
1492 llvm_unreachable("unsupported size for IndirectRegWrite pseudos");
1493}
1494
1495static unsigned getIndirectSGPRWriteMovRelPseudo64(unsigned VecSize) {
1496 if (VecSize <= 64) // 8 bytes
1497 return AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B64_V1;
1498 if (VecSize <= 128) // 16 bytes
1499 return AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B64_V2;
1500 if (VecSize <= 256) // 32 bytes
1501 return AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B64_V4;
1502 if (VecSize <= 512) // 64 bytes
1503 return AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B64_V8;
1504 if (VecSize <= 1024) // 128 bytes
1505 return AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B64_V16;
1506
1507 llvm_unreachable("unsupported size for IndirectRegWrite pseudos");
1508}
1509
1510const MCInstrDesc &
1511SIInstrInfo::getIndirectRegWriteMovRelPseudo(unsigned VecSize, unsigned EltSize,
1512 bool IsSGPR) const {
1513 if (IsSGPR) {
1514 switch (EltSize) {
1515 case 32:
1516 return get(getIndirectSGPRWriteMovRelPseudo32(VecSize));
1517 case 64:
1518 return get(getIndirectSGPRWriteMovRelPseudo64(VecSize));
1519 default:
1520 llvm_unreachable("invalid reg indexing elt size");
1521 }
1522 }
1523
1524 assert(EltSize == 32 && "invalid reg indexing elt size");
1526}
1527
1528static unsigned getSGPRSpillSaveOpcode(unsigned Size, bool NeedsCFI) {
1529 switch (Size) {
1530 case 4:
1531 return NeedsCFI ? AMDGPU::SI_SPILL_S32_CFI_SAVE : AMDGPU::SI_SPILL_S32_SAVE;
1532 case 8:
1533 return NeedsCFI ? AMDGPU::SI_SPILL_S64_CFI_SAVE : AMDGPU::SI_SPILL_S64_SAVE;
1534 case 12:
1535 return NeedsCFI ? AMDGPU::SI_SPILL_S96_CFI_SAVE : AMDGPU::SI_SPILL_S96_SAVE;
1536 case 16:
1537 return NeedsCFI ? AMDGPU::SI_SPILL_S128_CFI_SAVE
1538 : AMDGPU::SI_SPILL_S128_SAVE;
1539 case 20:
1540 return NeedsCFI ? AMDGPU::SI_SPILL_S160_CFI_SAVE
1541 : AMDGPU::SI_SPILL_S160_SAVE;
1542 case 24:
1543 return NeedsCFI ? AMDGPU::SI_SPILL_S192_CFI_SAVE
1544 : AMDGPU::SI_SPILL_S192_SAVE;
1545 case 28:
1546 return NeedsCFI ? AMDGPU::SI_SPILL_S224_CFI_SAVE
1547 : AMDGPU::SI_SPILL_S224_SAVE;
1548 case 32:
1549 return AMDGPU::SI_SPILL_S256_SAVE;
1550 case 36:
1551 return AMDGPU::SI_SPILL_S288_SAVE;
1552 case 40:
1553 return AMDGPU::SI_SPILL_S320_SAVE;
1554 case 44:
1555 return AMDGPU::SI_SPILL_S352_SAVE;
1556 case 48:
1557 return AMDGPU::SI_SPILL_S384_SAVE;
1558 case 64:
1559 return NeedsCFI ? AMDGPU::SI_SPILL_S512_CFI_SAVE
1560 : AMDGPU::SI_SPILL_S512_SAVE;
1561 case 128:
1562 return NeedsCFI ? AMDGPU::SI_SPILL_S1024_CFI_SAVE
1563 : AMDGPU::SI_SPILL_S1024_SAVE;
1564 default:
1565 llvm_unreachable("unknown register size");
1566 }
1567}
1568
1569static unsigned getVGPRSpillSaveOpcode(unsigned Size, bool NeedsCFI) {
1570 switch (Size) {
1571 case 2:
1572 return AMDGPU::SI_SPILL_V16_SAVE;
1573 case 4:
1574 return NeedsCFI ? AMDGPU::SI_SPILL_V32_CFI_SAVE : AMDGPU::SI_SPILL_V32_SAVE;
1575 case 8:
1576 return NeedsCFI ? AMDGPU::SI_SPILL_V64_CFI_SAVE : AMDGPU::SI_SPILL_V64_SAVE;
1577 case 12:
1578 return NeedsCFI ? AMDGPU::SI_SPILL_V96_CFI_SAVE : AMDGPU::SI_SPILL_V96_SAVE;
1579 case 16:
1580 return NeedsCFI ? AMDGPU::SI_SPILL_V128_CFI_SAVE
1581 : AMDGPU::SI_SPILL_V128_SAVE;
1582 case 20:
1583 return NeedsCFI ? AMDGPU::SI_SPILL_V160_CFI_SAVE
1584 : AMDGPU::SI_SPILL_V160_SAVE;
1585 case 24:
1586 return NeedsCFI ? AMDGPU::SI_SPILL_V192_CFI_SAVE
1587 : AMDGPU::SI_SPILL_V192_SAVE;
1588 case 28:
1589 return NeedsCFI ? AMDGPU::SI_SPILL_V224_CFI_SAVE
1590 : AMDGPU::SI_SPILL_V224_SAVE;
1591 case 32:
1592 return NeedsCFI ? AMDGPU::SI_SPILL_V256_CFI_SAVE
1593 : AMDGPU::SI_SPILL_V256_SAVE;
1594 case 36:
1595 return NeedsCFI ? AMDGPU::SI_SPILL_V288_CFI_SAVE
1596 : AMDGPU::SI_SPILL_V288_SAVE;
1597 case 40:
1598 return NeedsCFI ? AMDGPU::SI_SPILL_V320_CFI_SAVE
1599 : AMDGPU::SI_SPILL_V320_SAVE;
1600 case 44:
1601 return NeedsCFI ? AMDGPU::SI_SPILL_V352_CFI_SAVE
1602 : AMDGPU::SI_SPILL_V352_SAVE;
1603 case 48:
1604 return NeedsCFI ? AMDGPU::SI_SPILL_V384_CFI_SAVE
1605 : AMDGPU::SI_SPILL_V384_SAVE;
1606 case 64:
1607 return NeedsCFI ? AMDGPU::SI_SPILL_V512_CFI_SAVE
1608 : AMDGPU::SI_SPILL_V512_SAVE;
1609 case 128:
1610 return NeedsCFI ? AMDGPU::SI_SPILL_V1024_CFI_SAVE
1611 : AMDGPU::SI_SPILL_V1024_SAVE;
1612 default:
1613 llvm_unreachable("unknown register size");
1614 }
1615}
1616
1617static unsigned getAVSpillSaveOpcode(unsigned Size, bool NeedsCFI) {
1618 switch (Size) {
1619 case 4:
1620 return NeedsCFI ? AMDGPU::SI_SPILL_AV32_CFI_SAVE
1621 : AMDGPU::SI_SPILL_AV32_SAVE;
1622 case 8:
1623 return NeedsCFI ? AMDGPU::SI_SPILL_AV64_CFI_SAVE
1624 : AMDGPU::SI_SPILL_AV64_SAVE;
1625 case 12:
1626 return NeedsCFI ? AMDGPU::SI_SPILL_AV96_CFI_SAVE
1627 : AMDGPU::SI_SPILL_AV96_SAVE;
1628 case 16:
1629 return NeedsCFI ? AMDGPU::SI_SPILL_AV128_CFI_SAVE
1630 : AMDGPU::SI_SPILL_AV128_SAVE;
1631 case 20:
1632 return NeedsCFI ? AMDGPU::SI_SPILL_AV160_CFI_SAVE
1633 : AMDGPU::SI_SPILL_AV160_SAVE;
1634 case 24:
1635 return NeedsCFI ? AMDGPU::SI_SPILL_AV192_CFI_SAVE
1636 : AMDGPU::SI_SPILL_AV192_SAVE;
1637 case 28:
1638 return NeedsCFI ? AMDGPU::SI_SPILL_AV224_CFI_SAVE
1639 : AMDGPU::SI_SPILL_AV224_SAVE;
1640 case 32:
1641 return NeedsCFI ? AMDGPU::SI_SPILL_AV256_CFI_SAVE
1642 : AMDGPU::SI_SPILL_AV256_SAVE;
1643 case 36:
1644 return AMDGPU::SI_SPILL_AV288_SAVE;
1645 case 40:
1646 return AMDGPU::SI_SPILL_AV320_SAVE;
1647 case 44:
1648 return AMDGPU::SI_SPILL_AV352_SAVE;
1649 case 48:
1650 return AMDGPU::SI_SPILL_AV384_SAVE;
1651 case 64:
1652 return NeedsCFI ? AMDGPU::SI_SPILL_AV512_CFI_SAVE
1653 : AMDGPU::SI_SPILL_AV512_SAVE;
1654 case 128:
1655 return NeedsCFI ? AMDGPU::SI_SPILL_AV1024_CFI_SAVE
1656 : AMDGPU::SI_SPILL_AV1024_SAVE;
1657 default:
1658 llvm_unreachable("unknown register size");
1659 }
1660}
1661
1662static unsigned getWWMRegSpillSaveOpcode(unsigned Size,
1663 bool IsVectorSuperClass) {
1664 // Currently, there is only 32-bit WWM register spills needed.
1665 if (Size != 4)
1666 llvm_unreachable("unknown wwm register spill size");
1667
1668 if (IsVectorSuperClass)
1669 return AMDGPU::SI_SPILL_WWM_AV32_SAVE;
1670
1671 return AMDGPU::SI_SPILL_WWM_V32_SAVE;
1672}
1673
1675 Register Reg, const TargetRegisterClass *RC, unsigned Size,
1676 const SIMachineFunctionInfo &MFI, bool NeedsCFI) const {
1677 bool IsVectorSuperClass = RI.isVectorSuperClass(RC);
1678
1679 // Choose the right opcode if spilling a WWM register.
1681 return getWWMRegSpillSaveOpcode(Size, IsVectorSuperClass);
1682
1683 // TODO: Check if AGPRs are available
1684 if (ST.hasMAIInsts())
1685 return getAVSpillSaveOpcode(Size, NeedsCFI);
1686
1687 return getVGPRSpillSaveOpcode(Size, NeedsCFI);
1688}
1689
1690void SIInstrInfo::storeRegToStackSlotImpl(
1692 bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg,
1693 MachineInstr::MIFlag Flags, bool NeedsCFI) const {
1694 MachineFunction *MF = MBB.getParent();
1696 MachineFrameInfo &FrameInfo = MF->getFrameInfo();
1697 const DebugLoc &DL = MBB.findDebugLoc(MI);
1698
1699 MachinePointerInfo PtrInfo
1700 = MachinePointerInfo::getFixedStack(*MF, FrameIndex);
1702 PtrInfo, MachineMemOperand::MOStore, FrameInfo.getObjectSize(FrameIndex),
1703 FrameInfo.getObjectAlign(FrameIndex));
1704 unsigned SpillSize = RI.getSpillSize(*RC);
1705
1706 MachineRegisterInfo &MRI = MF->getRegInfo();
1707 if (RI.isSGPRClass(RC)) {
1708 if (FrameInfo.getStackID(FrameIndex) == TargetStackID::SGPRSpill)
1709 MFI->setHasSpilledSGPRs();
1710 assert(SrcReg != AMDGPU::M0 && "m0 should not be spilled");
1711 assert(SrcReg != AMDGPU::EXEC_LO && SrcReg != AMDGPU::EXEC_HI &&
1712 SrcReg != AMDGPU::EXEC && "exec should not be spilled");
1713
1714 // We are only allowed to create one new instruction when spilling
1715 // registers, so we need to use pseudo instruction for spilling SGPRs.
1716 const MCInstrDesc &OpDesc =
1717 get(getSGPRSpillSaveOpcode(SpillSize, NeedsCFI));
1718
1719 // The SGPR spill/restore instructions only work on number sgprs, so we need
1720 // to make sure we are using the correct register class.
1721 if (SrcReg.isVirtual() && SpillSize == 4) {
1722 MRI.constrainRegClass(SrcReg, &AMDGPU::SReg_32_XM0_XEXECRegClass);
1723 }
1724
1725 BuildMI(MBB, MI, DL, OpDesc)
1726 .addReg(SrcReg, getKillRegState(isKill)) // data
1727 .addFrameIndex(FrameIndex) // addr
1728 .addMemOperand(MMO)
1730
1731 return;
1732 }
1733
1734 unsigned Opcode = getVectorRegSpillSaveOpcode(VReg ? VReg : SrcReg, RC,
1735 SpillSize, *MFI, NeedsCFI);
1736 MFI->setHasSpilledVGPRs();
1737
1738 BuildMI(MBB, MI, DL, get(Opcode))
1739 .addReg(SrcReg, getKillRegState(isKill)) // data
1740 .addFrameIndex(FrameIndex) // addr
1741 .addReg(MFI->getStackPtrOffsetReg()) // scratch_offset
1742 .addImm(0) // offset
1743 .addMemOperand(MMO);
1744}
1745
1748 bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg,
1749 MachineInstr::MIFlag Flags) const {
1750 storeRegToStackSlotImpl(MBB, MI, SrcReg, isKill, FrameIndex, RC, VReg, Flags,
1751 false);
1752}
1753
1756 Register SrcReg, bool isKill,
1757 int FrameIndex,
1758 const TargetRegisterClass *RC) const {
1759 storeRegToStackSlotImpl(MBB, MI, SrcReg, isKill, FrameIndex, RC, Register(),
1760 MachineInstr::NoFlags, true);
1761}
1762
1763static unsigned getSGPRSpillRestoreOpcode(unsigned Size) {
1764 switch (Size) {
1765 case 4:
1766 return AMDGPU::SI_SPILL_S32_RESTORE;
1767 case 8:
1768 return AMDGPU::SI_SPILL_S64_RESTORE;
1769 case 12:
1770 return AMDGPU::SI_SPILL_S96_RESTORE;
1771 case 16:
1772 return AMDGPU::SI_SPILL_S128_RESTORE;
1773 case 20:
1774 return AMDGPU::SI_SPILL_S160_RESTORE;
1775 case 24:
1776 return AMDGPU::SI_SPILL_S192_RESTORE;
1777 case 28:
1778 return AMDGPU::SI_SPILL_S224_RESTORE;
1779 case 32:
1780 return AMDGPU::SI_SPILL_S256_RESTORE;
1781 case 36:
1782 return AMDGPU::SI_SPILL_S288_RESTORE;
1783 case 40:
1784 return AMDGPU::SI_SPILL_S320_RESTORE;
1785 case 44:
1786 return AMDGPU::SI_SPILL_S352_RESTORE;
1787 case 48:
1788 return AMDGPU::SI_SPILL_S384_RESTORE;
1789 case 64:
1790 return AMDGPU::SI_SPILL_S512_RESTORE;
1791 case 128:
1792 return AMDGPU::SI_SPILL_S1024_RESTORE;
1793 default:
1794 llvm_unreachable("unknown register size");
1795 }
1796}
1797
1798static unsigned getVGPRSpillRestoreOpcode(unsigned Size) {
1799 switch (Size) {
1800 case 2:
1801 return AMDGPU::SI_SPILL_V16_RESTORE;
1802 case 4:
1803 return AMDGPU::SI_SPILL_V32_RESTORE;
1804 case 8:
1805 return AMDGPU::SI_SPILL_V64_RESTORE;
1806 case 12:
1807 return AMDGPU::SI_SPILL_V96_RESTORE;
1808 case 16:
1809 return AMDGPU::SI_SPILL_V128_RESTORE;
1810 case 20:
1811 return AMDGPU::SI_SPILL_V160_RESTORE;
1812 case 24:
1813 return AMDGPU::SI_SPILL_V192_RESTORE;
1814 case 28:
1815 return AMDGPU::SI_SPILL_V224_RESTORE;
1816 case 32:
1817 return AMDGPU::SI_SPILL_V256_RESTORE;
1818 case 36:
1819 return AMDGPU::SI_SPILL_V288_RESTORE;
1820 case 40:
1821 return AMDGPU::SI_SPILL_V320_RESTORE;
1822 case 44:
1823 return AMDGPU::SI_SPILL_V352_RESTORE;
1824 case 48:
1825 return AMDGPU::SI_SPILL_V384_RESTORE;
1826 case 64:
1827 return AMDGPU::SI_SPILL_V512_RESTORE;
1828 case 128:
1829 return AMDGPU::SI_SPILL_V1024_RESTORE;
1830 default:
1831 llvm_unreachable("unknown register size");
1832 }
1833}
1834
1835static unsigned getAVSpillRestoreOpcode(unsigned Size) {
1836 switch (Size) {
1837 case 4:
1838 return AMDGPU::SI_SPILL_AV32_RESTORE;
1839 case 8:
1840 return AMDGPU::SI_SPILL_AV64_RESTORE;
1841 case 12:
1842 return AMDGPU::SI_SPILL_AV96_RESTORE;
1843 case 16:
1844 return AMDGPU::SI_SPILL_AV128_RESTORE;
1845 case 20:
1846 return AMDGPU::SI_SPILL_AV160_RESTORE;
1847 case 24:
1848 return AMDGPU::SI_SPILL_AV192_RESTORE;
1849 case 28:
1850 return AMDGPU::SI_SPILL_AV224_RESTORE;
1851 case 32:
1852 return AMDGPU::SI_SPILL_AV256_RESTORE;
1853 case 36:
1854 return AMDGPU::SI_SPILL_AV288_RESTORE;
1855 case 40:
1856 return AMDGPU::SI_SPILL_AV320_RESTORE;
1857 case 44:
1858 return AMDGPU::SI_SPILL_AV352_RESTORE;
1859 case 48:
1860 return AMDGPU::SI_SPILL_AV384_RESTORE;
1861 case 64:
1862 return AMDGPU::SI_SPILL_AV512_RESTORE;
1863 case 128:
1864 return AMDGPU::SI_SPILL_AV1024_RESTORE;
1865 default:
1866 llvm_unreachable("unknown register size");
1867 }
1868}
1869
1870static unsigned getWWMRegSpillRestoreOpcode(unsigned Size,
1871 bool IsVectorSuperClass) {
1872 // Currently, there is only 32-bit WWM register spills needed.
1873 if (Size != 4)
1874 llvm_unreachable("unknown wwm register spill size");
1875
1876 if (IsVectorSuperClass) // TODO: Always use this if there are AGPRs
1877 return AMDGPU::SI_SPILL_WWM_AV32_RESTORE;
1878
1879 return AMDGPU::SI_SPILL_WWM_V32_RESTORE;
1880}
1881
1883 Register Reg, const TargetRegisterClass *RC, unsigned Size,
1884 const SIMachineFunctionInfo &MFI) const {
1885 bool IsVectorSuperClass = RI.isVectorSuperClass(RC);
1886
1887 // Choose the right opcode if restoring a WWM register.
1889 return getWWMRegSpillRestoreOpcode(Size, IsVectorSuperClass);
1890
1891 // TODO: Check if AGPRs are available
1892 if (ST.hasMAIInsts())
1894
1895 assert(!RI.isAGPRClass(RC));
1897}
1898
1901 Register DestReg, int FrameIndex,
1902 const TargetRegisterClass *RC,
1903 Register VReg, unsigned SubReg,
1904 MachineInstr::MIFlag Flags) const {
1905 MachineFunction *MF = MBB.getParent();
1907 MachineFrameInfo &FrameInfo = MF->getFrameInfo();
1908 const DebugLoc &DL = MBB.findDebugLoc(MI);
1909 unsigned SpillSize = RI.getSpillSize(*RC);
1910
1911 MachinePointerInfo PtrInfo
1912 = MachinePointerInfo::getFixedStack(*MF, FrameIndex);
1913
1915 PtrInfo, MachineMemOperand::MOLoad, FrameInfo.getObjectSize(FrameIndex),
1916 FrameInfo.getObjectAlign(FrameIndex));
1917
1918 if (RI.isSGPRClass(RC)) {
1919 if (FrameInfo.getStackID(FrameIndex) == TargetStackID::SGPRSpill)
1920 MFI->setHasSpilledSGPRs();
1921 assert(DestReg != AMDGPU::M0 && "m0 should not be reloaded into");
1922 assert(DestReg != AMDGPU::EXEC_LO && DestReg != AMDGPU::EXEC_HI &&
1923 DestReg != AMDGPU::EXEC && "exec should not be spilled");
1924
1925 // FIXME: Maybe this should not include a memoperand because it will be
1926 // lowered to non-memory instructions.
1927 const MCInstrDesc &OpDesc = get(getSGPRSpillRestoreOpcode(SpillSize));
1928 if (DestReg.isVirtual() && SpillSize == 4) {
1929 MachineRegisterInfo &MRI = MF->getRegInfo();
1930 MRI.constrainRegClass(DestReg, &AMDGPU::SReg_32_XM0_XEXECRegClass);
1931 }
1932
1933 BuildMI(MBB, MI, DL, OpDesc, DestReg)
1934 .addFrameIndex(FrameIndex) // addr
1935 .addMemOperand(MMO)
1937
1938 return;
1939 }
1940
1941 unsigned Opcode = getVectorRegSpillRestoreOpcode(VReg ? VReg : DestReg, RC,
1942 SpillSize, *MFI);
1943 BuildMI(MBB, MI, DL, get(Opcode), DestReg)
1944 .addFrameIndex(FrameIndex) // vaddr
1945 .addReg(MFI->getStackPtrOffsetReg()) // scratch_offset
1946 .addImm(0) // offset
1947 .addMemOperand(MMO);
1948}
1949
1954
1957 unsigned Quantity) const {
1958 DebugLoc DL = MBB.findDebugLoc(MI);
1959 unsigned MaxSNopCount = 1u << ST.getSNopBits();
1960 while (Quantity > 0) {
1961 unsigned Arg = std::min(Quantity, MaxSNopCount);
1962 Quantity -= Arg;
1963 BuildMI(MBB, MI, DL, get(AMDGPU::S_NOP)).addImm(Arg - 1);
1964 }
1965}
1966
1970 const DebugLoc &DL) const {
1971 MachineFunction *MF = MBB.getParent();
1972 constexpr unsigned DoorbellIDMask = 0x3ff;
1973 constexpr unsigned ECQueueWaveAbort = 0x400;
1974
1975 MachineBasicBlock *TrapBB = &MBB;
1976 MachineBasicBlock *HaltLoopBB = MF->CreateMachineBasicBlock();
1977
1978 if (!MBB.succ_empty() || std::next(MI.getIterator()) != MBB.end()) {
1979 MBB.splitAt(MI, /*UpdateLiveIns=*/false);
1980 TrapBB = MF->CreateMachineBasicBlock();
1981 BuildMI(MBB, MI, DL, get(AMDGPU::S_CBRANCH_EXECNZ)).addMBB(TrapBB);
1982 MF->push_back(TrapBB);
1983 MBB.addSuccessor(TrapBB);
1984 }
1985 // Start with a `s_trap 2`, if we're in PRIV=1 and we need the workaround this
1986 // will be a nop.
1987 BuildMI(*TrapBB, TrapBB->end(), DL, get(AMDGPU::S_TRAP))
1988 .addImm(static_cast<unsigned>(GCNSubtarget::TrapID::LLVMAMDHSATrap));
1989 Register DoorbellReg = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
1990 BuildMI(*TrapBB, TrapBB->end(), DL, get(AMDGPU::S_SENDMSG_RTN_B32),
1991 DoorbellReg)
1993 BuildMI(*TrapBB, TrapBB->end(), DL, get(AMDGPU::S_MOV_B32), AMDGPU::TTMP2)
1994 .addUse(AMDGPU::M0);
1995 Register DoorbellRegMasked =
1996 MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
1997 BuildMI(*TrapBB, TrapBB->end(), DL, get(AMDGPU::S_AND_B32), DoorbellRegMasked)
1998 .addUse(DoorbellReg)
1999 .addImm(DoorbellIDMask);
2000 Register SetWaveAbortBit =
2001 MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
2002 BuildMI(*TrapBB, TrapBB->end(), DL, get(AMDGPU::S_OR_B32), SetWaveAbortBit)
2003 .addUse(DoorbellRegMasked)
2004 .addImm(ECQueueWaveAbort);
2005 BuildMI(*TrapBB, TrapBB->end(), DL, get(AMDGPU::S_MOV_B32), AMDGPU::M0)
2006 .addUse(SetWaveAbortBit);
2007 BuildMI(*TrapBB, TrapBB->end(), DL, get(AMDGPU::S_SENDMSG))
2009 BuildMI(*TrapBB, TrapBB->end(), DL, get(AMDGPU::S_MOV_B32), AMDGPU::M0)
2010 .addUse(AMDGPU::TTMP2);
2011 BuildMI(*TrapBB, TrapBB->end(), DL, get(AMDGPU::S_BRANCH)).addMBB(HaltLoopBB);
2012 TrapBB->addSuccessor(HaltLoopBB);
2013
2014 BuildMI(*HaltLoopBB, HaltLoopBB->end(), DL, get(AMDGPU::S_SETHALT)).addImm(5);
2015 BuildMI(*HaltLoopBB, HaltLoopBB->end(), DL, get(AMDGPU::S_BRANCH))
2016 .addMBB(HaltLoopBB);
2017 MF->push_back(HaltLoopBB);
2018 HaltLoopBB->addSuccessor(HaltLoopBB);
2019
2020 return MBB.getNextNode();
2021}
2022
2024 switch (MI.getOpcode()) {
2025 default:
2026 if (MI.isMetaInstruction())
2027 return 0;
2028 return 1; // FIXME: Do wait states equal cycles?
2029
2030 case AMDGPU::S_NOP:
2031 return MI.getOperand(0).getImm() + 1;
2032 // SI_RETURN_TO_EPILOG is a fallthrough to code outside of the function. The
2033 // hazard, even if one exist, won't really be visible. Should we handle it?
2034 }
2035}
2036
2038 MachineBasicBlock &MBB = *MI.getParent();
2039 DebugLoc DL = MBB.findDebugLoc(MI);
2041
2042 switch (MI.getOpcode()) {
2043 default: return TargetInstrInfo::expandPostRAPseudo(MI);
2044 case AMDGPU::S_MOV_B64_term:
2045 // This is only a terminator to get the correct spill code placement during
2046 // register allocation.
2047 MI.setDesc(get(AMDGPU::S_MOV_B64));
2048 break;
2049
2050 case AMDGPU::S_MOV_B32_term:
2051 // This is only a terminator to get the correct spill code placement during
2052 // register allocation.
2053 MI.setDesc(get(AMDGPU::S_MOV_B32));
2054 break;
2055
2056 case AMDGPU::S_XOR_B64_term:
2057 // This is only a terminator to get the correct spill code placement during
2058 // register allocation.
2059 MI.setDesc(get(AMDGPU::S_XOR_B64));
2060 break;
2061
2062 case AMDGPU::S_XOR_B32_term:
2063 // This is only a terminator to get the correct spill code placement during
2064 // register allocation.
2065 MI.setDesc(get(AMDGPU::S_XOR_B32));
2066 break;
2067 case AMDGPU::S_OR_B64_term:
2068 // This is only a terminator to get the correct spill code placement during
2069 // register allocation.
2070 MI.setDesc(get(AMDGPU::S_OR_B64));
2071 break;
2072 case AMDGPU::S_OR_B32_term:
2073 // This is only a terminator to get the correct spill code placement during
2074 // register allocation.
2075 MI.setDesc(get(AMDGPU::S_OR_B32));
2076 break;
2077
2078 case AMDGPU::S_ANDN2_B64_term:
2079 // This is only a terminator to get the correct spill code placement during
2080 // register allocation.
2081 MI.setDesc(get(AMDGPU::S_ANDN2_B64));
2082 break;
2083
2084 case AMDGPU::S_ANDN2_B32_term:
2085 // This is only a terminator to get the correct spill code placement during
2086 // register allocation.
2087 MI.setDesc(get(AMDGPU::S_ANDN2_B32));
2088 break;
2089
2090 case AMDGPU::S_AND_B64_term:
2091 // This is only a terminator to get the correct spill code placement during
2092 // register allocation.
2093 MI.setDesc(get(AMDGPU::S_AND_B64));
2094 break;
2095
2096 case AMDGPU::S_AND_B32_term:
2097 // This is only a terminator to get the correct spill code placement during
2098 // register allocation.
2099 MI.setDesc(get(AMDGPU::S_AND_B32));
2100 break;
2101
2102 case AMDGPU::S_AND_SAVEEXEC_B64_term:
2103 // This is only a terminator to get the correct spill code placement during
2104 // register allocation.
2105 MI.setDesc(get(AMDGPU::S_AND_SAVEEXEC_B64));
2106 break;
2107
2108 case AMDGPU::S_AND_SAVEEXEC_B32_term:
2109 // This is only a terminator to get the correct spill code placement during
2110 // register allocation.
2111 MI.setDesc(get(AMDGPU::S_AND_SAVEEXEC_B32));
2112 break;
2113
2114 case AMDGPU::V_CMPX_EQ_U32_nosdst_e32_term:
2115 MI.setDesc(get(AMDGPU::V_CMPX_EQ_U32_nosdst_e32));
2116 break;
2117 case AMDGPU::V_CMPX_EQ_U64_nosdst_e32_term:
2118 MI.setDesc(get(AMDGPU::V_CMPX_EQ_U64_nosdst_e32));
2119 break;
2120
2121 case AMDGPU::SI_SPILL_S32_TO_VGPR:
2122 MI.setDesc(get(AMDGPU::V_WRITELANE_B32));
2123 break;
2124
2125 case AMDGPU::SI_RESTORE_S32_FROM_VGPR:
2126 MI.setDesc(get(AMDGPU::V_READLANE_B32));
2127 break;
2128 case AMDGPU::AV_MOV_B32_IMM_PSEUDO: {
2129 Register Dst = MI.getOperand(0).getReg();
2130 bool IsAGPR = SIRegisterInfo::isAGPRClass(RI.getPhysRegBaseClass(Dst));
2131 MI.setDesc(
2132 get(IsAGPR ? AMDGPU::V_ACCVGPR_WRITE_B32_e64 : AMDGPU::V_MOV_B32_e32));
2133 break;
2134 }
2135 case AMDGPU::AV_MOV_B64_IMM_PSEUDO: {
2136 Register Dst = MI.getOperand(0).getReg();
2137 if (SIRegisterInfo::isAGPRClass(RI.getPhysRegBaseClass(Dst))) {
2138 int64_t Imm = MI.getOperand(1).getImm();
2139
2140 Register DstLo = RI.getSubReg(Dst, AMDGPU::sub0);
2141 Register DstHi = RI.getSubReg(Dst, AMDGPU::sub1);
2142 BuildMI(MBB, MI, DL, get(AMDGPU::V_ACCVGPR_WRITE_B32_e64), DstLo)
2144 BuildMI(MBB, MI, DL, get(AMDGPU::V_ACCVGPR_WRITE_B32_e64), DstHi)
2145 .addImm(SignExtend64<32>(Imm >> 32));
2146 MI.eraseFromParent();
2147 break;
2148 }
2149
2150 [[fallthrough]];
2151 }
2152 case AMDGPU::V_MOV_B64_PSEUDO: {
2153 Register Dst = MI.getOperand(0).getReg();
2154 Register DstLo = RI.getSubReg(Dst, AMDGPU::sub0);
2155 Register DstHi = RI.getSubReg(Dst, AMDGPU::sub1);
2156
2157 const MCInstrDesc &Mov64Desc = get(AMDGPU::V_MOV_B64_e32);
2158 const TargetRegisterClass *Mov64RC = getRegClass(Mov64Desc, /*OpNum=*/0);
2159
2160 const MachineOperand &SrcOp = MI.getOperand(1);
2161 // FIXME: Will this work for 64-bit floating point immediates?
2162 assert(!SrcOp.isFPImm());
2163 if (ST.hasVMovB64Inst() && Mov64RC->contains(Dst)) {
2164 MI.setDesc(Mov64Desc);
2165 if (SrcOp.isReg() || isInlineConstant(MI, 1) ||
2166 (SrcOp.isImm() &&
2167 (isUInt<32>(SrcOp.getImm()) || ST.has64BitLiterals())) ||
2168 (SrcOp.isGlobal() && ST.has64BitLiterals()))
2169 break;
2170 }
2171 if (SrcOp.isGlobal()) {
2172 // The address is unknown until link time, so the PK_MOV inline-constant
2173 // shortcut cannot apply.
2174 const GlobalValue *GV = SrcOp.getGlobal();
2175 int64_t Offset = SrcOp.getOffset();
2176 unsigned BaseFlags, LoReloc, HiReloc;
2177 std::tie(BaseFlags, LoReloc, HiReloc) =
2179
2180 BuildMI(MBB, MI, DL, get(AMDGPU::V_MOV_B32_e32), DstLo)
2181 .addGlobalAddress(GV, Offset, BaseFlags | LoReloc);
2182 BuildMI(MBB, MI, DL, get(AMDGPU::V_MOV_B32_e32), DstHi)
2183 .addGlobalAddress(GV, Offset, BaseFlags | HiReloc);
2184 } else if (SrcOp.isImm()) {
2185 APInt Imm(64, SrcOp.getImm());
2186 APInt Lo(32, Imm.getLoBits(32).getZExtValue());
2187 APInt Hi(32, Imm.getHiBits(32).getZExtValue());
2188 const MCInstrDesc &PkMovDesc = get(AMDGPU::V_PK_MOV_B32);
2189 const TargetRegisterClass *PkMovRC = getRegClass(PkMovDesc, /*OpNum=*/0);
2190
2191 if (ST.hasPkMovB32() && Lo == Hi && isInlineConstant(Lo) &&
2192 PkMovRC->contains(Dst)) {
2193 BuildMI(MBB, MI, DL, PkMovDesc, Dst)
2195 .addImm(Lo.getSExtValue())
2197 .addImm(Lo.getSExtValue())
2198 .addImm(0) // op_sel_lo
2199 .addImm(0) // op_sel_hi
2200 .addImm(0) // neg_lo
2201 .addImm(0) // neg_hi
2202 .addImm(0); // clamp
2203 } else {
2204 BuildMI(MBB, MI, DL, get(AMDGPU::V_MOV_B32_e32), DstLo)
2205 .addImm(Lo.getSExtValue());
2206 BuildMI(MBB, MI, DL, get(AMDGPU::V_MOV_B32_e32), DstHi)
2207 .addImm(Hi.getSExtValue());
2208 }
2209 } else {
2210 assert(SrcOp.isReg());
2211 if (ST.hasPkMovB32() &&
2212 !RI.isAGPR(MBB.getParent()->getRegInfo(), SrcOp.getReg())) {
2213 BuildMI(MBB, MI, DL, get(AMDGPU::V_PK_MOV_B32), Dst)
2214 .addImm(SISrcMods::OP_SEL_1) // src0_mod
2215 .addReg(SrcOp.getReg())
2217 .addReg(SrcOp.getReg())
2218 .addImm(0) // op_sel_lo
2219 .addImm(0) // op_sel_hi
2220 .addImm(0) // neg_lo
2221 .addImm(0) // neg_hi
2222 .addImm(0); // clamp
2223 } else {
2224 BuildMI(MBB, MI, DL, get(AMDGPU::V_MOV_B32_e32), DstLo)
2225 .addReg(RI.getSubReg(SrcOp.getReg(), AMDGPU::sub0));
2226 BuildMI(MBB, MI, DL, get(AMDGPU::V_MOV_B32_e32), DstHi)
2227 .addReg(RI.getSubReg(SrcOp.getReg(), AMDGPU::sub1));
2228 }
2229 }
2230 MI.eraseFromParent();
2231 break;
2232 }
2233 case AMDGPU::V_MOV_B64_DPP_PSEUDO: {
2235 break;
2236 }
2237 case AMDGPU::S_MOV_B64_IMM_PSEUDO: {
2238 const MachineOperand &SrcOp = MI.getOperand(1);
2239 assert(!SrcOp.isFPImm());
2240
2241 if (ST.has64BitLiterals()) {
2242 MI.setDesc(get(AMDGPU::S_MOV_B64));
2243 break;
2244 }
2245
2246 if (SrcOp.isGlobal()) {
2247 Register Dst = MI.getOperand(0).getReg();
2248 Register DstLo = RI.getSubReg(Dst, AMDGPU::sub0);
2249 Register DstHi = RI.getSubReg(Dst, AMDGPU::sub1);
2250 const GlobalValue *GV = SrcOp.getGlobal();
2251 int64_t Offset = SrcOp.getOffset();
2252 unsigned BaseFlags, LoReloc, HiReloc;
2253 std::tie(BaseFlags, LoReloc, HiReloc) =
2255
2256 BuildMI(MBB, MI, DL, get(AMDGPU::S_MOV_B32), DstLo)
2257 .addGlobalAddress(GV, Offset, BaseFlags | LoReloc);
2258 BuildMI(MBB, MI, DL, get(AMDGPU::S_MOV_B32), DstHi)
2259 .addGlobalAddress(GV, Offset, BaseFlags | HiReloc);
2260 MI.eraseFromParent();
2261 break;
2262 }
2263
2264 // SrcOp is immediate
2265 APInt Imm(64, SrcOp.getImm());
2266 if (Imm.isIntN(32) || isInlineConstant(Imm)) {
2267 MI.setDesc(get(AMDGPU::S_MOV_B64));
2268 break;
2269 }
2270
2271 Register Dst = MI.getOperand(0).getReg();
2272 Register DstLo = RI.getSubReg(Dst, AMDGPU::sub0);
2273 Register DstHi = RI.getSubReg(Dst, AMDGPU::sub1);
2274
2275 APInt Lo(32, Imm.getLoBits(32).getZExtValue());
2276 APInt Hi(32, Imm.getHiBits(32).getZExtValue());
2277 BuildMI(MBB, MI, DL, get(AMDGPU::S_MOV_B32), DstLo)
2278 .addImm(Lo.getSExtValue());
2279 BuildMI(MBB, MI, DL, get(AMDGPU::S_MOV_B32), DstHi)
2280 .addImm(Hi.getSExtValue());
2281 MI.eraseFromParent();
2282 break;
2283 }
2284 case AMDGPU::V_SET_INACTIVE_B32: {
2285 // Lower V_SET_INACTIVE_B32 to V_CNDMASK_B32.
2286 Register DstReg = MI.getOperand(0).getReg();
2287 BuildMI(MBB, MI, DL, get(AMDGPU::V_CNDMASK_B32_e64), DstReg)
2288 .add(MI.getOperand(3))
2289 .add(MI.getOperand(4))
2290 .add(MI.getOperand(1))
2291 .add(MI.getOperand(2))
2292 .add(MI.getOperand(5));
2293 MI.eraseFromParent();
2294 break;
2295 }
2296 case AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V1:
2297 case AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V2:
2298 case AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V3:
2299 case AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V4:
2300 case AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V5:
2301 case AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V6:
2302 case AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V7:
2303 case AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V8:
2304 case AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V9:
2305 case AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V10:
2306 case AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V11:
2307 case AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V12:
2308 case AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V16:
2309 case AMDGPU::V_INDIRECT_REG_WRITE_MOVREL_B32_V32:
2310 case AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V1:
2311 case AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V2:
2312 case AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V3:
2313 case AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V4:
2314 case AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V5:
2315 case AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V6:
2316 case AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V7:
2317 case AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V8:
2318 case AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V9:
2319 case AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V10:
2320 case AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V11:
2321 case AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V12:
2322 case AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V16:
2323 case AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B32_V32:
2324 case AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B64_V1:
2325 case AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B64_V2:
2326 case AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B64_V4:
2327 case AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B64_V8:
2328 case AMDGPU::S_INDIRECT_REG_WRITE_MOVREL_B64_V16: {
2329 const TargetRegisterClass *EltRC = getOpRegClass(MI, 2);
2330
2331 unsigned Opc;
2332 if (RI.hasVGPRs(EltRC)) {
2333 Opc = AMDGPU::V_MOVRELD_B32_e32;
2334 } else {
2335 Opc = RI.getRegSizeInBits(*EltRC) == 64 ? AMDGPU::S_MOVRELD_B64
2336 : AMDGPU::S_MOVRELD_B32;
2337 }
2338
2339 const MCInstrDesc &OpDesc = get(Opc);
2340 Register VecReg = MI.getOperand(0).getReg();
2341 bool IsUndef = MI.getOperand(1).isUndef();
2342 unsigned SubReg = MI.getOperand(3).getImm();
2343 assert(VecReg == MI.getOperand(1).getReg());
2344
2346 BuildMI(MBB, MI, DL, OpDesc)
2347 .addReg(RI.getSubReg(VecReg, SubReg), RegState::Undef)
2348 .add(MI.getOperand(2))
2350 .addReg(VecReg, RegState::Implicit | getUndefRegState(IsUndef));
2351
2352 const int ImpDefIdx =
2353 OpDesc.getNumOperands() + OpDesc.implicit_uses().size();
2354 const int ImpUseIdx = ImpDefIdx + 1;
2355 MIB->tieOperands(ImpDefIdx, ImpUseIdx);
2356 MI.eraseFromParent();
2357 break;
2358 }
2359 case AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V1:
2360 case AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V2:
2361 case AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V3:
2362 case AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V4:
2363 case AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V5:
2364 case AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V6:
2365 case AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V7:
2366 case AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V8:
2367 case AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V9:
2368 case AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V10:
2369 case AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V11:
2370 case AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V12:
2371 case AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V16:
2372 case AMDGPU::V_INDIRECT_REG_WRITE_GPR_IDX_B32_V32: {
2373 assert(ST.useVGPRIndexMode());
2374 Register VecReg = MI.getOperand(0).getReg();
2375 bool IsUndef = MI.getOperand(1).isUndef();
2376 MachineOperand &Idx = MI.getOperand(3);
2377 Register SubReg = MI.getOperand(4).getImm();
2378
2379 MachineInstr *SetOn = BuildMI(MBB, MI, DL, get(AMDGPU::S_SET_GPR_IDX_ON))
2380 .add(Idx)
2382 SetOn->getOperand(3).setIsUndef();
2383
2384 const MCInstrDesc &OpDesc = get(AMDGPU::V_MOV_B32_indirect_write);
2386 BuildMI(MBB, MI, DL, OpDesc)
2387 .addReg(RI.getSubReg(VecReg, SubReg), RegState::Undef)
2388 .add(MI.getOperand(2))
2390 .addReg(VecReg, RegState::Implicit | getUndefRegState(IsUndef));
2391
2392 const int ImpDefIdx =
2393 OpDesc.getNumOperands() + OpDesc.implicit_uses().size();
2394 const int ImpUseIdx = ImpDefIdx + 1;
2395 MIB->tieOperands(ImpDefIdx, ImpUseIdx);
2396
2397 MachineInstr *SetOff = BuildMI(MBB, MI, DL, get(AMDGPU::S_SET_GPR_IDX_OFF));
2398
2399 finalizeBundle(MBB, SetOn->getIterator(), std::next(SetOff->getIterator()));
2400
2401 MI.eraseFromParent();
2402 break;
2403 }
2404 case AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V1:
2405 case AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V2:
2406 case AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V3:
2407 case AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V4:
2408 case AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V5:
2409 case AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V6:
2410 case AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V7:
2411 case AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V8:
2412 case AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V9:
2413 case AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V10:
2414 case AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V11:
2415 case AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V12:
2416 case AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V16:
2417 case AMDGPU::V_INDIRECT_REG_READ_GPR_IDX_B32_V32: {
2418 assert(ST.useVGPRIndexMode());
2419 Register Dst = MI.getOperand(0).getReg();
2420 Register VecReg = MI.getOperand(1).getReg();
2421 bool IsUndef = MI.getOperand(1).isUndef();
2422 Register SubReg = MI.getOperand(3).getImm();
2423
2424 MachineInstr *SetOn = BuildMI(MBB, MI, DL, get(AMDGPU::S_SET_GPR_IDX_ON))
2425 .add(MI.getOperand(2))
2427 SetOn->getOperand(3).setIsUndef();
2428
2429 BuildMI(MBB, MI, DL, get(AMDGPU::V_MOV_B32_indirect_read))
2430 .addDef(Dst)
2431 .addReg(RI.getSubReg(VecReg, SubReg), RegState::Undef)
2432 .addReg(VecReg, RegState::Implicit | getUndefRegState(IsUndef));
2433
2434 MachineInstr *SetOff = BuildMI(MBB, MI, DL, get(AMDGPU::S_SET_GPR_IDX_OFF));
2435
2436 finalizeBundle(MBB, SetOn->getIterator(), std::next(SetOff->getIterator()));
2437
2438 MI.eraseFromParent();
2439 break;
2440 }
2441 case AMDGPU::SI_PC_ADD_REL_OFFSET: {
2442 MachineFunction &MF = *MBB.getParent();
2443 Register Reg = MI.getOperand(0).getReg();
2444 Register RegLo = RI.getSubReg(Reg, AMDGPU::sub0);
2445 Register RegHi = RI.getSubReg(Reg, AMDGPU::sub1);
2446 MachineOperand OpLo = MI.getOperand(1);
2447 MachineOperand OpHi = MI.getOperand(2);
2448
2449 // Create a bundle so these instructions won't be re-ordered by the
2450 // post-RA scheduler.
2451 MIBundleBuilder Bundler(MBB, MI);
2452 Bundler.append(BuildMI(MF, DL, get(AMDGPU::S_GETPC_B64), Reg));
2453
2454 // What we want here is an offset from the value returned by s_getpc (which
2455 // is the address of the s_add_u32 instruction) to the global variable, but
2456 // since the encoding of $symbol starts 4 bytes after the start of the
2457 // s_add_u32 instruction, we end up with an offset that is 4 bytes too
2458 // small. This requires us to add 4 to the global variable offset in order
2459 // to compute the correct address. Similarly for the s_addc_u32 instruction,
2460 // the encoding of $symbol starts 12 bytes after the start of the s_add_u32
2461 // instruction.
2462
2463 int64_t Adjust = 0;
2464 if (ST.hasGetPCZeroExtension()) {
2465 // Fix up hardware that does not sign-extend the 48-bit PC value by
2466 // inserting: s_sext_i32_i16 reghi, reghi
2467 Bundler.append(
2468 BuildMI(MF, DL, get(AMDGPU::S_SEXT_I32_I16), RegHi).addReg(RegHi));
2469 Adjust += 4;
2470 }
2471
2472 if (OpLo.isGlobal())
2473 OpLo.setOffset(OpLo.getOffset() + Adjust + 4);
2474 Bundler.append(
2475 BuildMI(MF, DL, get(AMDGPU::S_ADD_U32), RegLo).addReg(RegLo).add(OpLo));
2476
2477 if (OpHi.isGlobal())
2478 OpHi.setOffset(OpHi.getOffset() + Adjust + 12);
2479 Bundler.append(BuildMI(MF, DL, get(AMDGPU::S_ADDC_U32), RegHi)
2480 .addReg(RegHi)
2481 .add(OpHi));
2482
2483 finalizeBundle(MBB, Bundler.begin());
2484
2485 MI.eraseFromParent();
2486 break;
2487 }
2488 case AMDGPU::SI_PC_ADD_REL_OFFSET64: {
2489 MachineFunction &MF = *MBB.getParent();
2490 Register Reg = MI.getOperand(0).getReg();
2491 MachineOperand Op = MI.getOperand(1);
2492
2493 // Create a bundle so these instructions won't be re-ordered by the
2494 // post-RA scheduler.
2495 MIBundleBuilder Bundler(MBB, MI);
2496 Bundler.append(BuildMI(MF, DL, get(AMDGPU::S_GETPC_B64), Reg));
2497 if (Op.isGlobal())
2498 Op.setOffset(Op.getOffset() + 4);
2499 Bundler.append(
2500 BuildMI(MF, DL, get(AMDGPU::S_ADD_U64), Reg).addReg(Reg).add(Op));
2501
2502 finalizeBundle(MBB, Bundler.begin());
2503
2504 MI.eraseFromParent();
2505 break;
2506 }
2507 case AMDGPU::ENTER_STRICT_WWM: {
2508 // This only gets its own opcode so that SIPreAllocateWWMRegs can tell when
2509 // Whole Wave Mode is entered.
2510 MI.setDesc(get(LMC.OrSaveExecOpc));
2511 break;
2512 }
2513 case AMDGPU::ENTER_STRICT_WQM: {
2514 // This only gets its own opcode so that SIPreAllocateWWMRegs can tell when
2515 // STRICT_WQM is entered.
2516 BuildMI(MBB, MI, DL, get(LMC.MovOpc), MI.getOperand(0).getReg())
2517 .addReg(LMC.ExecReg);
2518 BuildMI(MBB, MI, DL, get(LMC.WQMOpc), LMC.ExecReg).addReg(LMC.ExecReg);
2519
2520 MI.eraseFromParent();
2521 break;
2522 }
2523 case AMDGPU::EXIT_STRICT_WWM:
2524 case AMDGPU::EXIT_STRICT_WQM: {
2525 // This only gets its own opcode so that SIPreAllocateWWMRegs can tell when
2526 // WWM/STICT_WQM is exited.
2527 MI.setDesc(get(LMC.MovOpc));
2528 break;
2529 }
2530 case AMDGPU::SI_RETURN: {
2531 const MachineFunction *MF = MBB.getParent();
2532 const GCNSubtarget &ST = MF->getSubtarget<GCNSubtarget>();
2533 const SIRegisterInfo *TRI = ST.getRegisterInfo();
2534 // Hiding the return address use with SI_RETURN may lead to extra kills in
2535 // the function and missing live-ins. We are fine in practice because callee
2536 // saved register handling ensures the register value is restored before
2537 // RET, but we need the undef flag here to appease the MachineVerifier
2538 // liveness checks.
2540 BuildMI(MBB, MI, DL, get(AMDGPU::S_SETPC_B64_return))
2541 .addReg(TRI->getReturnAddressReg(*MF), RegState::Undef);
2542
2543 MIB.copyImplicitOps(MI);
2544 MI.eraseFromParent();
2545 break;
2546 }
2547
2548 case AMDGPU::S_MUL_U64_U32_PSEUDO:
2549 case AMDGPU::S_MUL_I64_I32_PSEUDO:
2550 MI.setDesc(get(AMDGPU::S_MUL_U64));
2551 break;
2552
2553 case AMDGPU::S_GETPC_B64_pseudo:
2554 MI.setDesc(get(AMDGPU::S_GETPC_B64));
2555 if (ST.hasGetPCZeroExtension()) {
2556 Register Dst = MI.getOperand(0).getReg();
2557 Register DstHi = RI.getSubReg(Dst, AMDGPU::sub1);
2558 // Fix up hardware that does not sign-extend the 48-bit PC value by
2559 // inserting: s_sext_i32_i16 dsthi, dsthi
2560 BuildMI(MBB, std::next(MI.getIterator()), DL, get(AMDGPU::S_SEXT_I32_I16),
2561 DstHi)
2562 .addReg(DstHi);
2563 }
2564 break;
2565
2566 case AMDGPU::V_MAX_BF16_PSEUDO_e64: {
2567 assert(ST.hasBF16PackedInsts());
2568 MI.setDesc(get(AMDGPU::V_PK_MAX_NUM_BF16));
2569 MI.addOperand(MachineOperand::CreateImm(0)); // op_sel
2570 MI.addOperand(MachineOperand::CreateImm(0)); // neg_lo
2571 MI.addOperand(MachineOperand::CreateImm(0)); // neg_hi
2572 auto Op0 = getNamedOperand(MI, AMDGPU::OpName::src0_modifiers);
2573 Op0->setImm(Op0->getImm() | SISrcMods::OP_SEL_1);
2574 auto Op1 = getNamedOperand(MI, AMDGPU::OpName::src1_modifiers);
2575 Op1->setImm(Op1->getImm() | SISrcMods::OP_SEL_1);
2576 break;
2577 }
2578
2579 case AMDGPU::GET_STACK_BASE:
2580 // The stack starts at offset 0 unless we need to reserve some space at the
2581 // bottom.
2582 if (ST.getFrameLowering()->mayReserveScratchForCWSR(*MBB.getParent())) {
2583 // When CWSR is used in dynamic VGPR mode, the trap handler needs to save
2584 // some of the VGPRs. The size of the required scratch space has already
2585 // been computed by prolog epilog insertion.
2586 const SIMachineFunctionInfo *MFI =
2587 MBB.getParent()->getInfo<SIMachineFunctionInfo>();
2588 unsigned VGPRSize = MFI->getScratchReservedForDynamicVGPRs();
2589 Register DestReg = MI.getOperand(0).getReg();
2590 BuildMI(MBB, MI, DL, get(AMDGPU::S_GETREG_B32), DestReg)
2593 // The MicroEngine ID is 0 for the graphics queue, and 1 or 2 for compute
2594 // (3 is unused, so we ignore it). Unfortunately, S_GETREG doesn't set
2595 // SCC, so we need to check for 0 manually.
2596 BuildMI(MBB, MI, DL, get(AMDGPU::S_CMP_LG_U32)).addImm(0).addReg(DestReg);
2597 // Change the implicif-def of SCC to an explicit use (but first remove
2598 // the dead flag if present).
2599 MI.getOperand(MI.getNumExplicitOperands()).setIsDead(false);
2600 MI.getOperand(MI.getNumExplicitOperands()).setIsUse();
2601 MI.setDesc(get(AMDGPU::S_CMOVK_I32));
2602 MI.addOperand(MachineOperand::CreateImm(VGPRSize));
2603 } else {
2604 MI.setDesc(get(AMDGPU::S_MOV_B32));
2605 MI.addOperand(MachineOperand::CreateImm(0));
2606 MI.removeOperand(
2607 MI.getNumExplicitOperands()); // Drop implicit def of SCC.
2608 }
2609 break;
2610 }
2611
2612 return true;
2613}
2614
2617 unsigned SubIdx, const MachineInstr &Orig,
2618 LaneBitmask UsedLanes) const {
2619
2620 // Try shrinking the instruction to remat only the part needed for current
2621 // context.
2622 // TODO: Handle more cases.
2623 unsigned Opcode = Orig.getOpcode();
2624 switch (Opcode) {
2625 case AMDGPU::S_MOV_B64:
2626 case AMDGPU::S_MOV_B64_IMM_PSEUDO: {
2627 if (SubIdx != 0)
2628 break;
2629
2630 if (!Orig.getOperand(1).isImm())
2631 break;
2632
2633 // Shrink S_MOV_B64 to S_MOV_B32 when UsedLanes indicates only a single
2634 // 32-bit lane of the 64-bit value is live at the rematerialization point.
2635 if (UsedLanes.all())
2636 break;
2637
2638 // Determine which half of the 64-bit immediate corresponds to the use.
2639 unsigned OrigSubReg = Orig.getOperand(0).getSubReg();
2640 unsigned LoSubReg = RI.composeSubRegIndices(OrigSubReg, AMDGPU::sub0);
2641 unsigned HiSubReg = RI.composeSubRegIndices(OrigSubReg, AMDGPU::sub1);
2642
2643 bool NeedLo = (UsedLanes & RI.getSubRegIndexLaneMask(LoSubReg)).any();
2644 bool NeedHi = (UsedLanes & RI.getSubRegIndexLaneMask(HiSubReg)).any();
2645
2646 if (NeedLo && NeedHi)
2647 break;
2648
2649 int64_t Imm64 = Orig.getOperand(1).getImm();
2650 int32_t Imm32 = NeedLo ? Lo_32(Imm64) : Hi_32(Imm64);
2651
2652 unsigned UseSubReg = NeedLo ? LoSubReg : HiSubReg;
2653
2654 // Emit S_MOV_B32 defining just the needed 32-bit subreg of DestReg.
2655 BuildMI(MBB, I, Orig.getDebugLoc(), get(AMDGPU::S_MOV_B32))
2656 .addReg(DestReg, RegState::Define | RegState::Undef, UseSubReg)
2657 .addImm(Imm32);
2658 return;
2659 }
2660
2661 case AMDGPU::S_LOAD_DWORDX16_IMM:
2662 case AMDGPU::S_LOAD_DWORDX8_IMM: {
2663 if (SubIdx != 0)
2664 break;
2665
2666 if (I == MBB.end())
2667 break;
2668
2669 if (I->isBundled())
2670 break;
2671
2672 // Look for a single use of the register that is also a subreg.
2673 Register RegToFind = Orig.getOperand(0).getReg();
2674 MachineOperand *UseMO = nullptr;
2675 for (auto &CandMO : I->operands()) {
2676 if (!CandMO.isReg() || CandMO.getReg() != RegToFind || CandMO.isDef())
2677 continue;
2678 if (UseMO) {
2679 UseMO = nullptr;
2680 break;
2681 }
2682 UseMO = &CandMO;
2683 }
2684 if (!UseMO || UseMO->getSubReg() == AMDGPU::NoSubRegister)
2685 break;
2686
2687 unsigned Offset = RI.getSubRegIdxOffset(UseMO->getSubReg());
2688 unsigned SubregSize = RI.getSubRegIdxSize(UseMO->getSubReg());
2689
2690 MachineFunction *MF = MBB.getParent();
2691 MachineRegisterInfo &MRI = MF->getRegInfo();
2692 assert(MRI.use_nodbg_empty(DestReg) && "DestReg should have no users yet.");
2693
2694 unsigned NewOpcode = -1;
2695 if (SubregSize == 256)
2696 NewOpcode = AMDGPU::S_LOAD_DWORDX8_IMM;
2697 else if (SubregSize == 128)
2698 NewOpcode = AMDGPU::S_LOAD_DWORDX4_IMM;
2699 else
2700 break;
2701
2702 const MCInstrDesc &TID = get(NewOpcode);
2703 const TargetRegisterClass *NewRC =
2704 RI.getAllocatableClass(getRegClass(TID, 0));
2705 MRI.setRegClass(DestReg, NewRC);
2706
2707 UseMO->setReg(DestReg);
2708 UseMO->setSubReg(AMDGPU::NoSubRegister);
2709
2710 // Use a smaller load with the desired size, possibly with updated offset.
2711 MachineInstr *MI = MF->CloneMachineInstr(&Orig);
2712 MI->setDesc(TID);
2713 MI->getOperand(0).setReg(DestReg);
2714 MI->getOperand(0).setSubReg(AMDGPU::NoSubRegister);
2715 if (Offset) {
2716 MachineOperand *OffsetMO = getNamedOperand(*MI, AMDGPU::OpName::offset);
2717 int64_t FinalOffset = OffsetMO->getImm() + Offset / 8;
2718 OffsetMO->setImm(FinalOffset);
2719 }
2721 for (const MachineMemOperand *MemOp : Orig.memoperands())
2722 NewMMOs.push_back(MF->getMachineMemOperand(MemOp, MemOp->getPointerInfo(),
2723 SubregSize / 8));
2724 MI->setMemRefs(*MF, NewMMOs);
2725
2726 MBB.insert(I, MI);
2727 return;
2728 }
2729
2730 default:
2731 break;
2732 }
2733
2734 TargetInstrInfo::reMaterialize(MBB, I, DestReg, SubIdx, Orig, UsedLanes);
2735}
2736
2737std::pair<MachineInstr*, MachineInstr*>
2739 assert (MI.getOpcode() == AMDGPU::V_MOV_B64_DPP_PSEUDO);
2740
2741 if (ST.hasVMovB64Inst() && ST.hasFeature(AMDGPU::FeatureDPALU_DPP) &&
2743 ST, getNamedOperand(MI, AMDGPU::OpName::dpp_ctrl)->getImm())) {
2744 MI.setDesc(get(AMDGPU::V_MOV_B64_dpp));
2745 return std::pair(&MI, nullptr);
2746 }
2747
2748 MachineBasicBlock &MBB = *MI.getParent();
2749 DebugLoc DL = MBB.findDebugLoc(MI);
2750 MachineFunction *MF = MBB.getParent();
2751 MachineRegisterInfo &MRI = MF->getRegInfo();
2752 Register Dst = MI.getOperand(0).getReg();
2753 unsigned Part = 0;
2754 MachineInstr *Split[2];
2755
2756 for (auto Sub : { AMDGPU::sub0, AMDGPU::sub1 }) {
2757 auto MovDPP = BuildMI(MBB, MI, DL, get(AMDGPU::V_MOV_B32_dpp));
2758 if (Dst.isPhysical()) {
2759 MovDPP.addDef(RI.getSubReg(Dst, Sub));
2760 } else {
2761 assert(MRI.isSSA());
2762 auto Tmp = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
2763 MovDPP.addDef(Tmp);
2764 }
2765
2766 for (unsigned I = 1; I <= 2; ++I) { // old and src operands.
2767 const MachineOperand &SrcOp = MI.getOperand(I);
2768 assert(!SrcOp.isFPImm());
2769 if (SrcOp.isImm()) {
2770 APInt Imm(64, SrcOp.getImm());
2771 Imm.ashrInPlace(Part * 32);
2772 MovDPP.addImm(Imm.getLoBits(32).getZExtValue());
2773 } else {
2774 assert(SrcOp.isReg());
2775 Register Src = SrcOp.getReg();
2776 if (Src.isPhysical())
2777 MovDPP.addReg(RI.getSubReg(Src, Sub));
2778 else
2779 MovDPP.addReg(Src, getUndefRegState(SrcOp.isUndef()), Sub);
2780 }
2781 }
2782
2783 for (const MachineOperand &MO : llvm::drop_begin(MI.explicit_operands(), 3))
2784 MovDPP.addImm(MO.getImm());
2785
2786 Split[Part] = MovDPP;
2787 ++Part;
2788 }
2789
2790 if (Dst.isVirtual())
2791 BuildMI(MBB, MI, DL, get(AMDGPU::REG_SEQUENCE), Dst)
2792 .addReg(Split[0]->getOperand(0).getReg())
2793 .addImm(AMDGPU::sub0)
2794 .addReg(Split[1]->getOperand(0).getReg())
2795 .addImm(AMDGPU::sub1);
2796
2797 MI.eraseFromParent();
2798 return std::pair(Split[0], Split[1]);
2799}
2800
2801std::optional<DestSourcePair>
2803 if (MI.getOpcode() == AMDGPU::WWM_COPY)
2804 return DestSourcePair{MI.getOperand(0), MI.getOperand(1)};
2805
2806 return std::nullopt;
2807}
2808
2810 AMDGPU::OpName Src0OpName,
2811 MachineOperand &Src1,
2812 AMDGPU::OpName Src1OpName) const {
2813 MachineOperand *Src0Mods = getNamedOperand(MI, Src0OpName);
2814 if (!Src0Mods)
2815 return false;
2816
2817 MachineOperand *Src1Mods = getNamedOperand(MI, Src1OpName);
2818 assert(Src1Mods &&
2819 "All commutable instructions have both src0 and src1 modifiers");
2820
2821 int Src0ModsVal = Src0Mods->getImm();
2822 int Src1ModsVal = Src1Mods->getImm();
2823
2824 Src1Mods->setImm(Src0ModsVal);
2825 Src0Mods->setImm(Src1ModsVal);
2826 return true;
2827}
2828
2830 MachineOperand &RegOp,
2831 MachineOperand &NonRegOp) {
2832 Register Reg = RegOp.getReg();
2833 unsigned SubReg = RegOp.getSubReg();
2834 bool IsKill = RegOp.isKill();
2835 bool IsDead = RegOp.isDead();
2836 bool IsUndef = RegOp.isUndef();
2837 bool IsDebug = RegOp.isDebug();
2838
2839 if (NonRegOp.isImm())
2840 RegOp.ChangeToImmediate(NonRegOp.getImm());
2841 else if (NonRegOp.isFI())
2842 RegOp.ChangeToFrameIndex(NonRegOp.getIndex());
2843 else if (NonRegOp.isGlobal()) {
2844 RegOp.ChangeToGA(NonRegOp.getGlobal(), NonRegOp.getOffset(),
2845 NonRegOp.getTargetFlags());
2846 } else
2847 return nullptr;
2848
2849 // Make sure we don't reinterpret a subreg index in the target flags.
2850 RegOp.setTargetFlags(NonRegOp.getTargetFlags());
2851
2852 NonRegOp.ChangeToRegister(Reg, false, false, IsKill, IsDead, IsUndef, IsDebug);
2853 NonRegOp.setSubReg(SubReg);
2854
2855 return &MI;
2856}
2857
2859 MachineOperand &NonRegOp1,
2860 MachineOperand &NonRegOp2) {
2861 unsigned TargetFlags = NonRegOp1.getTargetFlags();
2862 int64_t NonRegVal = NonRegOp1.getImm();
2863
2864 NonRegOp1.setImm(NonRegOp2.getImm());
2865 NonRegOp2.setImm(NonRegVal);
2866 NonRegOp1.setTargetFlags(NonRegOp2.getTargetFlags());
2867 NonRegOp2.setTargetFlags(TargetFlags);
2868 return &MI;
2869}
2870
2871bool SIInstrInfo::isLegalToSwap(const MachineInstr &MI, unsigned OpIdx0,
2872 unsigned OpIdx1) const {
2873 const MCInstrDesc &InstDesc = MI.getDesc();
2874 const MCOperandInfo &OpInfo0 = InstDesc.operands()[OpIdx0];
2875 const MCOperandInfo &OpInfo1 = InstDesc.operands()[OpIdx1];
2876
2877 unsigned Opc = MI.getOpcode();
2878 int Src0Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0);
2879
2880 const MachineOperand &MO0 = MI.getOperand(OpIdx0);
2881 const MachineOperand &MO1 = MI.getOperand(OpIdx1);
2882
2883 // Swap doesn't breach constant bus or literal limits
2884 // It may move literal to position other than src0, this is not allowed
2885 // pre-gfx10 However, most test cases need literals in Src0 for VOP
2886 // FIXME: After gfx9, literal can be in place other than Src0
2887 if (isVALU(MI, /*AllowLDSDMA=*/true)) {
2888 if ((int)OpIdx0 == Src0Idx && !MO0.isReg() &&
2889 !isInlineConstant(MO0, OpInfo1))
2890 return false;
2891 if ((int)OpIdx1 == Src0Idx && !MO1.isReg() &&
2892 !isInlineConstant(MO1, OpInfo0))
2893 return false;
2894 }
2895
2896 if ((int)OpIdx1 != Src0Idx && MO0.isReg()) {
2897 if (OpInfo1.RegClass == -1)
2898 return OpInfo1.OperandType == MCOI::OPERAND_UNKNOWN;
2899 return isLegalRegOperand(MI, OpIdx1, MO0) &&
2900 (!MO1.isReg() || isLegalRegOperand(MI, OpIdx0, MO1));
2901 }
2902 if ((int)OpIdx0 != Src0Idx && MO1.isReg()) {
2903 if (OpInfo0.RegClass == -1)
2904 return OpInfo0.OperandType == MCOI::OPERAND_UNKNOWN;
2905 return (!MO0.isReg() || isLegalRegOperand(MI, OpIdx1, MO0)) &&
2906 isLegalRegOperand(MI, OpIdx0, MO1);
2907 }
2908
2909 // No need to check 64-bit literals since swapping does not bring new
2910 // 64-bit literals into current instruction to fold to 32-bit
2911
2912 return isImmOperandLegal(MI, OpIdx1, MO0);
2913}
2914
2916 unsigned Src0Idx,
2917 unsigned Src1Idx) const {
2918 assert(!NewMI && "this should never be used");
2919
2920 unsigned Opc = MI.getOpcode();
2921 int CommutedOpcode = commuteOpcode(Opc);
2922 if (CommutedOpcode == -1)
2923 return nullptr;
2924
2925 if (Src0Idx > Src1Idx)
2926 std::swap(Src0Idx, Src1Idx);
2927
2928 assert(AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0) ==
2929 static_cast<int>(Src0Idx) &&
2930 AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src1) ==
2931 static_cast<int>(Src1Idx) &&
2932 "inconsistency with findCommutedOpIndices");
2933
2934 if (!isLegalToSwap(MI, Src0Idx, Src1Idx))
2935 return nullptr;
2936
2937 MachineInstr *CommutedMI = nullptr;
2938 MachineOperand &Src0 = MI.getOperand(Src0Idx);
2939 MachineOperand &Src1 = MI.getOperand(Src1Idx);
2940 if (Src0.isReg() && Src1.isReg()) {
2941 // Be sure to copy the source modifiers to the right place.
2942 CommutedMI =
2943 TargetInstrInfo::commuteInstructionImpl(MI, NewMI, Src0Idx, Src1Idx);
2944 } else if (Src0.isReg() && !Src1.isReg()) {
2945 CommutedMI = swapRegAndNonRegOperand(MI, Src0, Src1);
2946 } else if (!Src0.isReg() && Src1.isReg()) {
2947 CommutedMI = swapRegAndNonRegOperand(MI, Src1, Src0);
2948 } else if (Src0.isImm() && Src1.isImm()) {
2949 CommutedMI = swapImmOperands(MI, Src0, Src1);
2950 } else {
2951 // FIXME: Found two non registers to commute. This does happen.
2952 return nullptr;
2953 }
2954
2955 if (CommutedMI) {
2956 swapSourceModifiers(MI, Src0, AMDGPU::OpName::src0_modifiers,
2957 Src1, AMDGPU::OpName::src1_modifiers);
2958
2959 swapSourceModifiers(MI, Src0, AMDGPU::OpName::src0_sel, Src1,
2960 AMDGPU::OpName::src1_sel);
2961
2962 CommutedMI->setDesc(get(CommutedOpcode));
2963 }
2964
2965 return CommutedMI;
2966}
2967
2968// This needs to be implemented because the source modifiers may be inserted
2969// between the true commutable operands, and the base
2970// TargetInstrInfo::commuteInstruction uses it.
2972 unsigned &SrcOpIdx0,
2973 unsigned &SrcOpIdx1) const {
2974 return findCommutedOpIndices(MI.getDesc(), SrcOpIdx0, SrcOpIdx1);
2975}
2976
2978 unsigned &SrcOpIdx0,
2979 unsigned &SrcOpIdx1) const {
2980 if (!Desc.isCommutable())
2981 return false;
2982
2983 unsigned Opc = Desc.getOpcode();
2984 int Src0Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0);
2985 if (Src0Idx == -1)
2986 return false;
2987
2988 int Src1Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src1);
2989 if (Src1Idx == -1)
2990 return false;
2991
2992 return fixCommutedOpIndices(SrcOpIdx0, SrcOpIdx1, Src0Idx, Src1Idx);
2993}
2994
2996 int64_t BrOffset) const {
2997 // BranchRelaxation should never have to check s_setpc_b64 or s_add_pc_i64
2998 // because its dest block is unanalyzable.
2999 assert(isSOPP(BranchOp) || isSOPK(BranchOp));
3000
3001 // Convert to dwords.
3002 BrOffset /= 4;
3003
3004 // The branch instructions do PC += signext(SIMM16 * 4) + 4, so the offset is
3005 // from the next instruction.
3006 BrOffset -= 1;
3007
3008 return isIntN(BranchOffsetBits, BrOffset);
3009}
3010
3013 return MI.getOperand(0).getMBB();
3014}
3015
3017 for (const MachineInstr &MI : MBB->terminators()) {
3018 if (MI.getOpcode() == AMDGPU::SI_IF || MI.getOpcode() == AMDGPU::SI_ELSE ||
3019 MI.getOpcode() == AMDGPU::SI_LOOP)
3020 return true;
3021 }
3022 return false;
3023}
3024
3026 MachineBasicBlock &DestBB,
3027 MachineBasicBlock &RestoreBB,
3028 const DebugLoc &DL, int64_t BrOffset,
3029 RegScavenger *RS) const {
3030 assert(MBB.empty() &&
3031 "new block should be inserted for expanding unconditional branch");
3032 assert(MBB.pred_size() == 1);
3033 assert(RestoreBB.empty() &&
3034 "restore block should be inserted for restoring clobbered registers");
3035
3036 MachineFunction *MF = MBB.getParent();
3037 MachineRegisterInfo &MRI = MF->getRegInfo();
3039 auto I = MBB.end();
3040 auto &MCCtx = MF->getContext();
3041
3042 if (ST.useAddPC64Inst()) {
3043 MCSymbol *Offset =
3044 MCCtx.createTempSymbol("offset", /*AlwaysAddSuffix=*/true);
3045 auto AddPC = BuildMI(MBB, I, DL, get(AMDGPU::S_ADD_PC_I64))
3047 MCSymbol *PostAddPCLabel =
3048 MCCtx.createTempSymbol("post_addpc", /*AlwaysAddSuffix=*/true);
3049 AddPC->setPostInstrSymbol(*MF, PostAddPCLabel);
3050 auto *OffsetExpr = MCBinaryExpr::createSub(
3051 MCSymbolRefExpr::create(DestBB.getSymbol(), MCCtx),
3052 MCSymbolRefExpr::create(PostAddPCLabel, MCCtx), MCCtx);
3053 Offset->setVariableValue(OffsetExpr);
3054 return;
3055 }
3056
3057 assert(RS && "RegScavenger required for long branching");
3058
3059 // FIXME: Virtual register workaround for RegScavenger not working with empty
3060 // blocks.
3061 Register PCReg = MRI.createVirtualRegister(&AMDGPU::SReg_64RegClass);
3062
3063 // Note: as this is used after hazard recognizer we need to apply some hazard
3064 // workarounds directly.
3065 const bool FlushSGPRWrites = (ST.isWave64() && ST.hasVALUMaskWriteHazard()) ||
3066 ST.hasVALUReadSGPRHazard();
3067 auto ApplyHazardWorkarounds = [this, &MBB, &I, &DL, FlushSGPRWrites]() {
3068 if (FlushSGPRWrites)
3069 BuildMI(MBB, I, DL, get(AMDGPU::S_WAITCNT_DEPCTR))
3071 };
3072
3073 // We need to compute the offset relative to the instruction immediately after
3074 // s_getpc_b64. Insert pc arithmetic code before last terminator.
3075 MachineInstr *GetPC = BuildMI(MBB, I, DL, get(AMDGPU::S_GETPC_B64), PCReg);
3076 ApplyHazardWorkarounds();
3077
3078 MCSymbol *PostGetPCLabel =
3079 MCCtx.createTempSymbol("post_getpc", /*AlwaysAddSuffix=*/true);
3080 GetPC->setPostInstrSymbol(*MF, PostGetPCLabel);
3081
3082 MCSymbol *OffsetLo =
3083 MCCtx.createTempSymbol("offset_lo", /*AlwaysAddSuffix=*/true);
3084 MCSymbol *OffsetHi =
3085 MCCtx.createTempSymbol("offset_hi", /*AlwaysAddSuffix=*/true);
3086 BuildMI(MBB, I, DL, get(AMDGPU::S_ADD_U32))
3087 .addReg(PCReg, RegState::Define, AMDGPU::sub0)
3088 .addReg(PCReg, {}, AMDGPU::sub0)
3089 .addSym(OffsetLo, MO_FAR_BRANCH_OFFSET);
3090 BuildMI(MBB, I, DL, get(AMDGPU::S_ADDC_U32))
3091 .addReg(PCReg, RegState::Define, AMDGPU::sub1)
3092 .addReg(PCReg, {}, AMDGPU::sub1)
3093 .addSym(OffsetHi, MO_FAR_BRANCH_OFFSET);
3094 ApplyHazardWorkarounds();
3095
3096 // Insert the indirect branch after the other terminator.
3097 BuildMI(&MBB, DL, get(AMDGPU::S_SETPC_B64))
3098 .addReg(PCReg);
3099
3100 // If a spill is needed for the pc register pair, we need to insert a spill
3101 // restore block right before the destination block, and insert a short branch
3102 // into the old destination block's fallthrough predecessor.
3103 // e.g.:
3104 //
3105 // s_cbranch_scc0 skip_long_branch:
3106 //
3107 // long_branch_bb:
3108 // spill s[8:9]
3109 // s_getpc_b64 s[8:9]
3110 // s_add_u32 s8, s8, restore_bb
3111 // s_addc_u32 s9, s9, 0
3112 // s_setpc_b64 s[8:9]
3113 //
3114 // skip_long_branch:
3115 // foo;
3116 //
3117 // .....
3118 //
3119 // dest_bb_fallthrough_predecessor:
3120 // bar;
3121 // s_branch dest_bb
3122 //
3123 // restore_bb:
3124 // restore s[8:9]
3125 // fallthrough dest_bb
3126 ///
3127 // dest_bb:
3128 // buzz;
3129
3130 Register LongBranchReservedReg = MFI->getLongBranchReservedReg();
3131 Register Scav;
3132
3133 // If we've previously reserved a register for long branches
3134 // avoid running the scavenger and just use those registers
3135 if (LongBranchReservedReg) {
3136 RS->enterBasicBlock(MBB);
3137 Scav = LongBranchReservedReg;
3138 } else {
3139 RS->enterBasicBlockEnd(MBB);
3140 Scav = RS->scavengeRegisterBackwards(
3141 AMDGPU::SReg_64RegClass, MachineBasicBlock::iterator(GetPC),
3142 /* RestoreAfter */ false, 0, /* AllowSpill */ false);
3143 }
3144 if (Scav) {
3145 RS->setRegUsed(Scav);
3146 MRI.replaceRegWith(PCReg, Scav);
3147 MRI.clearVirtRegs();
3148 } else {
3149 // As SGPR needs VGPR to be spilled, we reuse the slot of temporary VGPR for
3150 // SGPR spill.
3151 const GCNSubtarget &ST = MF->getSubtarget<GCNSubtarget>();
3152 const SIRegisterInfo *TRI = ST.getRegisterInfo();
3153 TRI->spillEmergencySGPR(GetPC, RestoreBB, AMDGPU::SGPR0_SGPR1, RS);
3154 MRI.replaceRegWith(PCReg, AMDGPU::SGPR0_SGPR1);
3155 MRI.clearVirtRegs();
3156 }
3157
3158 MCSymbol *DestLabel = Scav ? DestBB.getSymbol() : RestoreBB.getSymbol();
3159 // Now, the distance could be defined.
3161 MCSymbolRefExpr::create(DestLabel, MCCtx),
3162 MCSymbolRefExpr::create(PostGetPCLabel, MCCtx), MCCtx);
3163 // Add offset assignments.
3164 auto *Mask = MCConstantExpr::create(0xFFFFFFFFULL, MCCtx);
3165 OffsetLo->setVariableValue(MCBinaryExpr::createAnd(Offset, Mask, MCCtx));
3166 auto *ShAmt = MCConstantExpr::create(32, MCCtx);
3167 OffsetHi->setVariableValue(MCBinaryExpr::createAShr(Offset, ShAmt, MCCtx));
3168}
3169
3170unsigned SIInstrInfo::getBranchOpcode(SIInstrInfo::BranchPredicate Cond) {
3171 switch (Cond) {
3172 case SIInstrInfo::SCC_TRUE:
3173 return AMDGPU::S_CBRANCH_SCC1;
3174 case SIInstrInfo::SCC_FALSE:
3175 return AMDGPU::S_CBRANCH_SCC0;
3176 case SIInstrInfo::VCCNZ:
3177 return AMDGPU::S_CBRANCH_VCCNZ;
3178 case SIInstrInfo::VCCZ:
3179 return AMDGPU::S_CBRANCH_VCCZ;
3180 case SIInstrInfo::EXECNZ:
3181 return AMDGPU::S_CBRANCH_EXECNZ;
3182 case SIInstrInfo::EXECZ:
3183 return AMDGPU::S_CBRANCH_EXECZ;
3184 default:
3185 llvm_unreachable("invalid branch predicate");
3186 }
3187}
3188
3189SIInstrInfo::BranchPredicate SIInstrInfo::getBranchPredicate(unsigned Opcode) {
3190 switch (Opcode) {
3191 case AMDGPU::S_CBRANCH_SCC0:
3192 return SCC_FALSE;
3193 case AMDGPU::S_CBRANCH_SCC1:
3194 return SCC_TRUE;
3195 case AMDGPU::S_CBRANCH_VCCNZ:
3196 return VCCNZ;
3197 case AMDGPU::S_CBRANCH_VCCZ:
3198 return VCCZ;
3199 case AMDGPU::S_CBRANCH_EXECNZ:
3200 return EXECNZ;
3201 case AMDGPU::S_CBRANCH_EXECZ:
3202 return EXECZ;
3203 default:
3204 return INVALID_BR;
3205 }
3206}
3207
3211 MachineBasicBlock *&FBB,
3213 bool AllowModify) const {
3214 if (I->getOpcode() == AMDGPU::S_BRANCH) {
3215 // Unconditional Branch
3216 TBB = I->getOperand(0).getMBB();
3217 return false;
3218 }
3219
3220 BranchPredicate Pred = getBranchPredicate(I->getOpcode());
3221 if (Pred == INVALID_BR)
3222 return true;
3223
3224 MachineBasicBlock *CondBB = I->getOperand(0).getMBB();
3225 Cond.push_back(MachineOperand::CreateImm(Pred));
3226 Cond.push_back(I->getOperand(1)); // Save the branch register.
3227
3228 ++I;
3229
3230 if (I == MBB.end()) {
3231 // Conditional branch followed by fall-through.
3232 TBB = CondBB;
3233 return false;
3234 }
3235
3236 if (I->getOpcode() == AMDGPU::S_BRANCH) {
3237 TBB = CondBB;
3238 FBB = I->getOperand(0).getMBB();
3239 return false;
3240 }
3241
3242 return true;
3243}
3244
3246 MachineBasicBlock *&FBB,
3248 bool AllowModify) const {
3249 MachineBasicBlock::iterator I = MBB.getFirstTerminator();
3250 auto E = MBB.end();
3251 if (I == E)
3252 return false;
3253
3254 // Skip over the instructions that are artificially terminators for special
3255 // exec management.
3256 while (I != E && !I->isBranch() && !I->isReturn()) {
3257 switch (I->getOpcode()) {
3258 case AMDGPU::S_MOV_B64_term:
3259 case AMDGPU::S_XOR_B64_term:
3260 case AMDGPU::S_OR_B64_term:
3261 case AMDGPU::S_ANDN2_B64_term:
3262 case AMDGPU::S_AND_B64_term:
3263 case AMDGPU::S_AND_SAVEEXEC_B64_term:
3264 case AMDGPU::S_MOV_B32_term:
3265 case AMDGPU::S_XOR_B32_term:
3266 case AMDGPU::S_OR_B32_term:
3267 case AMDGPU::S_ANDN2_B32_term:
3268 case AMDGPU::S_AND_B32_term:
3269 case AMDGPU::S_AND_SAVEEXEC_B32_term:
3270 case AMDGPU::V_CMPX_EQ_U32_nosdst_e32_term:
3271 case AMDGPU::V_CMPX_EQ_U64_nosdst_e32_term:
3272 break;
3273 case AMDGPU::SI_IF:
3274 case AMDGPU::SI_ELSE:
3275 case AMDGPU::SI_KILL_I1_TERMINATOR:
3276 case AMDGPU::SI_KILL_F32_COND_IMM_TERMINATOR:
3277 // FIXME: It's messy that these need to be considered here at all.
3278 return true;
3279 default:
3280 llvm_unreachable("unexpected non-branch terminator inst");
3281 }
3282
3283 ++I;
3284 }
3285
3286 if (I == E)
3287 return false;
3288
3289 return analyzeBranchImpl(MBB, I, TBB, FBB, Cond, AllowModify);
3290}
3291
3293 int *BytesRemoved) const {
3294 unsigned Count = 0;
3295 unsigned RemovedSize = 0;
3296 for (MachineInstr &MI : llvm::make_early_inc_range(MBB.terminators())) {
3297 // Skip over artificial terminators when removing instructions.
3298 if (MI.isBranch() || MI.isReturn()) {
3299 RemovedSize += getInstSizeInBytes(MI);
3300 MI.eraseFromParent();
3301 ++Count;
3302 }
3303 }
3304
3305 if (BytesRemoved)
3306 *BytesRemoved = RemovedSize;
3307
3308 return Count;
3309}
3310
3311// Copy the flags onto the implicit condition register operand.
3313 const MachineOperand &OrigCond) {
3314 CondReg.setIsUndef(OrigCond.isUndef());
3315 CondReg.setIsKill(OrigCond.isKill());
3316}
3317
3320 MachineBasicBlock *FBB,
3322 const DebugLoc &DL,
3323 int *BytesAdded) const {
3324 if (!FBB && Cond.empty()) {
3325 BuildMI(&MBB, DL, get(AMDGPU::S_BRANCH))
3326 .addMBB(TBB);
3327 if (BytesAdded)
3328 *BytesAdded = ST.hasOffset3fBug() ? 8 : 4;
3329 return 1;
3330 }
3331
3332 assert(TBB && Cond[0].isImm());
3333
3334 unsigned Opcode
3335 = getBranchOpcode(static_cast<BranchPredicate>(Cond[0].getImm()));
3336
3337 if (!FBB) {
3338 MachineInstr *CondBr =
3339 BuildMI(&MBB, DL, get(Opcode))
3340 .addMBB(TBB);
3341
3342 // Copy the flags onto the implicit condition register operand.
3343 preserveCondRegFlags(CondBr->getOperand(1), Cond[1]);
3344 fixImplicitOperands(*CondBr);
3345
3346 if (BytesAdded)
3347 *BytesAdded = ST.hasOffset3fBug() ? 8 : 4;
3348 return 1;
3349 }
3350
3351 assert(TBB && FBB);
3352
3353 MachineInstr *CondBr =
3354 BuildMI(&MBB, DL, get(Opcode))
3355 .addMBB(TBB);
3356 fixImplicitOperands(*CondBr);
3357 BuildMI(&MBB, DL, get(AMDGPU::S_BRANCH))
3358 .addMBB(FBB);
3359
3360 MachineOperand &CondReg = CondBr->getOperand(1);
3361 CondReg.setIsUndef(Cond[1].isUndef());
3362 CondReg.setIsKill(Cond[1].isKill());
3363
3364 if (BytesAdded)
3365 *BytesAdded = ST.hasOffset3fBug() ? 16 : 8;
3366
3367 return 2;
3368}
3369
3372 if (Cond.size() != 2) {
3373 return true;
3374 }
3375
3376 if (Cond[0].isImm()) {
3377 Cond[0].setImm(-Cond[0].getImm());
3378 return false;
3379 }
3380
3381 return true;
3382}
3383
3384namespace {
3385class AMDGPUPipelinerLoopInfo : public TargetInstrInfo::PipelinerLoopInfo {
3386private:
3387 /// The compare instruction for loop control
3388 const MachineInstr *CmpInst = nullptr;
3389 /// The normalized condition used by createTripCountGreaterCondition()
3391
3392public:
3393 AMDGPUPipelinerLoopInfo(MachineInstr *CmpInst,
3395 : CmpInst(CmpInst), Cond(Cond.begin(), Cond.end()) {}
3396
3397 bool shouldIgnoreForPipelining(const MachineInstr *MI) const override {
3398 return CmpInst && MI == CmpInst;
3399 }
3400
3401 std::optional<bool> createTripCountGreaterCondition(
3402 int TC, MachineBasicBlock &MBB,
3403 SmallVectorImpl<MachineOperand> &CondParam) override {
3404 CondParam = this->Cond;
3405 return {};
3406 }
3407
3408 void adjustTripCount(int TripCountAdjust) override {}
3409
3410 void setPreheader(MachineBasicBlock *NewPreheader) override {}
3411};
3412} // namespace
3413
3414std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
3416 MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
3418 // Unanalyzable terminator.
3419 if (analyzeBranch(*LoopBB, TBB, FBB, Cond, /*AllowModify=*/false))
3420 return nullptr;
3421
3422 // Infinite loops are not supported.
3423 if (TBB == LoopBB && FBB == LoopBB)
3424 return nullptr;
3425
3426 // Must be conditional branch.
3427 if (FBB == nullptr)
3428 return nullptr;
3429
3430 assert((TBB == LoopBB || FBB == LoopBB) &&
3431 "The Loop must be a single-basic-block loop");
3432
3433 // Divergent (VCC/EXEC) back-edge is not supported.
3434 BranchPredicate Pred = static_cast<BranchPredicate>(Cond[0].getImm());
3435 if (Pred != SCC_TRUE && Pred != SCC_FALSE)
3436 return nullptr;
3437
3438 // Calls and inline assembly are not supported.
3439 for (const MachineInstr &MI : *LoopBB)
3440 if (MI.isCall() || MI.isInlineAsm())
3441 return nullptr;
3442
3443 // Normalization for createTripCountGreaterCondition(): make Cond mean
3444 // "exit the loop" so the expander emits correct prolog guard branches.
3445 if (TBB == LoopBB)
3447
3448 auto Instructions = make_range(
3450 LoopBB->rend());
3451 auto CmpI = llvm::find_if(Instructions, [&](const MachineInstr &MI) {
3452 return MI.modifiesRegister(Cond[1].getReg(), &RI);
3453 });
3454
3455 if (CmpI == Instructions.end() || CmpI->isPHI())
3456 return nullptr;
3457 MachineInstr *CmpInst = &*CmpI;
3458
3459 return std::make_unique<AMDGPUPipelinerLoopInfo>(CmpInst, Cond);
3460}
3461
3464 Register DstReg, Register TrueReg,
3465 Register FalseReg, int &CondCycles,
3466 int &TrueCycles, int &FalseCycles) const {
3467 switch (Cond[0].getImm()) {
3468 case VCCNZ:
3469 case VCCZ: {
3470 const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
3471 const TargetRegisterClass *RC = MRI.getRegClass(TrueReg);
3472 if (MRI.getRegClass(FalseReg) != RC)
3473 return false;
3474
3475 int NumInsts = AMDGPU::getRegBitWidth(*RC) / 32;
3476 CondCycles = TrueCycles = FalseCycles = NumInsts; // ???
3477
3478 // Limit to equal cost for branch vs. N v_cndmask_b32s.
3479 return RI.hasVGPRs(RC) && NumInsts <= 6;
3480 }
3481 case SCC_TRUE:
3482 case SCC_FALSE: {
3483 // FIXME: We could insert for VGPRs if we could replace the original compare
3484 // with a vector one.
3485 const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
3486 const TargetRegisterClass *RC = MRI.getRegClass(TrueReg);
3487 if (MRI.getRegClass(FalseReg) != RC)
3488 return false;
3489
3490 int NumInsts = AMDGPU::getRegBitWidth(*RC) / 32;
3491
3492 // Multiples of 8 can do s_cselect_b64
3493 if (NumInsts % 2 == 0)
3494 NumInsts /= 2;
3495
3496 CondCycles = TrueCycles = FalseCycles = NumInsts; // ???
3497 return RI.isSGPRClass(RC);
3498 }
3499 default:
3500 return false;
3501 }
3502}
3503
3507 Register TrueReg, Register FalseReg) const {
3508 BranchPredicate Pred = static_cast<BranchPredicate>(Cond[0].getImm());
3509 if (Pred == VCCZ || Pred == SCC_FALSE) {
3510 Pred = static_cast<BranchPredicate>(-Pred);
3511 std::swap(TrueReg, FalseReg);
3512 }
3513
3514 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
3515 const TargetRegisterClass *DstRC = MRI.getRegClass(DstReg);
3516 unsigned DstSize = RI.getRegSizeInBits(*DstRC);
3517
3518 if (DstSize == 32) {
3520 if (Pred == SCC_TRUE) {
3521 Select = BuildMI(MBB, I, DL, get(AMDGPU::S_CSELECT_B32), DstReg)
3522 .addReg(TrueReg)
3523 .addReg(FalseReg);
3524 } else {
3525 // Instruction's operands are backwards from what is expected.
3526 Select = BuildMI(MBB, I, DL, get(AMDGPU::V_CNDMASK_B32_e32), DstReg)
3527 .addReg(FalseReg)
3528 .addReg(TrueReg);
3529 }
3530
3531 preserveCondRegFlags(Select->getOperand(3), Cond[1]);
3532 return;
3533 }
3534
3535 if (DstSize == 64 && Pred == SCC_TRUE) {
3537 BuildMI(MBB, I, DL, get(AMDGPU::S_CSELECT_B64), DstReg)
3538 .addReg(TrueReg)
3539 .addReg(FalseReg);
3540
3541 preserveCondRegFlags(Select->getOperand(3), Cond[1]);
3542 return;
3543 }
3544
3545 static const int16_t Sub0_15[] = {
3546 AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, AMDGPU::sub3,
3547 AMDGPU::sub4, AMDGPU::sub5, AMDGPU::sub6, AMDGPU::sub7,
3548 AMDGPU::sub8, AMDGPU::sub9, AMDGPU::sub10, AMDGPU::sub11,
3549 AMDGPU::sub12, AMDGPU::sub13, AMDGPU::sub14, AMDGPU::sub15,
3550 };
3551
3552 static const int16_t Sub0_15_64[] = {
3553 AMDGPU::sub0_sub1, AMDGPU::sub2_sub3,
3554 AMDGPU::sub4_sub5, AMDGPU::sub6_sub7,
3555 AMDGPU::sub8_sub9, AMDGPU::sub10_sub11,
3556 AMDGPU::sub12_sub13, AMDGPU::sub14_sub15,
3557 };
3558
3559 unsigned SelOp = AMDGPU::V_CNDMASK_B32_e32;
3560 const TargetRegisterClass *EltRC = &AMDGPU::VGPR_32RegClass;
3561 const int16_t *SubIndices = Sub0_15;
3562 int NElts = DstSize / 32;
3563
3564 // 64-bit select is only available for SALU.
3565 // TODO: Split 96-bit into 64-bit and 32-bit, not 3x 32-bit.
3566 if (Pred == SCC_TRUE) {
3567 if (NElts % 2) {
3568 SelOp = AMDGPU::S_CSELECT_B32;
3569 EltRC = &AMDGPU::SGPR_32RegClass;
3570 } else {
3571 SelOp = AMDGPU::S_CSELECT_B64;
3572 EltRC = &AMDGPU::SGPR_64RegClass;
3573 SubIndices = Sub0_15_64;
3574 NElts /= 2;
3575 }
3576 }
3577
3579 MBB, I, DL, get(AMDGPU::REG_SEQUENCE), DstReg);
3580
3581 I = MIB->getIterator();
3582
3584 for (int Idx = 0; Idx != NElts; ++Idx) {
3585 Register DstElt = MRI.createVirtualRegister(EltRC);
3586 Regs.push_back(DstElt);
3587
3588 unsigned SubIdx = SubIndices[Idx];
3589
3591 if (SelOp == AMDGPU::V_CNDMASK_B32_e32) {
3592 Select = BuildMI(MBB, I, DL, get(SelOp), DstElt)
3593 .addReg(FalseReg, {}, SubIdx)
3594 .addReg(TrueReg, {}, SubIdx);
3595 } else {
3596 Select = BuildMI(MBB, I, DL, get(SelOp), DstElt)
3597 .addReg(TrueReg, {}, SubIdx)
3598 .addReg(FalseReg, {}, SubIdx);
3599 }
3600
3601 preserveCondRegFlags(Select->getOperand(3), Cond[1]);
3603
3604 MIB.addReg(DstElt)
3605 .addImm(SubIdx);
3606 }
3607}
3608
3610
3611 if (MI.isBranch() || MI.isCall() || MI.isReturn() || MI.isIndirectBranch())
3612 return true;
3613
3614 switch (MI.getOpcode()) {
3615 case AMDGPU::S_ENDPGM:
3616 case AMDGPU::S_ENDPGM_SAVED:
3617 case AMDGPU::S_TRAP:
3618 case AMDGPU::S_GETREG_B32:
3619 case AMDGPU::S_SETREG_B32:
3620 case AMDGPU::S_SETREG_B32_mode:
3621 case AMDGPU::S_SETREG_IMM32_B32:
3622 case AMDGPU::S_SETREG_IMM32_B32_mode:
3623 case AMDGPU::S_SENDMSG:
3624 case AMDGPU::S_SENDMSGHALT:
3625 case AMDGPU::S_SENDMSG_RTN_B32:
3626 case AMDGPU::S_SENDMSG_RTN_B64:
3627 case AMDGPU::S_BARRIER_WAIT:
3628 case AMDGPU::S_BARRIER_SIGNAL_M0:
3629 case AMDGPU::S_BARRIER_SIGNAL_IMM:
3630 case AMDGPU::S_BARRIER_SIGNAL_ISFIRST_M0:
3631 case AMDGPU::S_BARRIER_SIGNAL_ISFIRST_IMM:
3632 return true;
3633 default:
3634 return false;
3635 }
3636}
3637
3639 switch (MI.getOpcode()) {
3640 case AMDGPU::V_MOV_B16_t16_e32:
3641 case AMDGPU::V_MOV_B16_t16_e64:
3642 case AMDGPU::V_MOV_B32_e32:
3643 case AMDGPU::V_MOV_B32_e64:
3644 case AMDGPU::V_MOV_B64_PSEUDO:
3645 case AMDGPU::V_MOV_B64_e32:
3646 case AMDGPU::V_MOV_B64_e64:
3647 case AMDGPU::S_MOV_B32:
3648 case AMDGPU::S_MOV_B64:
3649 case AMDGPU::S_MOV_B64_IMM_PSEUDO:
3650 case AMDGPU::COPY:
3651 case AMDGPU::WWM_COPY:
3652 case AMDGPU::V_ACCVGPR_WRITE_B32_e64:
3653 case AMDGPU::V_ACCVGPR_READ_B32_e64:
3654 case AMDGPU::V_ACCVGPR_MOV_B32:
3655 case AMDGPU::AV_MOV_B32_IMM_PSEUDO:
3656 case AMDGPU::AV_MOV_B64_IMM_PSEUDO:
3657 return true;
3658 default:
3659 return false;
3660 }
3661}
3662
3664 switch (MI.getOpcode()) {
3665 case AMDGPU::V_MOV_B16_t16_e32:
3666 case AMDGPU::V_MOV_B16_t16_e64:
3667 return 2;
3668 case AMDGPU::V_MOV_B32_e32:
3669 case AMDGPU::V_MOV_B32_e64:
3670 case AMDGPU::V_MOV_B64_PSEUDO:
3671 case AMDGPU::V_MOV_B64_e32:
3672 case AMDGPU::V_MOV_B64_e64:
3673 case AMDGPU::S_MOV_B32:
3674 case AMDGPU::S_MOV_B64:
3675 case AMDGPU::S_MOV_B64_IMM_PSEUDO:
3676 case AMDGPU::COPY:
3677 case AMDGPU::WWM_COPY:
3678 case AMDGPU::V_ACCVGPR_WRITE_B32_e64:
3679 case AMDGPU::V_ACCVGPR_READ_B32_e64:
3680 case AMDGPU::V_ACCVGPR_MOV_B32:
3681 case AMDGPU::AV_MOV_B32_IMM_PSEUDO:
3682 case AMDGPU::AV_MOV_B64_IMM_PSEUDO:
3683 return 1;
3684 default:
3685 llvm_unreachable("MI is not a foldable copy");
3686 }
3687}
3688
3689static constexpr AMDGPU::OpName ModifierOpNames[] = {
3690 AMDGPU::OpName::src0_modifiers, AMDGPU::OpName::src1_modifiers,
3691 AMDGPU::OpName::src2_modifiers, AMDGPU::OpName::clamp,
3692 AMDGPU::OpName::omod, AMDGPU::OpName::op_sel};
3693
3695 unsigned Opc = MI.getOpcode();
3696 for (AMDGPU::OpName Name : reverse(ModifierOpNames)) {
3697 int Idx = AMDGPU::getNamedOperandIdx(Opc, Name);
3698 if (Idx >= 0)
3699 MI.removeOperand(Idx);
3700 }
3701}
3702
3704 const MCInstrDesc &NewDesc) const {
3705 MI.setDesc(NewDesc);
3706
3707 // Remove any leftover implicit operands from mutating the instruction. e.g.
3708 // if we replace an s_and_b32 with a copy, we don't need the implicit scc def
3709 // anymore.
3710 const MCInstrDesc &Desc = MI.getDesc();
3711 unsigned NumOps = Desc.getNumOperands() + Desc.implicit_uses().size() +
3712 Desc.implicit_defs().size();
3713
3714 for (unsigned I = MI.getNumOperands() - 1; I >= NumOps; --I)
3715 MI.removeOperand(I);
3716}
3717
3718std::optional<int64_t> SIInstrInfo::extractSubregFromImm(int64_t Imm,
3719 unsigned SubRegIndex) {
3720 switch (SubRegIndex) {
3721 case AMDGPU::NoSubRegister:
3722 return Imm;
3723 case AMDGPU::sub0:
3724 return SignExtend64<32>(Imm);
3725 case AMDGPU::sub1:
3726 return SignExtend64<32>(Imm >> 32);
3727 case AMDGPU::lo16:
3728 return SignExtend64<16>(Imm);
3729 case AMDGPU::hi16:
3730 return SignExtend64<16>(Imm >> 16);
3731 case AMDGPU::sub1_lo16:
3732 return SignExtend64<16>(Imm >> 32);
3733 case AMDGPU::sub1_hi16:
3734 return SignExtend64<16>(Imm >> 48);
3735 default:
3736 return std::nullopt;
3737 }
3738
3739 llvm_unreachable("covered subregister switch");
3740}
3741
3742static unsigned getNewFMAAKInst(const GCNSubtarget &ST, unsigned Opc) {
3743 switch (Opc) {
3744 case AMDGPU::V_MAC_F16_e32:
3745 case AMDGPU::V_MAC_F16_e64:
3746 case AMDGPU::V_MAD_F16_e64:
3747 return AMDGPU::V_MADAK_F16;
3748 case AMDGPU::V_MAC_F32_e32:
3749 case AMDGPU::V_MAC_F32_e64:
3750 case AMDGPU::V_MAD_F32_e64:
3751 return AMDGPU::V_MADAK_F32;
3752 case AMDGPU::V_FMAC_F32_e32:
3753 case AMDGPU::V_FMAC_F32_e64:
3754 case AMDGPU::V_FMA_F32_e64:
3755 return AMDGPU::V_FMAAK_F32;
3756 case AMDGPU::V_FMAC_F16_e32:
3757 case AMDGPU::V_FMAC_F16_e64:
3758 case AMDGPU::V_FMAC_F16_t16_e64:
3759 case AMDGPU::V_FMAC_F16_fake16_e64:
3760 case AMDGPU::V_FMAC_F16_t16_e32:
3761 case AMDGPU::V_FMAC_F16_fake16_e32:
3762 case AMDGPU::V_FMA_F16_e64:
3763 return ST.hasTrue16BitInsts() ? ST.useRealTrue16Insts()
3764 ? AMDGPU::V_FMAAK_F16_t16
3765 : AMDGPU::V_FMAAK_F16_fake16
3766 : AMDGPU::V_FMAAK_F16;
3767 case AMDGPU::V_FMAC_F64_e32:
3768 case AMDGPU::V_FMAC_F64_e64:
3769 case AMDGPU::V_FMA_F64_e64:
3770 return AMDGPU::V_FMAAK_F64;
3771 default:
3772 llvm_unreachable("invalid instruction");
3773 }
3774}
3775
3776static unsigned getNewFMAMKInst(const GCNSubtarget &ST, unsigned Opc) {
3777 switch (Opc) {
3778 case AMDGPU::V_MAC_F16_e32:
3779 case AMDGPU::V_MAC_F16_e64:
3780 case AMDGPU::V_MAD_F16_e64:
3781 return AMDGPU::V_MADMK_F16;
3782 case AMDGPU::V_MAC_F32_e32:
3783 case AMDGPU::V_MAC_F32_e64:
3784 case AMDGPU::V_MAD_F32_e64:
3785 return AMDGPU::V_MADMK_F32;
3786 case AMDGPU::V_FMAC_F32_e32:
3787 case AMDGPU::V_FMAC_F32_e64:
3788 case AMDGPU::V_FMA_F32_e64:
3789 return AMDGPU::V_FMAMK_F32;
3790 case AMDGPU::V_FMAC_F16_e32:
3791 case AMDGPU::V_FMAC_F16_e64:
3792 case AMDGPU::V_FMAC_F16_t16_e64:
3793 case AMDGPU::V_FMAC_F16_fake16_e64:
3794 case AMDGPU::V_FMAC_F16_t16_e32:
3795 case AMDGPU::V_FMAC_F16_fake16_e32:
3796 case AMDGPU::V_FMA_F16_e64:
3797 return ST.hasTrue16BitInsts() ? ST.useRealTrue16Insts()
3798 ? AMDGPU::V_FMAMK_F16_t16
3799 : AMDGPU::V_FMAMK_F16_fake16
3800 : AMDGPU::V_FMAMK_F16;
3801 case AMDGPU::V_FMAC_F64_e32:
3802 case AMDGPU::V_FMAC_F64_e64:
3803 case AMDGPU::V_FMA_F64_e64:
3804 return AMDGPU::V_FMAMK_F64;
3805 default:
3806 llvm_unreachable("invalid instruction");
3807 }
3808}
3809
3811 Register Reg, MachineRegisterInfo *MRI) const {
3812 int64_t Imm;
3813 if (!getConstValDefinedInReg(DefMI, Reg, Imm))
3814 return false;
3815
3816 const bool HasMultipleUses = !MRI->hasOneNonDBGUse(Reg);
3817
3818 assert(!DefMI.getOperand(0).getSubReg() && "Expected SSA form");
3819
3820 unsigned Opc = UseMI.getOpcode();
3821 if (Opc == AMDGPU::COPY) {
3822 assert(!UseMI.getOperand(0).getSubReg() && "Expected SSA form");
3823
3824 Register DstReg = UseMI.getOperand(0).getReg();
3825 Register UseSubReg = UseMI.getOperand(1).getSubReg();
3826
3827 const TargetRegisterClass *DstRC = RI.getRegClassForReg(*MRI, DstReg);
3828
3829 if (HasMultipleUses) {
3830 // TODO: This should fold in more cases with multiple use, but we need to
3831 // more carefully consider what those uses are.
3832 unsigned ImmDefSize = RI.getRegSizeInBits(*MRI->getRegClass(Reg));
3833
3834 // Avoid breaking up a 64-bit inline immediate into a subregister extract.
3835 if (UseSubReg != AMDGPU::NoSubRegister && ImmDefSize == 64)
3836 return false;
3837
3838 // Most of the time folding a 32-bit inline constant is free (though this
3839 // might not be true if we can't later fold it into a real user).
3840 //
3841 // FIXME: This isInlineConstant check is imprecise if
3842 // getConstValDefinedInReg handled the tricky non-mov cases.
3843 if (ImmDefSize == 32 &&
3845 return false;
3846 }
3847
3848 bool Is16Bit = UseSubReg != AMDGPU::NoSubRegister &&
3849 RI.getSubRegIdxSize(UseSubReg) == 16;
3850
3851 if (Is16Bit) {
3852 if (RI.hasVGPRs(DstRC))
3853 return false; // Do not clobber vgpr_hi16
3854
3855 if (DstReg.isVirtual() && UseSubReg != AMDGPU::lo16)
3856 return false;
3857 }
3858
3859 MachineFunction *MF = UseMI.getMF();
3860
3861 unsigned NewOpc = AMDGPU::INSTRUCTION_LIST_END;
3862 MCRegister MovDstPhysReg =
3863 DstReg.isPhysical() ? DstReg.asMCReg() : MCRegister();
3864
3865 std::optional<int64_t> SubRegImm = extractSubregFromImm(Imm, UseSubReg);
3866
3867 // TODO: Try to fold with AMDGPU::V_MOV_B16_t16_e64
3868 for (unsigned MovOp :
3869 {AMDGPU::S_MOV_B32, AMDGPU::V_MOV_B32_e32, AMDGPU::S_MOV_B64,
3870 AMDGPU::V_MOV_B64_PSEUDO, AMDGPU::V_ACCVGPR_WRITE_B32_e64}) {
3871 const MCInstrDesc &MovDesc = get(MovOp);
3872
3873 const TargetRegisterClass *MovDstRC = getRegClass(MovDesc, 0);
3874 if (Is16Bit) {
3875 // We just need to find a correctly sized register class, so the
3876 // subregister index compatibility doesn't matter since we're statically
3877 // extracting the immediate value.
3878 MovDstRC = RI.getMatchingSuperRegClass(MovDstRC, DstRC, AMDGPU::lo16);
3879 if (!MovDstRC)
3880 continue;
3881
3882 if (MovDstPhysReg) {
3883 // FIXME: We probably should not do this. If there is a live value in
3884 // the high half of the register, it will be corrupted.
3885 MovDstPhysReg =
3886 RI.getMatchingSuperReg(MovDstPhysReg, AMDGPU::lo16, MovDstRC);
3887 if (!MovDstPhysReg)
3888 continue;
3889 }
3890 }
3891
3892 // Result class isn't the right size, try the next instruction.
3893 if (MovDstPhysReg) {
3894 if (!MovDstRC->contains(MovDstPhysReg))
3895 return false;
3896 } else if (!MRI->constrainRegClass(DstReg, MovDstRC)) {
3897 // TODO: This will be overly conservative in the case of 16-bit virtual
3898 // SGPRs. We could hack up the virtual register uses to use a compatible
3899 // 32-bit class.
3900 continue;
3901 }
3902
3903 const MCOperandInfo &OpInfo = MovDesc.operands()[1];
3904
3905 // Ensure the interpreted immediate value is a valid operand in the new
3906 // mov.
3907 //
3908 // FIXME: isImmOperandLegal should have form that doesn't require existing
3909 // MachineInstr or MachineOperand
3910 if (!RI.opCanUseLiteralConstant(OpInfo.OperandType) &&
3911 !isInlineConstant(*SubRegImm, OpInfo.OperandType))
3912 break;
3913
3914 NewOpc = MovOp;
3915 break;
3916 }
3917
3918 if (NewOpc == AMDGPU::INSTRUCTION_LIST_END)
3919 return false;
3920
3921 if (Is16Bit) {
3922 UseMI.getOperand(0).setSubReg(AMDGPU::NoSubRegister);
3923 if (MovDstPhysReg)
3924 UseMI.getOperand(0).setReg(MovDstPhysReg);
3925 assert(UseMI.getOperand(1).getReg().isVirtual());
3926 }
3927
3928 const MCInstrDesc &NewMCID = get(NewOpc);
3929 UseMI.setDesc(NewMCID);
3930 UseMI.getOperand(1).ChangeToImmediate(*SubRegImm);
3931 UseMI.addImplicitDefUseOperands(*MF);
3932 return true;
3933 }
3934
3935 if (HasMultipleUses)
3936 return false;
3937
3938 if (Opc == AMDGPU::V_MAD_F32_e64 || Opc == AMDGPU::V_MAC_F32_e64 ||
3939 Opc == AMDGPU::V_MAD_F16_e64 || Opc == AMDGPU::V_MAC_F16_e64 ||
3940 Opc == AMDGPU::V_FMA_F32_e64 || Opc == AMDGPU::V_FMAC_F32_e64 ||
3941 Opc == AMDGPU::V_FMA_F16_e64 || Opc == AMDGPU::V_FMAC_F16_e64 ||
3942 Opc == AMDGPU::V_FMAC_F16_t16_e64 ||
3943 Opc == AMDGPU::V_FMAC_F16_fake16_e64 || Opc == AMDGPU::V_FMA_F64_e64 ||
3944 Opc == AMDGPU::V_FMAC_F64_e64) {
3945 // Don't fold if we are using source or output modifiers. The new VOP2
3946 // instructions don't have them.
3948 return false;
3949
3950 // If this is a free constant, there's no reason to do this.
3951 // TODO: We could fold this here instead of letting SIFoldOperands do it
3952 // later.
3953 int Src0Idx = getNamedOperandIdx(UseMI.getOpcode(), AMDGPU::OpName::src0);
3954
3955 // Any src operand can be used for the legality check.
3956 if (isInlineConstant(UseMI, Src0Idx, Imm))
3957 return false;
3958
3959 MachineOperand *Src0 = &UseMI.getOperand(Src0Idx);
3960
3961 MachineOperand *Src1 = getNamedOperand(UseMI, AMDGPU::OpName::src1);
3962 MachineOperand *Src2 = getNamedOperand(UseMI, AMDGPU::OpName::src2);
3963
3964 auto CopyRegOperandToNarrowerRC =
3965 [MRI, this](MachineInstr &MI, unsigned OpNo,
3966 const TargetRegisterClass *NewRC) -> void {
3967 if (!MI.getOperand(OpNo).isReg())
3968 return;
3969 Register Reg = MI.getOperand(OpNo).getReg();
3970 const TargetRegisterClass *RC = RI.getRegClassForReg(*MRI, Reg);
3971 if (RI.getCommonSubClass(RC, NewRC) != NewRC)
3972 return;
3973 Register Tmp = MRI->createVirtualRegister(NewRC);
3974 BuildMI(*MI.getParent(), MI.getIterator(), MI.getDebugLoc(),
3975 get(AMDGPU::COPY), Tmp)
3976 .addReg(Reg);
3977 MI.getOperand(OpNo).setReg(Tmp);
3978 MI.getOperand(OpNo).setIsKill();
3979 };
3980
3981 // Multiplied part is the constant: Use v_madmk_{f16, f32}.
3982 if ((Src0->isReg() && Src0->getReg() == Reg) ||
3983 (Src1->isReg() && Src1->getReg() == Reg)) {
3984 MachineOperand *RegSrc =
3985 Src1->isReg() && Src1->getReg() == Reg ? Src0 : Src1;
3986 if (!RegSrc->isReg())
3987 return false;
3988 if (RI.isSGPRClass(MRI->getRegClass(RegSrc->getReg())) &&
3989 ST.getConstantBusLimit(Opc) < 2)
3990 return false;
3991
3992 if (!Src2->isReg() || RI.isSGPRClass(MRI->getRegClass(Src2->getReg())))
3993 return false;
3994
3995 // If src2 is also a literal constant then we have to choose which one to
3996 // fold. In general it is better to choose madak so that the other literal
3997 // can be materialized in an sgpr instead of a vgpr:
3998 // s_mov_b32 s0, literal
3999 // v_madak_f32 v0, s0, v0, literal
4000 // Instead of:
4001 // v_mov_b32 v1, literal
4002 // v_madmk_f32 v0, v0, literal, v1
4003 MachineInstr *Def = MRI->getUniqueVRegDef(Src2->getReg());
4004 if (Def && Def->isMoveImmediate() &&
4005 !isInlineConstant(Def->getOperand(1)))
4006 return false;
4007
4008 unsigned NewOpc = getNewFMAMKInst(ST, Opc);
4009 if (pseudoToMCOpcode(NewOpc) == -1)
4010 return false;
4011
4012 const std::optional<int64_t> SubRegImm = extractSubregFromImm(
4013 Imm, RegSrc == Src1 ? Src0->getSubReg() : Src1->getSubReg());
4014
4015 // FIXME: This would be a lot easier if we could return a new instruction
4016 // instead of having to modify in place.
4017
4018 Register SrcReg = RegSrc->getReg();
4019 unsigned SrcSubReg = RegSrc->getSubReg();
4020 Src0->setReg(SrcReg);
4021 Src0->setSubReg(SrcSubReg);
4022 Src0->setIsKill(RegSrc->isKill());
4023
4024 if (Opc == AMDGPU::V_MAC_F32_e64 || Opc == AMDGPU::V_MAC_F16_e64 ||
4025 Opc == AMDGPU::V_FMAC_F32_e64 || Opc == AMDGPU::V_FMAC_F16_t16_e64 ||
4026 Opc == AMDGPU::V_FMAC_F16_fake16_e64 ||
4027 Opc == AMDGPU::V_FMAC_F16_e64 || Opc == AMDGPU::V_FMAC_F64_e64)
4028 UseMI.untieRegOperand(
4029 AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src2));
4030
4031 Src1->ChangeToImmediate(*SubRegImm);
4032
4034 UseMI.setDesc(get(NewOpc));
4035
4036 if (NewOpc == AMDGPU::V_FMAMK_F16_t16 ||
4037 NewOpc == AMDGPU::V_FMAMK_F16_fake16) {
4038 const TargetRegisterClass *NewRC = getRegClass(get(NewOpc), 0);
4039 Register Tmp = MRI->createVirtualRegister(NewRC);
4040 BuildMI(*UseMI.getParent(), std::next(UseMI.getIterator()),
4041 UseMI.getDebugLoc(), get(AMDGPU::COPY),
4042 UseMI.getOperand(0).getReg())
4043 .addReg(Tmp, RegState::Kill);
4044 UseMI.getOperand(0).setReg(Tmp);
4045 CopyRegOperandToNarrowerRC(UseMI, 1, NewRC);
4046 CopyRegOperandToNarrowerRC(UseMI, 3, NewRC);
4047 }
4048
4049 bool DeleteDef = MRI->use_nodbg_empty(Reg);
4050 if (DeleteDef)
4051 DefMI.eraseFromParent();
4052
4053 return true;
4054 }
4055
4056 // Added part is the constant: Use v_madak_{f16, f32}.
4057 if (Src2->isReg() && Src2->getReg() == Reg) {
4058 if (ST.getConstantBusLimit(Opc) < 2) {
4059 // Not allowed to use constant bus for another operand.
4060 // We can however allow an inline immediate as src0.
4061 bool Src0Inlined = false;
4062 if (Src0->isReg()) {
4063 // Try to inline constant if possible.
4064 // If the Def moves immediate and the use is single
4065 // We are saving VGPR here.
4066 MachineInstr *Def = MRI->getUniqueVRegDef(Src0->getReg());
4067 if (Def && Def->isMoveImmediate() &&
4068 isInlineConstant(Def->getOperand(1)) &&
4069 MRI->hasOneNonDBGUse(Src0->getReg())) {
4070 Src0->ChangeToImmediate(Def->getOperand(1).getImm());
4071 Src0Inlined = true;
4072 } else if (ST.getConstantBusLimit(Opc) <= 1 &&
4073 RI.isSGPRReg(*MRI, Src0->getReg())) {
4074 return false;
4075 }
4076 // VGPR is okay as Src0 - fallthrough
4077 }
4078
4079 if (Src1->isReg() && !Src0Inlined) {
4080 // We have one slot for inlinable constant so far - try to fill it
4081 MachineInstr *Def = MRI->getUniqueVRegDef(Src1->getReg());
4082 if (Def && Def->isMoveImmediate() &&
4083 isInlineConstant(Def->getOperand(1)) &&
4084 MRI->hasOneNonDBGUse(Src1->getReg()) && commuteInstruction(UseMI))
4085 Src0->ChangeToImmediate(Def->getOperand(1).getImm());
4086 else if (RI.isSGPRReg(*MRI, Src1->getReg()))
4087 return false;
4088 // VGPR is okay as Src1 - fallthrough
4089 }
4090 }
4091
4092 unsigned NewOpc = getNewFMAAKInst(ST, Opc);
4093 if (pseudoToMCOpcode(NewOpc) == -1)
4094 return false;
4095
4096 // FIXME: This would be a lot easier if we could return a new instruction
4097 // instead of having to modify in place.
4098
4099 if (Opc == AMDGPU::V_MAC_F32_e64 || Opc == AMDGPU::V_MAC_F16_e64 ||
4100 Opc == AMDGPU::V_FMAC_F32_e64 || Opc == AMDGPU::V_FMAC_F16_t16_e64 ||
4101 Opc == AMDGPU::V_FMAC_F16_fake16_e64 ||
4102 Opc == AMDGPU::V_FMAC_F16_e64 || Opc == AMDGPU::V_FMAC_F64_e64)
4103 UseMI.untieRegOperand(
4104 AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src2));
4105
4106 const std::optional<int64_t> SubRegImm =
4108
4109 // ChangingToImmediate adds Src2 back to the instruction.
4110 Src2->ChangeToImmediate(*SubRegImm);
4111
4112 // These come before src2.
4114 UseMI.setDesc(get(NewOpc));
4115
4116 if (NewOpc == AMDGPU::V_FMAAK_F16_t16 ||
4117 NewOpc == AMDGPU::V_FMAAK_F16_fake16) {
4118 const TargetRegisterClass *NewRC = getRegClass(get(NewOpc), 0);
4119 Register Tmp = MRI->createVirtualRegister(NewRC);
4120 BuildMI(*UseMI.getParent(), std::next(UseMI.getIterator()),
4121 UseMI.getDebugLoc(), get(AMDGPU::COPY),
4122 UseMI.getOperand(0).getReg())
4123 .addReg(Tmp, RegState::Kill);
4124 UseMI.getOperand(0).setReg(Tmp);
4125 CopyRegOperandToNarrowerRC(UseMI, 1, NewRC);
4126 CopyRegOperandToNarrowerRC(UseMI, 2, NewRC);
4127 }
4128
4129 // It might happen that UseMI was commuted
4130 // and we now have SGPR as SRC1. If so 2 inlined
4131 // constant and SGPR are illegal.
4133
4134 bool DeleteDef = MRI->use_nodbg_empty(Reg);
4135 if (DeleteDef)
4136 DefMI.eraseFromParent();
4137
4138 return true;
4139 }
4140 }
4141
4142 return false;
4143}
4144
4145static bool
4148 if (BaseOps1.size() != BaseOps2.size())
4149 return false;
4150 for (size_t I = 0, E = BaseOps1.size(); I < E; ++I) {
4151 if (!BaseOps1[I]->isIdenticalTo(*BaseOps2[I]))
4152 return false;
4153 }
4154 return true;
4155}
4156
4157static bool offsetsDoNotOverlap(LocationSize WidthA, int OffsetA,
4158 LocationSize WidthB, int OffsetB) {
4159 int LowOffset = OffsetA < OffsetB ? OffsetA : OffsetB;
4160 int HighOffset = OffsetA < OffsetB ? OffsetB : OffsetA;
4161 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
4162 return LowWidth.hasValue() &&
4163 LowOffset + (int)LowWidth.getValue() <= HighOffset;
4164}
4165
4166bool SIInstrInfo::checkInstOffsetsDoNotOverlap(const MachineInstr &MIa,
4167 const MachineInstr &MIb) const {
4168 SmallVector<const MachineOperand *, 4> BaseOps0, BaseOps1;
4169 int64_t Offset0, Offset1;
4170 LocationSize Dummy0 = LocationSize::precise(0);
4171 LocationSize Dummy1 = LocationSize::precise(0);
4172 bool Offset0IsScalable, Offset1IsScalable;
4173 if (!getMemOperandsWithOffsetWidth(MIa, BaseOps0, Offset0, Offset0IsScalable,
4174 Dummy0, &RI) ||
4175 !getMemOperandsWithOffsetWidth(MIb, BaseOps1, Offset1, Offset1IsScalable,
4176 Dummy1, &RI))
4177 return false;
4178
4179 if (!memOpsHaveSameBaseOperands(BaseOps0, BaseOps1))
4180 return false;
4181
4182 if (!MIa.hasOneMemOperand() || !MIb.hasOneMemOperand()) {
4183 // FIXME: Handle ds_read2 / ds_write2.
4184 return false;
4185 }
4186 LocationSize Width0 = MIa.memoperands().front()->getSize();
4187 LocationSize Width1 = MIb.memoperands().front()->getSize();
4188 return offsetsDoNotOverlap(Width0, Offset0, Width1, Offset1);
4189}
4190
4192 const MachineInstr &MIb) const {
4193 assert(MIa.mayLoadOrStore() &&
4194 "MIa must load from or modify a memory location");
4195 assert(MIb.mayLoadOrStore() &&
4196 "MIb must load from or modify a memory location");
4197
4199 return false;
4200
4201 // XXX - Can we relax this between address spaces?
4202 if (MIa.hasOrderedMemoryRef() || MIb.hasOrderedMemoryRef())
4203 return false;
4204
4205 if (isLDSDMA(MIa) || isLDSDMA(MIb))
4206 return false;
4207
4208 if (MIa.isBundle() || MIb.isBundle())
4209 return false;
4210
4211 // TODO: Should we check the address space from the MachineMemOperand? That
4212 // would allow us to distinguish objects we know don't alias based on the
4213 // underlying address space, even if it was lowered to a different one,
4214 // e.g. private accesses lowered to use MUBUF instructions on a scratch
4215 // buffer.
4216 if (isDS(MIa)) {
4217 if (isDS(MIb))
4218 return checkInstOffsetsDoNotOverlap(MIa, MIb);
4219
4220 return !isFLAT(MIb) || isSegmentSpecificFLAT(MIb);
4221 }
4222
4223 if (isMUBUF(MIa) || isMTBUF(MIa)) {
4224 if (isMUBUF(MIb) || isMTBUF(MIb))
4225 return checkInstOffsetsDoNotOverlap(MIa, MIb);
4226
4227 if (isFLAT(MIb))
4228 return isFLATScratch(MIb);
4229
4230 return !isSMRD(MIb);
4231 }
4232
4233 if (isSMRD(MIa)) {
4234 if (isSMRD(MIb))
4235 return checkInstOffsetsDoNotOverlap(MIa, MIb);
4236
4237 if (isFLAT(MIb))
4238 return isFLATScratch(MIb);
4239
4240 return !isMUBUF(MIb) && !isMTBUF(MIb);
4241 }
4242
4243 if (isFLAT(MIa)) {
4244 if (isFLAT(MIb)) {
4245 if ((isFLATScratch(MIa) && isFLATGlobal(MIb)) ||
4246 (isFLATGlobal(MIa) && isFLATScratch(MIb)))
4247 return true;
4248
4249 return checkInstOffsetsDoNotOverlap(MIa, MIb);
4250 }
4251
4252 return false;
4253 }
4254
4255 return false;
4256}
4257
4259 MachineInstr &NewMI) {
4260 if (LV) {
4261 unsigned NumOps = MI.getNumOperands();
4262 for (unsigned I = 1; I < NumOps; ++I) {
4263 MachineOperand &Op = MI.getOperand(I);
4264 if (Op.isReg() && Op.isKill())
4265 LV->replaceKillInstruction(Op.getReg(), MI, NewMI);
4266 }
4267 }
4268}
4269
4270static unsigned getNewFMAInst(const GCNSubtarget &ST, unsigned Opc) {
4271 switch (Opc) {
4272 case AMDGPU::V_MAC_F16_e32:
4273 case AMDGPU::V_MAC_F16_e64:
4274 return AMDGPU::V_MAD_F16_e64;
4275 case AMDGPU::V_MAC_F32_e32:
4276 case AMDGPU::V_MAC_F32_e64:
4277 return AMDGPU::V_MAD_F32_e64;
4278 case AMDGPU::V_MAC_LEGACY_F32_e32:
4279 case AMDGPU::V_MAC_LEGACY_F32_e64:
4280 return AMDGPU::V_MAD_LEGACY_F32_e64;
4281 case AMDGPU::V_FMAC_LEGACY_F32_e32:
4282 case AMDGPU::V_FMAC_LEGACY_F32_e64:
4283 return AMDGPU::V_FMA_LEGACY_F32_e64;
4284 case AMDGPU::V_FMAC_F16_e32:
4285 case AMDGPU::V_FMAC_F16_e64:
4286 case AMDGPU::V_FMAC_F16_t16_e64:
4287 case AMDGPU::V_FMAC_F16_fake16_e64:
4288 return ST.hasTrue16BitInsts() ? ST.useRealTrue16Insts()
4289 ? AMDGPU::V_FMA_F16_gfx9_t16_e64
4290 : AMDGPU::V_FMA_F16_gfx9_fake16_e64
4291 : AMDGPU::V_FMA_F16_gfx9_e64;
4292 case AMDGPU::V_FMAC_F32_e32:
4293 case AMDGPU::V_FMAC_F32_e64:
4294 return AMDGPU::V_FMA_F32_e64;
4295 case AMDGPU::V_FMAC_F64_e32:
4296 case AMDGPU::V_FMAC_F64_e64:
4297 return AMDGPU::V_FMA_F64_e64;
4298 default:
4299 llvm_unreachable("invalid instruction");
4300 }
4301}
4302
4303/// Helper struct for the implementation of 3-address conversion to communicate
4304/// updates made to instruction operands.
4306 /// Other instruction whose def is no longer used by the converted
4307 /// instruction.
4309};
4310
4312 LiveVariables *LV,
4313 LiveIntervals *LIS) const {
4314 MachineBasicBlock &MBB = *MI.getParent();
4315 MachineInstr *CandidateMI = &MI;
4316
4317 if (MI.isBundle()) {
4318 // This is a temporary placeholder for bundle handling that enables us to
4319 // exercise the relevant code paths in the two-address instruction pass.
4320 if (MI.getBundleSize() != 1)
4321 return nullptr;
4322 CandidateMI = MI.getNextNode();
4323 }
4324
4326 MachineInstr *NewMI = convertToThreeAddressImpl(*CandidateMI, U);
4327 if (!NewMI)
4328 return nullptr;
4329
4330 if (MI.isBundle()) {
4331 CandidateMI->eraseFromBundle();
4332
4333 for (MachineOperand &MO : MI.all_defs()) {
4334 if (MO.isTied())
4335 MI.untieRegOperand(MO.getOperandNo());
4336 }
4337 } else {
4338 updateLiveVariables(LV, MI, *NewMI);
4339 if (LIS) {
4340 LIS->ReplaceMachineInstrInMaps(MI, *NewMI);
4341 // SlotIndex of defs needs to be updated when converting to early-clobber
4342 MachineOperand &Def = NewMI->getOperand(0);
4343 if (Def.isEarlyClobber() && Def.isReg() &&
4344 LIS->hasInterval(Def.getReg())) {
4345 SlotIndex OldIndex = LIS->getInstructionIndex(*NewMI).getRegSlot(false);
4346 SlotIndex NewIndex = LIS->getInstructionIndex(*NewMI).getRegSlot(true);
4347 auto &LI = LIS->getInterval(Def.getReg());
4348 auto UpdateDefIndex = [&](LiveRange &LR) {
4349 auto *S = LR.find(OldIndex);
4350 if (S != LR.end() && S->start == OldIndex) {
4351 assert(S->valno && S->valno->def == OldIndex);
4352 S->start = NewIndex;
4353 S->valno->def = NewIndex;
4354 }
4355 };
4356 UpdateDefIndex(LI);
4357 for (auto &SR : LI.subranges())
4358 UpdateDefIndex(SR);
4359 }
4360 }
4361 }
4362
4363 if (U.RemoveMIUse) {
4364 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
4365 // The only user is the instruction which will be killed.
4366 Register DefReg = U.RemoveMIUse->getOperand(0).getReg();
4367
4368 if (MRI.hasOneNonDBGUse(DefReg)) {
4369 // We cannot just remove the DefMI here, calling pass will crash.
4370 U.RemoveMIUse->setDesc(get(AMDGPU::IMPLICIT_DEF));
4371 U.RemoveMIUse->getOperand(0).setIsDead(true);
4372 for (unsigned I = U.RemoveMIUse->getNumOperands() - 1; I != 0; --I)
4373 U.RemoveMIUse->removeOperand(I);
4374 if (LV)
4375 LV->getVarInfo(DefReg).AliveBlocks.clear();
4376 }
4377
4378 if (MI.isBundle()) {
4379 VirtRegInfo VRI = AnalyzeVirtRegInBundle(MI, DefReg);
4380 if (!VRI.Reads && !VRI.Writes) {
4381 for (MachineOperand &MO : MI.all_uses()) {
4382 if (MO.isReg() && MO.getReg() == DefReg) {
4383 assert(MO.getSubReg() == 0 &&
4384 "tied sub-registers in bundles currently not supported");
4385 MI.removeOperand(MO.getOperandNo());
4386 break;
4387 }
4388 }
4389
4390 if (LIS)
4391 LIS->shrinkToUses(&LIS->getInterval(DefReg));
4392 }
4393 } else if (LIS) {
4394 LiveInterval &DefLI = LIS->getInterval(DefReg);
4395
4396 // We cannot delete the original instruction here, so hack out the use
4397 // in the original instruction with a dummy register so we can use
4398 // shrinkToUses to deal with any multi-use edge cases. Other targets do
4399 // not have the complexity of deleting a use to consider here.
4400 Register DummyReg = MRI.cloneVirtualRegister(DefReg);
4401 for (MachineOperand &MIOp : MI.uses()) {
4402 if (MIOp.isReg() && MIOp.getReg() == DefReg) {
4403 MIOp.setIsUndef(true);
4404 MIOp.setReg(DummyReg);
4405 }
4406 }
4407
4408 if (MI.isBundle()) {
4409 VirtRegInfo VRI = AnalyzeVirtRegInBundle(MI, DefReg);
4410 if (!VRI.Reads && !VRI.Writes) {
4411 for (MachineOperand &MIOp : MI.uses()) {
4412 if (MIOp.isReg() && MIOp.getReg() == DefReg) {
4413 MIOp.setIsUndef(true);
4414 MIOp.setReg(DummyReg);
4415 }
4416 }
4417 }
4418
4419 MI.addOperand(MachineOperand::CreateReg(DummyReg, false, false, false,
4420 false, /*isUndef=*/true));
4421 }
4422
4423 LIS->shrinkToUses(&DefLI);
4424 }
4425 }
4426
4427 return MI.isBundle() ? &MI : NewMI;
4428}
4429
4431SIInstrInfo::convertToThreeAddressImpl(MachineInstr &MI,
4432 ThreeAddressUpdates &U) const {
4433 MachineBasicBlock &MBB = *MI.getParent();
4434 unsigned Opc = MI.getOpcode();
4435
4436 // Handle MFMA.
4437 int NewMFMAOpc = AMDGPU::getMFMAEarlyClobberOp(Opc);
4438 if (NewMFMAOpc != -1) {
4440 BuildMI(MBB, MI, MI.getDebugLoc(), get(NewMFMAOpc));
4441 for (unsigned I = 0, E = MI.getNumExplicitOperands(); I != E; ++I)
4442 MIB.add(MI.getOperand(I));
4443 return MIB;
4444 }
4445
4446 if (SIInstrInfo::isWMMA(MI)) {
4447 unsigned NewOpc = AMDGPU::mapWMMA2AddrTo3AddrOpcode(MI.getOpcode());
4448 MachineInstrBuilder MIB = BuildMI(MBB, MI, MI.getDebugLoc(), get(NewOpc))
4449 .setMIFlags(MI.getFlags());
4450 for (unsigned I = 0, E = MI.getNumExplicitOperands(); I != E; ++I)
4451 MIB->addOperand(MI.getOperand(I));
4452 return MIB;
4453 }
4454
4455 assert(Opc != AMDGPU::V_FMAC_F16_t16_e32 &&
4456 Opc != AMDGPU::V_FMAC_F16_fake16_e32 &&
4457 "V_FMAC_F16_t16/fake16_e32 is not supported and not expected to be "
4458 "present pre-RA");
4459
4460 // Handle MAC/FMAC.
4461 bool IsF64 = Opc == AMDGPU::V_FMAC_F64_e32 || Opc == AMDGPU::V_FMAC_F64_e64;
4462 bool IsLegacy = Opc == AMDGPU::V_MAC_LEGACY_F32_e32 ||
4463 Opc == AMDGPU::V_MAC_LEGACY_F32_e64 ||
4464 Opc == AMDGPU::V_FMAC_LEGACY_F32_e32 ||
4465 Opc == AMDGPU::V_FMAC_LEGACY_F32_e64;
4466 bool Src0Literal = false;
4467
4468 switch (Opc) {
4469 default:
4470 return nullptr;
4471 case AMDGPU::V_MAC_F16_e64:
4472 case AMDGPU::V_FMAC_F16_e64:
4473 case AMDGPU::V_FMAC_F16_t16_e64:
4474 case AMDGPU::V_FMAC_F16_fake16_e64:
4475 case AMDGPU::V_MAC_F32_e64:
4476 case AMDGPU::V_MAC_LEGACY_F32_e64:
4477 case AMDGPU::V_FMAC_F32_e64:
4478 case AMDGPU::V_FMAC_LEGACY_F32_e64:
4479 case AMDGPU::V_FMAC_F64_e64:
4480 break;
4481 case AMDGPU::V_MAC_F16_e32:
4482 case AMDGPU::V_FMAC_F16_e32:
4483 case AMDGPU::V_MAC_F32_e32:
4484 case AMDGPU::V_MAC_LEGACY_F32_e32:
4485 case AMDGPU::V_FMAC_F32_e32:
4486 case AMDGPU::V_FMAC_LEGACY_F32_e32:
4487 case AMDGPU::V_FMAC_F64_e32: {
4488 int Src0Idx = AMDGPU::getNamedOperandIdx(MI.getOpcode(),
4489 AMDGPU::OpName::src0);
4490 const MachineOperand *Src0 = &MI.getOperand(Src0Idx);
4491 if (!Src0->isReg() && !Src0->isImm())
4492 return nullptr;
4493
4494 if (Src0->isImm() && !isInlineConstant(MI, Src0Idx, *Src0))
4495 Src0Literal = true;
4496
4497 break;
4498 }
4499 }
4500
4501 MachineInstrBuilder MIB;
4502 const MachineOperand *Dst = getNamedOperand(MI, AMDGPU::OpName::vdst);
4503 const MachineOperand *Src0 = getNamedOperand(MI, AMDGPU::OpName::src0);
4504 const MachineOperand *Src0Mods =
4505 getNamedOperand(MI, AMDGPU::OpName::src0_modifiers);
4506 const MachineOperand *Src1 = getNamedOperand(MI, AMDGPU::OpName::src1);
4507 const MachineOperand *Src1Mods =
4508 getNamedOperand(MI, AMDGPU::OpName::src1_modifiers);
4509 const MachineOperand *Src2 = getNamedOperand(MI, AMDGPU::OpName::src2);
4510 const MachineOperand *Src2Mods =
4511 getNamedOperand(MI, AMDGPU::OpName::src2_modifiers);
4512 const MachineOperand *Clamp = getNamedOperand(MI, AMDGPU::OpName::clamp);
4513 const MachineOperand *Omod = getNamedOperand(MI, AMDGPU::OpName::omod);
4514 const MachineOperand *OpSel = getNamedOperand(MI, AMDGPU::OpName::op_sel);
4515
4516 if (!Src0Mods && !Src1Mods && !Src2Mods && !Clamp && !Omod && !IsLegacy &&
4517 (!IsF64 || ST.hasFmaakFmamkF64Insts()) &&
4518 // If we have an SGPR input, we will violate the constant bus restriction.
4519 (ST.getConstantBusLimit(Opc) > 1 || !Src0->isReg() ||
4520 !RI.isSGPRReg(MBB.getParent()->getRegInfo(), Src0->getReg()))) {
4521 MachineInstr *DefMI = nullptr;
4522 const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
4523 std::optional<int64_t> ImmOpt;
4524 int64_t Imm;
4525
4526 if (!Src0Literal &&
4527 (ImmOpt = getImmOrMaterializedImm(MRI, *Src2, &DefMI))) {
4528 unsigned NewOpc = getNewFMAAKInst(ST, Opc);
4529 if (pseudoToMCOpcode(NewOpc) != -1) {
4530 MIB = BuildMI(MBB, MI, MI.getDebugLoc(), get(NewOpc))
4531 .add(*Dst)
4532 .add(*Src0)
4533 .add(*Src1)
4534 .addImm(*ImmOpt)
4535 .setMIFlags(MI.getFlags());
4536 U.RemoveMIUse = DefMI;
4537 return MIB;
4538 }
4539 }
4540 unsigned NewOpc = getNewFMAMKInst(ST, Opc);
4541 if (!Src0Literal &&
4542 (ImmOpt = getImmOrMaterializedImm(MRI, *Src1, &DefMI))) {
4543 if (pseudoToMCOpcode(NewOpc) != -1) {
4544 MIB = BuildMI(MBB, MI, MI.getDebugLoc(), get(NewOpc))
4545 .add(*Dst)
4546 .add(*Src0)
4547 .addImm(*ImmOpt)
4548 .add(*Src2)
4549 .setMIFlags(MI.getFlags());
4550 U.RemoveMIUse = DefMI;
4551 return MIB;
4552 }
4553 }
4554 if ((ImmOpt = getImmOrMaterializedImm(MRI, *Src0, &DefMI))) {
4555 Imm = *ImmOpt;
4556 if (pseudoToMCOpcode(NewOpc) != -1 &&
4558 MI, AMDGPU::getNamedOperandIdx(NewOpc, AMDGPU::OpName::src0),
4559 Src1)) {
4560 MIB = BuildMI(MBB, MI, MI.getDebugLoc(), get(NewOpc))
4561 .add(*Dst)
4562 .add(*Src1)
4563 .addImm(Imm)
4564 .add(*Src2)
4565 .setMIFlags(MI.getFlags());
4566 U.RemoveMIUse = DefMI;
4567 return MIB;
4568 }
4569 }
4570 }
4571
4572 // VOP2 mac/fmac with a literal operand cannot be converted to VOP3 mad/fma
4573 // if VOP3 does not allow a literal operand.
4574 if (Src0Literal && !ST.hasVOP3Literal())
4575 return nullptr;
4576
4577 unsigned NewOpc = getNewFMAInst(ST, Opc);
4578
4579 if (pseudoToMCOpcode(NewOpc) == -1)
4580 return nullptr;
4581
4582 MIB = BuildMI(MBB, MI, MI.getDebugLoc(), get(NewOpc))
4583 .add(*Dst)
4584 .addImm(Src0Mods ? Src0Mods->getImm() : 0)
4585 .add(*Src0)
4586 .addImm(Src1Mods ? Src1Mods->getImm() : 0)
4587 .add(*Src1)
4588 .addImm(Src2Mods ? Src2Mods->getImm() : 0)
4589 .add(*Src2)
4590 .addImm(Clamp ? Clamp->getImm() : 0)
4591 .addImm(Omod ? Omod->getImm() : 0)
4592 .setMIFlags(MI.getFlags());
4593 if (AMDGPU::hasNamedOperand(NewOpc, AMDGPU::OpName::op_sel))
4594 MIB.addImm(OpSel ? OpSel->getImm() : 0);
4595 return MIB;
4596}
4597
4598// It's not generally safe to move VALU instructions across these since it will
4599// start using the register as a base index rather than directly.
4600// XXX - Why isn't hasSideEffects sufficient for these?
4602 switch (MI.getOpcode()) {
4603 case AMDGPU::S_SET_GPR_IDX_ON:
4604 case AMDGPU::S_SET_GPR_IDX_MODE:
4605 case AMDGPU::S_SET_GPR_IDX_OFF:
4606 return true;
4607 default:
4608 return false;
4609 }
4610}
4611
4613 const MachineBasicBlock *MBB,
4614 const MachineFunction &MF) const {
4615 // Skipping the check for SP writes in the base implementation. The reason it
4616 // was added was apparently due to compile time concerns.
4617 //
4618 // TODO: Do we really want this barrier? It triggers unnecessary hazard nops
4619 // but is probably avoidable.
4620
4621 // Copied from base implementation.
4622 // Terminators and labels can't be scheduled around.
4623 if (MI.isTerminator() || MI.isPosition())
4624 return true;
4625
4626 // INLINEASM_BR can jump to another block
4627 if (MI.getOpcode() == TargetOpcode::INLINEASM_BR)
4628 return true;
4629
4630 if (MI.getOpcode() == AMDGPU::SCHED_BARRIER && MI.getOperand(0).getImm() == 0)
4631 return true;
4632
4633 // Target-independent instructions do not have an implicit-use of EXEC, even
4634 // when they operate on VGPRs. Treating EXEC modifications as scheduling
4635 // boundaries prevents incorrect movements of such instructions.
4636 return MI.modifiesRegister(AMDGPU::EXEC, &RI) ||
4637 MI.getOpcode() == AMDGPU::S_SETREG_IMM32_B32 ||
4638 MI.getOpcode() == AMDGPU::S_SETREG_B32 ||
4639 MI.getOpcode() == AMDGPU::S_SETPRIO ||
4640 MI.getOpcode() == AMDGPU::S_SETPRIO_INC_WG ||
4642}
4643
4645 return Opcode == AMDGPU::DS_ORDERED_COUNT ||
4646 Opcode == AMDGPU::DS_ADD_GS_REG_RTN ||
4647 Opcode == AMDGPU::DS_SUB_GS_REG_RTN || isGWS(Opcode);
4648}
4649
4651 // Instructions that access scratch use FLAT encoding or BUF encodings.
4652 if ((!isFLAT(MI) || isFLATGlobal(MI)) && !isBUF(MI))
4653 return false;
4654
4655 // SCRATCH instructions always access scratch.
4656 if (isFLATScratch(MI))
4657 return true;
4658
4659 // If FLAT_SCRATCH registers are not initialized, we can never access scratch
4660 // via the aperture.
4661 if (MI.getMF()->getFunction().hasFnAttribute("amdgpu-no-flat-scratch-init"))
4662 return false;
4663
4664 // If there are no memory operands then conservatively assume the flat
4665 // operation may access scratch.
4666 if (MI.memoperands_empty())
4667 return true;
4668
4669 // See if any memory operand specifies an address space that involves scratch.
4670 return any_of(MI.memoperands(), [](const MachineMemOperand *Memop) {
4671 unsigned AS = Memop->getAddrSpace();
4672 if (AS == AMDGPUAS::FLAT_ADDRESS) {
4673 const MDNode *MD = Memop->getAAInfo().NoAliasAddrSpace;
4674 return !MD || !AMDGPU::hasValueInRangeLikeMetadata(
4675 *MD, AMDGPUAS::PRIVATE_ADDRESS);
4676 }
4677 return AS == AMDGPUAS::PRIVATE_ADDRESS;
4678 });
4679}
4680
4682 assert(isFLAT(MI));
4683
4684 // All flat instructions use the VMEM counter except prefetch.
4685 if (!usesVM_CNT(MI))
4686 return false;
4687
4688 // If there are no memory operands then conservatively assume the flat
4689 // operation may access VMEM.
4690 if (MI.memoperands_empty())
4691 return true;
4692
4693 // See if any memory operand specifies an address space that involves VMEM.
4694 // Flat operations only supported FLAT, LOCAL (LDS), or address spaces
4695 // involving VMEM such as GLOBAL, CONSTANT, PRIVATE (SCRATCH), etc. The REGION
4696 // (GDS) address space is not supported by flat operations. Therefore, simply
4697 // return true unless only the LDS address space is found.
4698 for (const MachineMemOperand *Memop : MI.memoperands()) {
4699 unsigned AS = Memop->getAddrSpace();
4701 if (AS != AMDGPUAS::LOCAL_ADDRESS)
4702 return true;
4703 }
4704
4705 return false;
4706}
4707
4709 bool TgSplit) const {
4710 assert(isFLAT(MI));
4711
4712 // Flat instruction such as SCRATCH and GLOBAL do not use the lgkm counter.
4713 if (!usesLGKM_CNT(MI))
4714 return false;
4715
4716 // If in tgsplit mode then there can be no use of LDS.
4717 if (TgSplit)
4718 return false;
4719
4720 // If there are no memory operands then conservatively assume the flat
4721 // operation may access LDS.
4722 if (MI.memoperands_empty())
4723 return true;
4724
4725 // See if any memory operand specifies an address space that involves LDS.
4726 for (const MachineMemOperand *Memop : MI.memoperands()) {
4727 unsigned AS = Memop->getAddrSpace();
4729 return true;
4730 }
4731
4732 return false;
4733}
4734
4736 // Skip the full operand and register alias search modifiesRegister
4737 // does. There's only a handful of instructions that touch this, it's only an
4738 // implicit def, and doesn't alias any other registers.
4739 return is_contained(MI.getDesc().implicit_defs(), AMDGPU::MODE);
4740}
4741
4743 unsigned Opcode = MI.getOpcode();
4744
4745 if (MI.mayStore() && isSMRD(MI))
4746 return true; // scalar store or atomic
4747
4748 // This will terminate the function when other lanes may need to continue.
4749 if (MI.isReturn())
4750 return true;
4751
4752 // These instructions cause shader I/O that may cause hardware lockups
4753 // when executed with an empty EXEC mask.
4754 //
4755 // Note: exp with VM = DONE = 0 is automatically skipped by hardware when
4756 // EXEC = 0, but checking for that case here seems not worth it
4757 // given the typical code patterns.
4758 if (Opcode == AMDGPU::S_SENDMSG || Opcode == AMDGPU::S_SENDMSGHALT ||
4759 isEXP(Opcode) || Opcode == AMDGPU::DS_ORDERED_COUNT ||
4760 Opcode == AMDGPU::S_TRAP || Opcode == AMDGPU::S_WAIT_EVENT ||
4761 Opcode == AMDGPU::S_SETHALT)
4762 return true;
4763
4764 if (MI.isCall() || MI.isInlineAsm())
4765 return true; // conservative assumption
4766
4767 // Assume that barrier interactions are only intended with active lanes.
4768 if (isBarrier(Opcode))
4769 return true;
4770
4771 // A mode change is a scalar operation that influences vector instructions.
4773 return true;
4774
4775 // These are like SALU instructions in terms of effects, so it's questionable
4776 // whether we should return true for those.
4777 //
4778 // However, executing them with EXEC = 0 causes them to operate on undefined
4779 // data, which we avoid by returning true here.
4780 if (Opcode == AMDGPU::V_READFIRSTLANE_B32 ||
4781 Opcode == AMDGPU::V_READLANE_B32 || Opcode == AMDGPU::V_WRITELANE_B32 ||
4782 Opcode == AMDGPU::SI_RESTORE_S32_FROM_VGPR ||
4783 Opcode == AMDGPU::SI_SPILL_S32_TO_VGPR)
4784 return true;
4785
4786 return false;
4787}
4788
4790 const MachineInstr &MI) const {
4791 if (MI.isMetaInstruction())
4792 return false;
4793
4794 // This won't read exec if this is an SGPR->SGPR copy.
4795 if (MI.isCopyLike()) {
4796 if (!RI.isSGPRReg(MRI, MI.getOperand(0).getReg()))
4797 return true;
4798
4799 // Make sure this isn't copying exec as a normal operand
4800 return MI.readsRegister(AMDGPU::EXEC, &RI);
4801 }
4802
4803 // Make a conservative assumption about the callee.
4804 if (MI.isCall())
4805 return true;
4806
4807 // Be conservative with any unhandled generic opcodes.
4808 if (!isTargetSpecificOpcode(MI.getOpcode()))
4809 return true;
4810
4811 return !isSALU(MI) || MI.readsRegister(AMDGPU::EXEC, &RI);
4812}
4813
4815 switch (Imm.getBitWidth()) {
4816 case 1: // This likely will be a condition code mask.
4817 return true;
4818
4819 case 32:
4820 return AMDGPU::isInlinableLiteral32(Imm.getSExtValue(),
4821 ST.hasInv2PiInlineImm());
4822 case 64:
4823 return AMDGPU::isInlinableLiteral64(Imm.getSExtValue(),
4824 ST.hasInv2PiInlineImm());
4825 case 16:
4826 return ST.has16BitInsts() &&
4827 AMDGPU::isInlinableLiteralI16(Imm.getSExtValue(),
4828 ST.hasInv2PiInlineImm());
4829 default:
4830 llvm_unreachable("invalid bitwidth");
4831 }
4832}
4833
4835 APInt IntImm = Imm.bitcastToAPInt();
4836 int64_t IntImmVal = IntImm.getSExtValue();
4837 bool HasInv2Pi = ST.hasInv2PiInlineImm();
4838 switch (APFloat::SemanticsToEnum(Imm.getSemantics())) {
4839 default:
4840 llvm_unreachable("invalid fltSemantics");
4843 return isInlineConstant(IntImm);
4845 return ST.has16BitInsts() &&
4846 AMDGPU::isInlinableLiteralBF16(IntImmVal, HasInv2Pi);
4848 return ST.has16BitInsts() &&
4849 AMDGPU::isInlinableLiteralFP16(IntImmVal, HasInv2Pi);
4850 }
4851}
4852
4853bool SIInstrInfo::isInlineConstant(int64_t Imm, uint8_t OperandType) const {
4854 // MachineOperand provides no way to tell the true operand size, since it only
4855 // records a 64-bit value. We need to know the size to determine if a 32-bit
4856 // floating point immediate bit pattern is legal for an integer immediate. It
4857 // would be for any 32-bit integer operand, but would not be for a 64-bit one.
4858 switch (OperandType) {
4868 int32_t Trunc = static_cast<int32_t>(Imm);
4869 return AMDGPU::isInlinableLiteral32(Trunc, ST.hasInv2PiInlineImm());
4870 }
4878 return AMDGPU::isInlinableLiteral64(Imm, ST.hasInv2PiInlineImm());
4881 // We would expect inline immediates to not be concerned with an integer/fp
4882 // distinction. However, in the case of 16-bit integer operations, the
4883 // "floating point" values appear to not work. It seems read the low 16-bits
4884 // of 32-bit immediates, which happens to always work for the integer
4885 // values.
4886 //
4887 // See llvm bugzilla 46302.
4888 //
4889 // TODO: Theoretically we could use op-sel to use the high bits of the
4890 // 32-bit FP values.
4899 return AMDGPU::isPKFMACF16InlineConstant(Imm, ST.isGFX11Plus());
4904 return false;
4907 if (isInt<16>(Imm) || isUInt<16>(Imm)) {
4908 // A few special case instructions have 16-bit operands on subtargets
4909 // where 16-bit instructions are not legal.
4910 // TODO: Do the 32-bit immediates work? We shouldn't really need to handle
4911 // constants in these cases
4912 int16_t Trunc = static_cast<int16_t>(Imm);
4913 return ST.has16BitInsts() &&
4914 AMDGPU::isInlinableLiteralFP16(Trunc, ST.hasInv2PiInlineImm());
4915 }
4916
4917 return false;
4918 }
4921 if (isInt<16>(Imm) || isUInt<16>(Imm)) {
4922 int16_t Trunc = static_cast<int16_t>(Imm);
4923 return ST.has16BitInsts() &&
4924 AMDGPU::isInlinableLiteralBF16(Trunc, ST.hasInv2PiInlineImm());
4925 }
4926 return false;
4927 }
4931 return false;
4933 return isLegalAV64PseudoImm(Imm);
4936 // Always embedded in the instruction for free.
4937 return true;
4947 // Just ignore anything else.
4948 return false;
4949 default:
4950 llvm_unreachable("invalid operand type");
4951 }
4952}
4953
4954static bool compareMachineOp(const MachineOperand &Op0,
4955 const MachineOperand &Op1) {
4956 if (Op0.getType() != Op1.getType())
4957 return false;
4958
4959 switch (Op0.getType()) {
4961 return Op0.getReg() == Op1.getReg();
4963 return Op0.getImm() == Op1.getImm();
4964 default:
4965 llvm_unreachable("Didn't expect to be comparing these operand types");
4966 }
4967}
4968
4970 const MCOperandInfo &OpInfo) const {
4971 if (OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE)
4972 return true;
4973
4974 if (!RI.opCanUseLiteralConstant(OpInfo.OperandType))
4975 return false;
4976
4977 if (!isVOP3(InstDesc) || !AMDGPU::isSISrcOperand(OpInfo))
4978 return true;
4979
4980 return ST.hasVOP3Literal();
4981}
4982
4983bool SIInstrInfo::isImmOperandLegal(const MCInstrDesc &InstDesc, unsigned OpNo,
4984 int64_t ImmVal) const {
4985 const unsigned Opc = InstDesc.getOpcode();
4986 int Src1Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src1);
4987 if (Src1Idx != -1 && isDPP(Opc) && !ST.hasDPPSrc1SGPR() &&
4988 OpNo == static_cast<unsigned>(Src1Idx))
4989 return false;
4990
4991 const MCOperandInfo &OpInfo = InstDesc.operands()[OpNo];
4992 if (isInlineConstant(ImmVal, OpInfo.OperandType)) {
4993 if (isMAI(InstDesc) && ST.hasMFMAInlineLiteralBug() &&
4994 OpNo == (unsigned)AMDGPU::getNamedOperandIdx(InstDesc.getOpcode(),
4995 AMDGPU::OpName::src2))
4996 return false;
4997
4998 if (ST.hasBF16InlineConstFromUpperFP32() && isVOP1(Opc)) {
4999 if ((OpInfo.OperandType == AMDGPU::OPERAND_REG_IMM_BF16 ||
5000 OpInfo.OperandType == AMDGPU::OPERAND_REG_INLINE_C_BF16) &&
5001 isInlineConstant(ImmVal, OpInfo.OperandType))
5002 return false;
5003 }
5004
5005 return RI.opCanUseInlineConstant(OpInfo.OperandType);
5006 }
5007
5008 return isLiteralOperandLegal(InstDesc, OpInfo);
5009}
5010
5011bool SIInstrInfo::isImmOperandLegal(const MCInstrDesc &InstDesc, unsigned OpNo,
5012 const MachineOperand &MO) const {
5013 if (MO.isImm())
5014 return isImmOperandLegal(InstDesc, OpNo, MO.getImm());
5015
5016 assert((MO.isTargetIndex() || MO.isFI() || MO.isGlobal()) &&
5017 "unexpected imm-like operand kind");
5018 const MCOperandInfo &OpInfo = InstDesc.operands()[OpNo];
5019 return isLiteralOperandLegal(InstDesc, OpInfo);
5020}
5021
5023 // 2 32-bit inline constants packed into one.
5024 return AMDGPU::isInlinableLiteral32(Lo_32(Imm), ST.hasInv2PiInlineImm()) &&
5025 AMDGPU::isInlinableLiteral32(Hi_32(Imm), ST.hasInv2PiInlineImm());
5026}
5027
5028bool SIInstrInfo::hasVALU32BitEncoding(unsigned Opcode) const {
5029 // GFX90A does not have V_MUL_LEGACY_F32_e32.
5030 if (Opcode == AMDGPU::V_MUL_LEGACY_F32_e64 && ST.hasGFX90AInsts())
5031 return false;
5032
5033 int Op32 = AMDGPU::getVOPe32(Opcode);
5034 if (Op32 == -1)
5035 return false;
5036
5037 return pseudoToMCOpcode(Op32) != -1;
5038}
5039
5040bool SIInstrInfo::hasModifiers(unsigned Opcode) const {
5041 // The src0_modifier operand is present on all instructions
5042 // that have modifiers.
5043
5044 return AMDGPU::hasNamedOperand(Opcode, AMDGPU::OpName::src0_modifiers);
5045}
5046
5048 AMDGPU::OpName OpName) const {
5049 const MachineOperand *Mods = getNamedOperand(MI, OpName);
5050 return Mods && Mods->getImm();
5051}
5052
5054 return any_of(ModifierOpNames,
5055 [&](AMDGPU::OpName Name) { return hasModifiersSet(MI, Name); });
5056}
5057
5059 const MachineRegisterInfo &MRI) const {
5060 const MachineOperand *Src2 = getNamedOperand(MI, AMDGPU::OpName::src2);
5061 // Can't shrink instruction with three operands.
5062 if (Src2) {
5063 switch (MI.getOpcode()) {
5064 default: return false;
5065
5066 case AMDGPU::V_ADDC_U32_e64:
5067 case AMDGPU::V_SUBB_U32_e64:
5068 case AMDGPU::V_SUBBREV_U32_e64: {
5069 const MachineOperand *Src1
5070 = getNamedOperand(MI, AMDGPU::OpName::src1);
5071 if (!Src1->isReg() || !RI.isVGPR(MRI, Src1->getReg()))
5072 return false;
5073 // Additional verification is needed for sdst/src2.
5074 return true;
5075 }
5076 case AMDGPU::V_MAC_F16_e64:
5077 case AMDGPU::V_MAC_F32_e64:
5078 case AMDGPU::V_MAC_LEGACY_F32_e64:
5079 case AMDGPU::V_FMAC_F16_e64:
5080 case AMDGPU::V_FMAC_F16_t16_e64:
5081 case AMDGPU::V_FMAC_F16_fake16_e64:
5082 case AMDGPU::V_FMAC_F32_e64:
5083 case AMDGPU::V_FMAC_F64_e64:
5084 case AMDGPU::V_FMAC_LEGACY_F32_e64:
5085 if (!Src2->isReg() || !RI.isVGPR(MRI, Src2->getReg()) ||
5086 hasModifiersSet(MI, AMDGPU::OpName::src2_modifiers))
5087 return false;
5088 break;
5089
5090 case AMDGPU::V_CNDMASK_B32_e64:
5091 break;
5092 }
5093 }
5094
5095 const MachineOperand *Src1 = getNamedOperand(MI, AMDGPU::OpName::src1);
5096 if (Src1 && (!Src1->isReg() || !RI.isVGPR(MRI, Src1->getReg()) ||
5097 hasModifiersSet(MI, AMDGPU::OpName::src1_modifiers)))
5098 return false;
5099
5100 // Make sure src0 isn't using any modifiers.
5101 if (hasModifiersSet(MI, AMDGPU::OpName::src0_modifiers))
5102 return false;
5103
5104 // Can it be shrunk to a valid 32 bit opcode?
5105 if (!hasVALU32BitEncoding(MI.getOpcode()))
5106 return false;
5107
5108 const MachineOperand *Src0 = getNamedOperand(MI, AMDGPU::OpName::src0);
5109 if (Src0 && Src0->isImm()) {
5110 unsigned Op32 = AMDGPU::getVOPe32(MI.getOpcode());
5111 if (!isImmOperandLegal(
5112 get(Op32), AMDGPU::getNamedOperandIdx(Op32, AMDGPU::OpName::src0),
5113 *Src0))
5114 return false;
5115 }
5116
5117 // Check output modifiers
5118 return !hasModifiersSet(MI, AMDGPU::OpName::omod) &&
5119 !hasModifiersSet(MI, AMDGPU::OpName::clamp) &&
5120 !hasModifiersSet(MI, AMDGPU::OpName::byte_sel) &&
5121 // TODO: Can we avoid checking bound_ctrl/fi here?
5122 // They are only used by permlane*_swap special case.
5123 !hasModifiersSet(MI, AMDGPU::OpName::bound_ctrl) &&
5124 !hasModifiersSet(MI, AMDGPU::OpName::fi);
5125}
5126
5127// Set VCC operand with all flags from \p Orig, except for setting it as
5128// implicit.
5130 const MachineOperand &Orig) {
5131
5132 for (MachineOperand &Use : MI.implicit_operands()) {
5133 if (Use.isUse() &&
5134 (Use.getReg() == AMDGPU::VCC || Use.getReg() == AMDGPU::VCC_LO)) {
5135 Use.setIsUndef(Orig.isUndef());
5136 Use.setIsKill(Orig.isKill());
5137 return;
5138 }
5139 }
5140}
5141
5143 unsigned Op32) const {
5144 MachineBasicBlock *MBB = MI.getParent();
5145
5146 const MCInstrDesc &Op32Desc = get(Op32);
5147 MachineInstrBuilder Inst32 =
5148 BuildMI(*MBB, MI, MI.getDebugLoc(), Op32Desc)
5149 .setMIFlags(MI.getFlags());
5150
5151 // Add the dst operand if the 32-bit encoding also has an explicit $vdst.
5152 // For VOPC instructions, this is replaced by an implicit def of vcc.
5153
5154 // We assume the defs of the shrunk opcode are in the same order, and the
5155 // shrunk opcode loses the last def (SGPR def, in the VOP3->VOPC case).
5156 for (int I = 0, E = Op32Desc.getNumDefs(); I != E; ++I)
5157 Inst32.add(MI.getOperand(I));
5158
5159 const MachineOperand *Src2 = getNamedOperand(MI, AMDGPU::OpName::src2);
5160
5161 int Idx = MI.getNumExplicitDefs();
5162 for (const MachineOperand &Use : MI.explicit_uses()) {
5163 int OpTy = MI.getDesc().operands()[Idx++].OperandType;
5165 continue;
5166
5167 if (&Use == Src2) {
5168 if (AMDGPU::getNamedOperandIdx(Op32, AMDGPU::OpName::src2) == -1) {
5169 // In the case of V_CNDMASK_B32_e32, the explicit operand src2 is
5170 // replaced with an implicit read of vcc or vcc_lo. The implicit read
5171 // of vcc was already added during the initial BuildMI, but we
5172 // 1) may need to change vcc to vcc_lo to preserve the original register
5173 // 2) have to preserve the original flags.
5174 copyFlagsToImplicitVCC(*Inst32, *Src2);
5175 continue;
5176 }
5177 }
5178
5179 Inst32.add(Use);
5180 }
5181
5182 // FIXME: Losing implicit operands
5183 fixImplicitOperands(*Inst32);
5184 return Inst32;
5185}
5186
5188 // Null is free
5189 Register Reg = RegOp.getReg();
5190 if (Reg == AMDGPU::SGPR_NULL || Reg == AMDGPU::SGPR_NULL64)
5191 return false;
5192
5193 // SGPRs use the constant bus
5194
5195 // FIXME: implicit registers that are not part of the MCInstrDesc's implicit
5196 // physical register operands should also count, except for exec.
5197 if (RegOp.isImplicit())
5198 return Reg == AMDGPU::VCC || Reg == AMDGPU::VCC_LO || Reg == AMDGPU::M0;
5199
5200 // SGPRs use the constant bus
5201 return AMDGPU::SReg_32RegClass.contains(Reg) ||
5202 AMDGPU::SReg_64RegClass.contains(Reg);
5203}
5204
5206 const MachineRegisterInfo &MRI) const {
5207 Register Reg = RegOp.getReg();
5208 return Reg.isVirtual() ? RI.isSGPRClass(MRI.getRegClass(Reg))
5209 : physRegUsesConstantBus(RegOp);
5210}
5211
5213 const MachineOperand &MO,
5214 const MCOperandInfo &OpInfo) const {
5215 // Literal constants use the constant bus.
5216 if (!MO.isReg())
5217 return !isInlineConstant(MO, OpInfo);
5218
5219 Register Reg = MO.getReg();
5220 return Reg.isVirtual() ? RI.isSGPRClass(MRI.getRegClass(Reg))
5222}
5223
5225 for (const MachineOperand &MO : MI.implicit_operands()) {
5226 // We only care about reads.
5227 if (MO.isDef())
5228 continue;
5229
5230 switch (MO.getReg()) {
5231 case AMDGPU::VCC:
5232 case AMDGPU::VCC_LO:
5233 case AMDGPU::VCC_HI:
5234 case AMDGPU::M0:
5235 case AMDGPU::FLAT_SCR:
5236 return MO.getReg();
5237
5238 default:
5239 break;
5240 }
5241 }
5242
5243 return Register();
5244}
5245
5246static bool shouldReadExec(const MachineInstr &MI) {
5247 if (SIInstrInfo::isVALU(MI, /*AllowLDSDMA=*/true)) {
5248 switch (MI.getOpcode()) {
5249 case AMDGPU::V_READLANE_B32:
5250 case AMDGPU::SI_RESTORE_S32_FROM_VGPR:
5251 case AMDGPU::V_WRITELANE_B32:
5252 case AMDGPU::SI_SPILL_S32_TO_VGPR:
5253 return false;
5254 }
5255
5256 return true;
5257 }
5258
5259 if (MI.isPreISelOpcode() ||
5260 SIInstrInfo::isGenericOpcode(MI.getOpcode()) ||
5263 return false;
5264
5265 return true;
5266}
5267
5268static bool isRegOrFI(const MachineOperand &MO) {
5269 return MO.isReg() || MO.isFI();
5270}
5271
5272static bool isSubRegOf(const SIRegisterInfo &TRI,
5273 const MachineOperand &SuperVec,
5274 const MachineOperand &SubReg) {
5275 if (SubReg.getReg().isPhysical())
5276 return TRI.isSubRegister(SuperVec.getReg(), SubReg.getReg());
5277
5278 return SubReg.getSubReg() != AMDGPU::NoSubRegister &&
5279 SubReg.getReg() == SuperVec.getReg();
5280}
5281
5282// Verify the illegal copy from vector register to SGPR for generic opcode COPY
5283bool SIInstrInfo::verifyCopy(const MachineInstr &MI,
5284 const MachineRegisterInfo &MRI,
5285 StringRef &ErrInfo) const {
5286 Register DstReg = MI.getOperand(0).getReg();
5287 Register SrcReg = MI.getOperand(1).getReg();
5288 // This is a check for copy from vector register to SGPR
5289 if (RI.isVectorRegister(MRI, SrcReg) && RI.isSGPRReg(MRI, DstReg)) {
5290 ErrInfo = "illegal copy from vector register to SGPR";
5291 return false;
5292 }
5293 return true;
5294}
5295
5297 StringRef &ErrInfo) const {
5298 uint32_t Opcode = MI.getOpcode();
5299 const MachineFunction *MF = MI.getMF();
5300 const MachineRegisterInfo &MRI = MF->getRegInfo();
5301
5302 // FIXME: At this point the COPY verify is done only for non-ssa forms.
5303 // Find a better property to recognize the point where instruction selection
5304 // is just done.
5305 // We can only enforce this check after SIFixSGPRCopies pass so that the
5306 // illegal copies are legalized and thereafter we don't expect a pass
5307 // inserting similar copies.
5308 if (!MRI.isSSA() && MI.isCopy())
5309 return verifyCopy(MI, MRI, ErrInfo);
5310
5311 if (SIInstrInfo::isGenericOpcode(Opcode))
5312 return true;
5313
5314 int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
5315 int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
5316 int Src2Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src2);
5317 int Src3Idx = -1;
5318 if (Src0Idx == -1) {
5319 // VOPD V_DUAL_* instructions use different operand names.
5320 Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0X);
5321 Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::vsrc1X);
5322 Src2Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0Y);
5323 Src3Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::vsrc1Y);
5324 }
5325
5326 // Make sure the number of operands is correct.
5327 const MCInstrDesc &Desc = get(Opcode);
5328 if (!Desc.isVariadic() &&
5329 Desc.getNumOperands() != MI.getNumExplicitOperands()) {
5330 ErrInfo = "Instruction has wrong number of operands.";
5331 return false;
5332 }
5333
5334 if (MI.isInlineAsm()) {
5335 // Verify register classes for inlineasm constraints.
5336 for (unsigned I = InlineAsm::MIOp_FirstOperand, E = MI.getNumOperands();
5337 I != E; ++I) {
5338 const TargetRegisterClass *RC = MI.getRegClassConstraint(I, this, &RI);
5339 if (!RC)
5340 continue;
5341
5342 const MachineOperand &Op = MI.getOperand(I);
5343 if (!Op.isReg())
5344 continue;
5345
5346 Register Reg = Op.getReg();
5347 if (!Reg.isVirtual() && !RC->contains(Reg)) {
5348 ErrInfo = "inlineasm operand has incorrect register class.";
5349 return false;
5350 }
5351 }
5352
5353 return true;
5354 }
5355
5356 if (isImage(MI) && MI.memoperands_empty() && MI.mayLoadOrStore()) {
5357 ErrInfo = "missing memory operand from image instruction.";
5358 return false;
5359 }
5360
5361 // Make sure the register classes are correct.
5362 for (int i = 0, e = Desc.getNumOperands(); i != e; ++i) {
5363 const MachineOperand &MO = MI.getOperand(i);
5364 if (MO.isFPImm()) {
5365 ErrInfo = "FPImm Machine Operands are not supported. ISel should bitcast "
5366 "all fp values to integers.";
5367 return false;
5368 }
5369
5370 const MCOperandInfo &OpInfo = Desc.operands()[i];
5371 int16_t RegClass = getOpRegClassID(OpInfo);
5372
5373 switch (OpInfo.OperandType) {
5375 if (MI.getOperand(i).isImm() || MI.getOperand(i).isGlobal()) {
5376 ErrInfo = "Illegal immediate value for operand.";
5377 return false;
5378 }
5379 break;
5391 break;
5393 break;
5394 break;
5408 if (!MO.isReg() && (!MO.isImm() || !isInlineConstant(MI, i))) {
5409 ErrInfo = "Illegal immediate value for operand.";
5410 return false;
5411 }
5412 break;
5413 }
5418 if (ST.has64BitLiterals() && Desc.getSize() != 4 && MO.isImm() &&
5419 !isInlineConstant(MI, i) &&
5421 OpInfo.OperandType ==
5423 ErrInfo = "illegal 64-bit immediate value for operand.";
5424 return false;
5425 }
5426 break;
5429 if (!MI.getOperand(i).isImm() || !isInlineConstant(MI, i)) {
5430 ErrInfo = "Expected inline constant for operand.";
5431 return false;
5432 }
5433 break;
5436 break;
5441 // Check if this operand is an immediate.
5442 // FrameIndex operands will be replaced by immediates, so they are
5443 // allowed.
5444 if (!MI.getOperand(i).isImm() && !MI.getOperand(i).isFI()) {
5445 ErrInfo = "Expected immediate, but got non-immediate";
5446 return false;
5447 }
5448 break;
5452 break;
5453 default:
5454 if (OpInfo.isGenericType())
5455 continue;
5456 break;
5457 }
5458
5459 if (!MO.isReg())
5460 continue;
5461 Register Reg = MO.getReg();
5462 if (!Reg)
5463 continue;
5464
5465 // FIXME: Ideally we would have separate instruction definitions with the
5466 // aligned register constraint.
5467 // FIXME: We do not verify inline asm operands, but custom inline asm
5468 // verification is broken anyway
5469 if (ST.needsAlignedVGPRs() && Opcode != AMDGPU::AV_MOV_B64_IMM_PSEUDO &&
5470 Opcode != AMDGPU::V_MOV_B64_PSEUDO && !isSpill(MI)) {
5471 const TargetRegisterClass *RC = RI.getRegClassForReg(MRI, Reg);
5472 if (RI.hasVectorRegisters(RC) && MO.getSubReg()) {
5473 if (const TargetRegisterClass *SubRC =
5474 RI.getSubRegisterClass(RC, MO.getSubReg())) {
5475 RC = RI.getCompatibleSubRegClass(RC, SubRC, MO.getSubReg());
5476 if (RC)
5477 RC = SubRC;
5478 }
5479 }
5480
5481 // Check that this is the aligned version of the class.
5482 if (!RC || !RI.isProperlyAlignedRC(*RC)) {
5483 ErrInfo = "Subtarget requires even aligned vector registers";
5484 return false;
5485 }
5486 }
5487
5488 if (RegClass != -1) {
5489 if (Reg.isVirtual())
5490 continue;
5491
5492 const TargetRegisterClass *RC = RI.getRegClass(RegClass);
5493 if (!RC->contains(Reg)) {
5494 ErrInfo = "Operand has incorrect register class.";
5495 return false;
5496 }
5497 }
5498 }
5499
5500 // Verify SDWA
5501 if (isSDWA(MI)) {
5502 if (!ST.hasSDWA()) {
5503 ErrInfo = "SDWA is not supported on this target";
5504 return false;
5505 }
5506
5507 for (auto Op : {AMDGPU::OpName::src0_sel, AMDGPU::OpName::src1_sel,
5508 AMDGPU::OpName::dst_sel}) {
5509 const MachineOperand *MO = getNamedOperand(MI, Op);
5510 if (!MO)
5511 continue;
5512 int64_t Imm = MO->getImm();
5514 ErrInfo = "Invalid SDWA selection";
5515 return false;
5516 }
5517 }
5518
5519 int DstIdx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::vdst);
5520
5521 for (int OpIdx : {DstIdx, Src0Idx, Src1Idx, Src2Idx}) {
5522 if (OpIdx == -1)
5523 continue;
5524 const MachineOperand &MO = MI.getOperand(OpIdx);
5525
5526 if (!ST.hasSDWAScalar()) {
5527 // Only VGPRS on VI
5528 if (!MO.isReg() || !RI.hasVGPRs(RI.getRegClassForReg(MRI, MO.getReg()))) {
5529 ErrInfo = "Only VGPRs allowed as operands in SDWA instructions on VI";
5530 return false;
5531 }
5532 } else {
5533 // No immediates on GFX9
5534 if (!MO.isReg()) {
5535 ErrInfo =
5536 "Only reg allowed as operands in SDWA instructions on GFX9+";
5537 return false;
5538 }
5539 }
5540 }
5541
5542 if (!ST.hasSDWAOmod()) {
5543 // No omod allowed on VI
5544 const MachineOperand *OMod = getNamedOperand(MI, AMDGPU::OpName::omod);
5545 if (OMod != nullptr &&
5546 (!OMod->isImm() || OMod->getImm() != 0)) {
5547 ErrInfo = "OMod not allowed in SDWA instructions on VI";
5548 return false;
5549 }
5550 }
5551
5552 if (Opcode == AMDGPU::V_CVT_F32_FP8_sdwa ||
5553 Opcode == AMDGPU::V_CVT_F32_BF8_sdwa ||
5554 Opcode == AMDGPU::V_CVT_PK_F32_FP8_sdwa ||
5555 Opcode == AMDGPU::V_CVT_PK_F32_BF8_sdwa) {
5556 const MachineOperand *Src0ModsMO =
5557 getNamedOperand(MI, AMDGPU::OpName::src0_modifiers);
5558 unsigned Mods = Src0ModsMO->getImm();
5559 if (Mods & SISrcMods::ABS || Mods & SISrcMods::NEG ||
5560 Mods & SISrcMods::SEXT) {
5561 ErrInfo = "sext, abs and neg are not allowed on this instruction";
5562 return false;
5563 }
5564 }
5565
5566 uint32_t BasicOpcode = AMDGPU::getBasicFromSDWAOp(Opcode);
5567 if (isVOPC(BasicOpcode)) {
5568 if (!ST.hasSDWASdst() && DstIdx != -1) {
5569 // Only vcc allowed as dst on VI for VOPC
5570 const MachineOperand &Dst = MI.getOperand(DstIdx);
5571 if (!Dst.isReg() || Dst.getReg() != AMDGPU::VCC) {
5572 ErrInfo = "Only VCC allowed as dst in SDWA instructions on VI";
5573 return false;
5574 }
5575 } else if (!ST.hasSDWAOutModsVOPC()) {
5576 // No clamp allowed on GFX9 for VOPC
5577 const MachineOperand *Clamp = getNamedOperand(MI, AMDGPU::OpName::clamp);
5578 if (Clamp && (!Clamp->isImm() || Clamp->getImm() != 0)) {
5579 ErrInfo = "Clamp not allowed in VOPC SDWA instructions on VI";
5580 return false;
5581 }
5582
5583 // No omod allowed on GFX9 for VOPC
5584 const MachineOperand *OMod = getNamedOperand(MI, AMDGPU::OpName::omod);
5585 if (OMod && (!OMod->isImm() || OMod->getImm() != 0)) {
5586 ErrInfo = "OMod not allowed in VOPC SDWA instructions on VI";
5587 return false;
5588 }
5589 }
5590 }
5591
5592 const MachineOperand *DstUnused = getNamedOperand(MI, AMDGPU::OpName::dst_unused);
5593 if (DstUnused && DstUnused->isImm() &&
5594 DstUnused->getImm() == AMDGPU::SDWA::UNUSED_PRESERVE) {
5595 const MachineOperand &Dst = MI.getOperand(DstIdx);
5596 if (!Dst.isReg() || !Dst.isTied()) {
5597 ErrInfo = "Dst register should have tied register";
5598 return false;
5599 }
5600
5601 const MachineOperand &TiedMO =
5602 MI.getOperand(MI.findTiedOperandIdx(DstIdx));
5603 if (!TiedMO.isReg() || !TiedMO.isImplicit() || !TiedMO.isUse()) {
5604 ErrInfo =
5605 "Dst register should be tied to implicit use of preserved register";
5606 return false;
5607 }
5608 if (TiedMO.getReg().isPhysical() && Dst.getReg() != TiedMO.getReg()) {
5609 ErrInfo = "Dst register should use same physical register as preserved";
5610 return false;
5611 }
5612 }
5613 }
5614
5615 if (isDPP(MI) && !ST.hasDPPSrc1SGPR() && Src1Idx != -1) {
5616 const MachineOperand &Src1MO = MI.getOperand(Src1Idx);
5617 if (Src1MO.isReg() && RI.isSGPRReg(MRI, Src1MO.getReg())) {
5618 ErrInfo = "DPP src1 cannot be SGPR on this subtarget";
5619 return false;
5620 }
5621 if (Src1MO.isImm()) {
5622 ErrInfo = "DPP src1 cannot be an immediate on this subtarget";
5623 return false;
5624 }
5625 }
5626
5627 // Verify MIMG / VIMAGE / VSAMPLE
5628 if (isImage(Opcode) && !MI.mayStore()) {
5629 // Ensure that the return type used is large enough for all the options
5630 // being used TFE/LWE require an extra result register.
5631 const MachineOperand *DMask = getNamedOperand(MI, AMDGPU::OpName::dmask);
5632 if (DMask) {
5633 uint64_t DMaskImm = DMask->getImm();
5634 uint32_t RegCount = isGather4(Opcode) ? 4 : llvm::popcount(DMaskImm);
5635 const MachineOperand *TFE = getNamedOperand(MI, AMDGPU::OpName::tfe);
5636 const MachineOperand *LWE = getNamedOperand(MI, AMDGPU::OpName::lwe);
5637 const MachineOperand *D16 = getNamedOperand(MI, AMDGPU::OpName::d16);
5638
5639 // Adjust for packed 16 bit values
5640 if (D16 && D16->getImm() && !ST.hasUnpackedD16VMem())
5641 RegCount = divideCeil(RegCount, 2);
5642
5643 // Adjust if using LWE or TFE
5644 if ((LWE && LWE->getImm()) || (TFE && TFE->getImm()))
5645 RegCount += 1;
5646
5647 const uint32_t DstIdx =
5648 AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::vdata);
5649 const MachineOperand &Dst = MI.getOperand(DstIdx);
5650 if (Dst.isReg()) {
5651 const TargetRegisterClass *DstRC = getOpRegClass(MI, DstIdx);
5652 uint32_t DstSize = RI.getRegSizeInBits(*DstRC) / 32;
5653 if (RegCount > DstSize) {
5654 ErrInfo = "Image instruction returns too many registers for dst "
5655 "register class";
5656 return false;
5657 }
5658 }
5659 }
5660 }
5661
5662 // Verify VOP*. Ignore multiple sgpr operands on writelane.
5663 if (isVALU(MI, /*AllowLDSDMA=*/true) &&
5664 Desc.getOpcode() != AMDGPU::V_WRITELANE_B32) {
5665 unsigned ConstantBusCount = 0;
5666 bool UsesLiteral = false;
5667 const MachineOperand *LiteralVal = nullptr;
5668
5669 int ImmIdx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::imm);
5670 if (ImmIdx != -1) {
5671 ++ConstantBusCount;
5672 UsesLiteral = true;
5673 LiteralVal = &MI.getOperand(ImmIdx);
5674 }
5675
5676 SmallVector<Register, 2> SGPRsUsed;
5677 Register SGPRUsed;
5678
5679 // Only look at the true operands. Only a real operand can use the constant
5680 // bus, and we don't want to check pseudo-operands like the source modifier
5681 // flags.
5682 for (int OpIdx : {Src0Idx, Src1Idx, Src2Idx, Src3Idx}) {
5683 if (OpIdx == -1)
5684 continue;
5685 const MachineOperand &MO = MI.getOperand(OpIdx);
5686 if (usesConstantBus(MRI, MO, MI.getDesc().operands()[OpIdx])) {
5687 if (MO.isReg()) {
5688 SGPRUsed = MO.getReg();
5689 if (!llvm::is_contained(SGPRsUsed, SGPRUsed)) {
5690 ++ConstantBusCount;
5691 SGPRsUsed.push_back(SGPRUsed);
5692 }
5693 } else if (!MO.isFI()) { // Treat FI like a register.
5694 if (!UsesLiteral) {
5695 ++ConstantBusCount;
5696 UsesLiteral = true;
5697 LiteralVal = &MO;
5698 } else if (!MO.isIdenticalTo(*LiteralVal)) {
5699 assert(isVOP2(MI) || isVOP3(MI));
5700 ErrInfo = "VOP2/VOP3 instruction uses more than one literal";
5701 return false;
5702 }
5703 }
5704 }
5705 }
5706
5707 SGPRUsed = findImplicitSGPRRead(MI);
5708 if (SGPRUsed) {
5709 // Implicit uses may safely overlap true operands
5710 if (llvm::all_of(SGPRsUsed, [this, SGPRUsed](unsigned SGPR) {
5711 return !RI.regsOverlap(SGPRUsed, SGPR);
5712 })) {
5713 ++ConstantBusCount;
5714 SGPRsUsed.push_back(SGPRUsed);
5715 }
5716 }
5717
5718 // v_writelane_b32 is an exception from constant bus restriction:
5719 // vsrc0 can be sgpr, const or m0 and lane select sgpr, m0 or inline-const
5720 if (ConstantBusCount > ST.getConstantBusLimit(Opcode) &&
5721 Opcode != AMDGPU::V_WRITELANE_B32) {
5722 ErrInfo = "VOP* instruction violates constant bus restriction";
5723 return false;
5724 }
5725
5726 if (isVOP3(MI) && UsesLiteral && !ST.hasVOP3Literal()) {
5727 ErrInfo = "VOP3 instruction uses literal";
5728 return false;
5729 }
5730 }
5731
5732 // Special case for writelane - this can break the multiple constant bus rule,
5733 // but still can't use more than one SGPR register
5734 if (Desc.getOpcode() == AMDGPU::V_WRITELANE_B32) {
5735 unsigned SGPRCount = 0;
5736 Register SGPRUsed;
5737
5738 for (int OpIdx : {Src0Idx, Src1Idx}) {
5739 if (OpIdx == -1)
5740 break;
5741
5742 const MachineOperand &MO = MI.getOperand(OpIdx);
5743
5744 if (usesConstantBus(MRI, MO, MI.getDesc().operands()[OpIdx])) {
5745 if (MO.isReg() && MO.getReg() != AMDGPU::M0) {
5746 if (MO.getReg() != SGPRUsed)
5747 ++SGPRCount;
5748 SGPRUsed = MO.getReg();
5749 }
5750 }
5751 if (SGPRCount > ST.getConstantBusLimit(Opcode)) {
5752 ErrInfo = "WRITELANE instruction violates constant bus restriction";
5753 return false;
5754 }
5755 }
5756 }
5757
5758 // Verify misc. restrictions on specific instructions.
5759 if (Desc.getOpcode() == AMDGPU::V_DIV_SCALE_F32_e64 ||
5760 Desc.getOpcode() == AMDGPU::V_DIV_SCALE_F64_e64) {
5761 const MachineOperand &Src0 = MI.getOperand(Src0Idx);
5762 const MachineOperand &Src1 = MI.getOperand(Src1Idx);
5763 const MachineOperand &Src2 = MI.getOperand(Src2Idx);
5764 if (Src0.isReg() && Src1.isReg() && Src2.isReg()) {
5765 if (!compareMachineOp(Src0, Src1) &&
5766 !compareMachineOp(Src0, Src2)) {
5767 ErrInfo = "v_div_scale_{f32|f64} require src0 = src1 or src2";
5768 return false;
5769 }
5770 }
5771 if ((getNamedOperand(MI, AMDGPU::OpName::src0_modifiers)->getImm() &
5772 SISrcMods::ABS) ||
5773 (getNamedOperand(MI, AMDGPU::OpName::src1_modifiers)->getImm() &
5774 SISrcMods::ABS) ||
5775 (getNamedOperand(MI, AMDGPU::OpName::src2_modifiers)->getImm() &
5776 SISrcMods::ABS)) {
5777 ErrInfo = "ABS not allowed in VOP3B instructions";
5778 return false;
5779 }
5780 }
5781
5782 if (isSOP2(MI) || isSOPC(MI)) {
5783 const MachineOperand &Src0 = MI.getOperand(Src0Idx);
5784 const MachineOperand &Src1 = MI.getOperand(Src1Idx);
5785
5786 if (!isRegOrFI(Src0) && !isRegOrFI(Src1) &&
5787 !isInlineConstant(Src0, Desc.operands()[Src0Idx]) &&
5788 !isInlineConstant(Src1, Desc.operands()[Src1Idx]) &&
5789 !Src0.isIdenticalTo(Src1)) {
5790 ErrInfo = "SOP2/SOPC instruction requires too many immediate constants";
5791 return false;
5792 }
5793 }
5794
5795 if (isSOPK(MI)) {
5796 const auto *Op = getNamedOperand(MI, AMDGPU::OpName::simm16);
5797 if (Desc.isBranch()) {
5798 if (!Op->isMBB()) {
5799 ErrInfo = "invalid branch target for SOPK instruction";
5800 return false;
5801 }
5802 } else {
5803 uint64_t Imm = Op->getImm();
5804 if (sopkIsZext(Opcode)) {
5805 if (!isUInt<16>(Imm)) {
5806 ErrInfo = "invalid immediate for SOPK instruction";
5807 return false;
5808 }
5809 } else {
5810 if (!isInt<16>(Imm)) {
5811 ErrInfo = "invalid immediate for SOPK instruction";
5812 return false;
5813 }
5814 }
5815 }
5816 }
5817
5818 if (Desc.getOpcode() == AMDGPU::V_MOVRELS_B32_e32 ||
5819 Desc.getOpcode() == AMDGPU::V_MOVRELS_B32_e64 ||
5820 Desc.getOpcode() == AMDGPU::V_MOVRELD_B32_e32 ||
5821 Desc.getOpcode() == AMDGPU::V_MOVRELD_B32_e64) {
5822 const bool IsDst = Desc.getOpcode() == AMDGPU::V_MOVRELD_B32_e32 ||
5823 Desc.getOpcode() == AMDGPU::V_MOVRELD_B32_e64;
5824
5825 const unsigned StaticNumOps =
5826 Desc.getNumOperands() + Desc.implicit_uses().size();
5827 const unsigned NumImplicitOps = IsDst ? 2 : 1;
5828
5829 // Require additional implicit operands. This allows a fixup done by the
5830 // post RA scheduler where the main implicit operand is killed and
5831 // implicit-defs are added for sub-registers that remain live after this
5832 // instruction.
5833 if (MI.getNumOperands() < StaticNumOps + NumImplicitOps) {
5834 ErrInfo = "missing implicit register operands";
5835 return false;
5836 }
5837
5838 const MachineOperand *Dst = getNamedOperand(MI, AMDGPU::OpName::vdst);
5839 if (IsDst) {
5840 if (!Dst->isUse()) {
5841 ErrInfo = "v_movreld_b32 vdst should be a use operand";
5842 return false;
5843 }
5844
5845 unsigned UseOpIdx;
5846 if (!MI.isRegTiedToUseOperand(StaticNumOps, &UseOpIdx) ||
5847 UseOpIdx != StaticNumOps + 1) {
5848 ErrInfo = "movrel implicit operands should be tied";
5849 return false;
5850 }
5851 }
5852
5853 const MachineOperand &Src0 = MI.getOperand(Src0Idx);
5854 const MachineOperand &ImpUse
5855 = MI.getOperand(StaticNumOps + NumImplicitOps - 1);
5856 if (!ImpUse.isReg() || !ImpUse.isUse() ||
5857 !isSubRegOf(RI, ImpUse, IsDst ? *Dst : Src0)) {
5858 ErrInfo = "src0 should be subreg of implicit vector use";
5859 return false;
5860 }
5861 }
5862
5863 // Make sure we aren't losing exec uses in the td files. This mostly requires
5864 // being careful when using let Uses to try to add other use registers.
5865 if (shouldReadExec(MI)) {
5866 if (!MI.hasRegisterImplicitUseOperand(AMDGPU::EXEC)) {
5867 ErrInfo = "VALU instruction does not implicitly read exec mask";
5868 return false;
5869 }
5870 }
5871
5872 if (isSMRD(MI)) {
5873 if (MI.mayStore() &&
5874 ST.getGeneration() == AMDGPUSubtarget::VOLCANIC_ISLANDS) {
5875 // The register offset form of scalar stores may only use m0 as the
5876 // soffset register.
5877 const MachineOperand *Soff = getNamedOperand(MI, AMDGPU::OpName::soffset);
5878 if (Soff && Soff->getReg() != AMDGPU::M0) {
5879 ErrInfo = "scalar stores must use m0 as offset register";
5880 return false;
5881 }
5882 }
5883 }
5884
5885 if (isFLAT(MI) && !ST.hasFlatInstOffsets()) {
5886 const MachineOperand *Offset = getNamedOperand(MI, AMDGPU::OpName::offset);
5887 if (Offset->getImm() != 0) {
5888 ErrInfo = "subtarget does not support offsets in flat instructions";
5889 return false;
5890 }
5891 }
5892
5893 if (isDS(MI) && !ST.hasGDS()) {
5894 const MachineOperand *GDSOp = getNamedOperand(MI, AMDGPU::OpName::gds);
5895 if (GDSOp && GDSOp->getImm() != 0) {
5896 ErrInfo = "GDS is not supported on this subtarget";
5897 return false;
5898 }
5899 }
5900
5901 if (isImage(MI)) {
5902 const MachineOperand *DimOp = getNamedOperand(MI, AMDGPU::OpName::dim);
5903 if (DimOp) {
5904 int VAddr0Idx = AMDGPU::getNamedOperandIdx(Opcode,
5905 AMDGPU::OpName::vaddr0);
5906 AMDGPU::OpName RSrcOpName =
5907 isMIMG(MI) ? AMDGPU::OpName::srsrc : AMDGPU::OpName::rsrc;
5908 int RsrcIdx = AMDGPU::getNamedOperandIdx(Opcode, RSrcOpName);
5909 const AMDGPU::MIMGInfo *Info = AMDGPU::getMIMGInfo(Opcode);
5910 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
5911 AMDGPU::getMIMGBaseOpcodeInfo(Info->BaseOpcode);
5912 const AMDGPU::MIMGDimInfo *Dim =
5914
5915 if (!Dim) {
5916 ErrInfo = "dim is out of range";
5917 return false;
5918 }
5919
5920 bool IsA16 = false;
5921 if (ST.hasR128A16()) {
5922 const MachineOperand *R128A16 = getNamedOperand(MI, AMDGPU::OpName::r128);
5923 IsA16 = R128A16->getImm() != 0;
5924 } else if (ST.hasA16()) {
5925 const MachineOperand *A16 = getNamedOperand(MI, AMDGPU::OpName::a16);
5926 IsA16 = A16->getImm() != 0;
5927 }
5928
5929 bool IsNSA = RsrcIdx - VAddr0Idx > 1;
5930
5931 unsigned AddrWords =
5932 AMDGPU::getAddrSizeMIMGOp(BaseOpcode, Dim, IsA16, ST.hasG16());
5933
5934 unsigned VAddrWords;
5935 if (IsNSA) {
5936 VAddrWords = RsrcIdx - VAddr0Idx;
5937 if (ST.hasPartialNSAEncoding() &&
5938 AddrWords > ST.getNSAMaxSize(isVSAMPLE(MI))) {
5939 unsigned LastVAddrIdx = RsrcIdx - 1;
5940 VAddrWords += getOpSize(MI, LastVAddrIdx) / 4 - 1;
5941 }
5942 } else {
5943 VAddrWords = getOpSize(MI, VAddr0Idx) / 4;
5944 if (AddrWords > 12)
5945 AddrWords = 16;
5946 }
5947
5948 if (VAddrWords != AddrWords) {
5949 LLVM_DEBUG(dbgs() << "bad vaddr size, expected " << AddrWords
5950 << " but got " << VAddrWords << "\n");
5951 ErrInfo = "bad vaddr size";
5952 return false;
5953 }
5954 }
5955 }
5956
5957 const MachineOperand *DppCt = getNamedOperand(MI, AMDGPU::OpName::dpp_ctrl);
5958 if (DppCt) {
5959 using namespace AMDGPU::DPP;
5960
5961 unsigned DC = DppCt->getImm();
5962 if (DC == DppCtrl::DPP_UNUSED1 || DC == DppCtrl::DPP_UNUSED2 ||
5963 DC == DppCtrl::DPP_UNUSED3 || DC > DppCtrl::DPP_LAST ||
5964 (DC >= DppCtrl::DPP_UNUSED4_FIRST && DC <= DppCtrl::DPP_UNUSED4_LAST) ||
5965 (DC >= DppCtrl::DPP_UNUSED5_FIRST && DC <= DppCtrl::DPP_UNUSED5_LAST) ||
5966 (DC >= DppCtrl::DPP_UNUSED6_FIRST && DC <= DppCtrl::DPP_UNUSED6_LAST) ||
5967 (DC >= DppCtrl::DPP_UNUSED7_FIRST && DC <= DppCtrl::DPP_UNUSED7_LAST) ||
5968 (DC >= DppCtrl::DPP_UNUSED8_FIRST && DC <= DppCtrl::DPP_UNUSED8_LAST)) {
5969 ErrInfo = "Invalid dpp_ctrl value";
5970 return false;
5971 }
5972 if (DC >= DppCtrl::WAVE_SHL1 && DC <= DppCtrl::WAVE_ROR1 &&
5973 !ST.hasDPPWavefrontShifts()) {
5974 ErrInfo = "Invalid dpp_ctrl value: "
5975 "wavefront shifts are not supported on GFX10+";
5976 return false;
5977 }
5978 if (DC >= DppCtrl::BCAST15 && DC <= DppCtrl::BCAST31 &&
5979 !ST.hasDPPBroadcasts()) {
5980 ErrInfo = "Invalid dpp_ctrl value: "
5981 "broadcasts are not supported on GFX10+";
5982 return false;
5983 }
5984 if (DC >= DppCtrl::ROW_SHARE_FIRST && DC <= DppCtrl::ROW_XMASK_LAST &&
5985 ST.getGeneration() < AMDGPUSubtarget::GFX10) {
5986 if (DC >= DppCtrl::ROW_NEWBCAST_FIRST &&
5987 DC <= DppCtrl::ROW_NEWBCAST_LAST &&
5988 !ST.hasGFX90AInsts()) {
5989 ErrInfo = "Invalid dpp_ctrl value: "
5990 "row_newbroadcast/row_share is not supported before "
5991 "GFX90A/GFX10";
5992 return false;
5993 }
5994 if (DC > DppCtrl::ROW_NEWBCAST_LAST || !ST.hasGFX90AInsts()) {
5995 ErrInfo = "Invalid dpp_ctrl value: "
5996 "row_share and row_xmask are not supported before GFX10";
5997 return false;
5998 }
5999 }
6000
6001 if (Opcode != AMDGPU::V_MOV_B64_DPP_PSEUDO &&
6003 AMDGPU::isDPALU_DPP(Desc, *this, ST)) {
6004 ErrInfo = "Invalid dpp_ctrl value: "
6005 "DP ALU dpp only support row_newbcast";
6006 return false;
6007 }
6008 }
6009
6010 if ((MI.mayStore() || MI.mayLoad()) && !isVGPRSpill(MI)) {
6011 const MachineOperand *Dst = getNamedOperand(MI, AMDGPU::OpName::vdst);
6012 AMDGPU::OpName DataName =
6013 isDS(Opcode) ? AMDGPU::OpName::data0 : AMDGPU::OpName::vdata;
6014 const MachineOperand *Data = getNamedOperand(MI, DataName);
6015 const MachineOperand *Data2 = getNamedOperand(MI, AMDGPU::OpName::data1);
6016 if (Data && !Data->isReg())
6017 Data = nullptr;
6018
6019 if (!ST.hasGFX90AInsts()) {
6020 if ((Dst && RI.isAGPR(MRI, Dst->getReg())) ||
6021 (Data && RI.isAGPR(MRI, Data->getReg())) ||
6022 (Data2 && RI.isAGPR(MRI, Data2->getReg()))) {
6023 ErrInfo = "Invalid register class: "
6024 "agpr loads and stores not supported on this GPU";
6025 return false;
6026 }
6027 }
6028 }
6029
6030 if (ST.needsAlignedVGPRs()) {
6031 const auto isAlignedReg = [&MI, &MRI, this](AMDGPU::OpName OpName) -> bool {
6033 if (!Op)
6034 return true;
6035 Register Reg = Op->getReg();
6036 if (Reg.isPhysical())
6037 return !(RI.getHWRegIndex(Reg) & 1);
6038 const TargetRegisterClass &RC = *MRI.getRegClass(Reg);
6039 return RI.getRegSizeInBits(RC) > 32 && RI.isProperlyAlignedRC(RC) &&
6040 !(RI.getChannelFromSubReg(Op->getSubReg()) & 1);
6041 };
6042
6043 if (Opcode == AMDGPU::DS_GWS_INIT || Opcode == AMDGPU::DS_GWS_SEMA_BR ||
6044 Opcode == AMDGPU::DS_GWS_BARRIER) {
6045
6046 if (!isAlignedReg(AMDGPU::OpName::data0)) {
6047 ErrInfo = "Subtarget requires even aligned vector registers "
6048 "for DS_GWS instructions";
6049 return false;
6050 }
6051 }
6052
6053 if (isMIMG(MI)) {
6054 if (!isAlignedReg(AMDGPU::OpName::vaddr)) {
6055 ErrInfo = "Subtarget requires even aligned vector registers "
6056 "for vaddr operand of image instructions";
6057 return false;
6058 }
6059 }
6060 }
6061
6062 if (Opcode == AMDGPU::V_ACCVGPR_WRITE_B32_e64 && !ST.hasGFX90AInsts()) {
6063 const MachineOperand *Src = getNamedOperand(MI, AMDGPU::OpName::src0);
6064 if (Src->isReg() && RI.isSGPRReg(MRI, Src->getReg())) {
6065 ErrInfo = "Invalid register class: "
6066 "v_accvgpr_write with an SGPR is not supported on this GPU";
6067 return false;
6068 }
6069 }
6070
6071 if (Desc.getOpcode() == AMDGPU::G_AMDGPU_WAVE_ADDRESS) {
6072 const MachineOperand &SrcOp = MI.getOperand(1);
6073 if (!SrcOp.isReg() || SrcOp.getReg().isVirtual()) {
6074 ErrInfo = "pseudo expects only physical SGPRs";
6075 return false;
6076 }
6077 }
6078
6079 if (const MachineOperand *CPol = getNamedOperand(MI, AMDGPU::OpName::cpol)) {
6080 if (CPol->getImm() & AMDGPU::CPol::SCAL) {
6081 if (!ST.hasScaleOffset()) {
6082 ErrInfo = "Subtarget does not support offset scaling";
6083 return false;
6084 }
6085 if (!AMDGPU::supportsScaleOffset(*this, MI.getOpcode())) {
6086 ErrInfo = "Instruction does not support offset scaling";
6087 return false;
6088 }
6089 }
6090 }
6091
6092 // See SIInstrInfo::isLegalSingleSGPRReadInstOperand for more information.
6093 if (AMDGPU::isSingleSGPRReadInst(Opcode)) {
6094 for (unsigned I = 0; I < 3; ++I) {
6096 return false;
6097 }
6098 }
6099
6100 if (ST.hasFlatScratchHiInB64InstHazard() && isSALU(MI) &&
6101 MI.readsRegister(AMDGPU::SRC_FLAT_SCRATCH_BASE_HI, nullptr)) {
6102 const MachineOperand *Dst = getNamedOperand(MI, AMDGPU::OpName::sdst);
6103 if ((Dst && RI.getRegClassForReg(MRI, Dst->getReg()) ==
6104 &AMDGPU::SReg_64RegClass) ||
6105 Opcode == AMDGPU::S_BITCMP0_B64 || Opcode == AMDGPU::S_BITCMP1_B64) {
6106 ErrInfo = "Instruction cannot read flat_scratch_base_hi";
6107 return false;
6108 }
6109 }
6110
6111 return true;
6112}
6113
6115 if (MI.getOpcode() == AMDGPU::S_MOV_B32) {
6116 const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
6117 return MI.getOperand(1).isReg() || RI.isAGPR(MRI, MI.getOperand(0).getReg())
6118 ? AMDGPU::COPY
6119 : AMDGPU::V_MOV_B32_e32;
6120 }
6121 return getVALUOp(MI.getOpcode());
6122}
6123
6124// It is more readable to list mapped opcodes on the same line.
6125// clang-format off
6126
6127unsigned SIInstrInfo::getVALUOp(unsigned Opc) const {
6128 switch (Opc) {
6129 default: return AMDGPU::INSTRUCTION_LIST_END;
6130 case AMDGPU::REG_SEQUENCE: return AMDGPU::REG_SEQUENCE;
6131 case AMDGPU::COPY: return AMDGPU::COPY;
6132 case AMDGPU::PHI: return AMDGPU::PHI;
6133 case AMDGPU::INSERT_SUBREG: return AMDGPU::INSERT_SUBREG;
6134 case AMDGPU::WQM: return AMDGPU::WQM;
6135 case AMDGPU::SOFT_WQM: return AMDGPU::SOFT_WQM;
6136 case AMDGPU::STRICT_WWM: return AMDGPU::STRICT_WWM;
6137 case AMDGPU::STRICT_WQM: return AMDGPU::STRICT_WQM;
6138 case AMDGPU::S_ADD_I32:
6139 return ST.hasAddNoCarryInsts() ? AMDGPU::V_ADD_U32_e64 : AMDGPU::V_ADD_CO_U32_e32;
6140 case AMDGPU::S_ADDC_U32:
6141 return AMDGPU::V_ADDC_U32_e32;
6142 case AMDGPU::S_SUB_I32:
6143 return ST.hasAddNoCarryInsts() ? AMDGPU::V_SUB_U32_e64 : AMDGPU::V_SUB_CO_U32_e32;
6144 // FIXME: These are not consistently handled, and selected when the carry is
6145 // used.
6146 case AMDGPU::S_ADD_U32:
6147 return AMDGPU::V_ADD_CO_U32_e32;
6148 case AMDGPU::S_SUB_U32:
6149 return AMDGPU::V_SUB_CO_U32_e32;
6150 case AMDGPU::S_ADD_U64_PSEUDO:
6151 return AMDGPU::V_ADD_U64_PSEUDO;
6152 case AMDGPU::S_SUB_U64_PSEUDO:
6153 return AMDGPU::V_SUB_U64_PSEUDO;
6154 case AMDGPU::S_SUBB_U32: return AMDGPU::V_SUBB_U32_e32;
6155 case AMDGPU::S_MUL_I32: return AMDGPU::V_MUL_LO_U32_e64;
6156 case AMDGPU::S_MUL_HI_U32: return AMDGPU::V_MUL_HI_U32_e64;
6157 case AMDGPU::S_MUL_HI_I32: return AMDGPU::V_MUL_HI_I32_e64;
6158 case AMDGPU::S_AND_B32: return AMDGPU::V_AND_B32_e64;
6159 case AMDGPU::S_OR_B32: return AMDGPU::V_OR_B32_e64;
6160 case AMDGPU::S_XOR_B32: return AMDGPU::V_XOR_B32_e64;
6161 case AMDGPU::S_XNOR_B32:
6162 return ST.hasDLInsts() ? AMDGPU::V_XNOR_B32_e64 : AMDGPU::INSTRUCTION_LIST_END;
6163 case AMDGPU::S_MIN_I32: return AMDGPU::V_MIN_I32_e64;
6164 case AMDGPU::S_MIN_U32: return AMDGPU::V_MIN_U32_e64;
6165 case AMDGPU::S_MAX_I32: return AMDGPU::V_MAX_I32_e64;
6166 case AMDGPU::S_MAX_U32: return AMDGPU::V_MAX_U32_e64;
6167 case AMDGPU::S_ASHR_I32: return AMDGPU::V_ASHR_I32_e32;
6168 case AMDGPU::S_ASHR_I64: return AMDGPU::V_ASHR_I64_e64;
6169 case AMDGPU::S_LSHL_B32: return AMDGPU::V_LSHL_B32_e32;
6170 case AMDGPU::S_LSHL_B64: return AMDGPU::V_LSHL_B64_e64;
6171 case AMDGPU::S_LSHR_B32: return AMDGPU::V_LSHR_B32_e32;
6172 case AMDGPU::S_LSHR_B64: return AMDGPU::V_LSHR_B64_e64;
6173 case AMDGPU::S_SEXT_I32_I8: return AMDGPU::V_BFE_I32_e64;
6174 case AMDGPU::S_SEXT_I32_I16: return AMDGPU::V_BFE_I32_e64;
6175 case AMDGPU::S_BFE_U32: return AMDGPU::V_BFE_U32_e64;
6176 case AMDGPU::S_BFE_I32: return AMDGPU::V_BFE_I32_e64;
6177 case AMDGPU::S_BFM_B32: return AMDGPU::V_BFM_B32_e64;
6178 case AMDGPU::S_BREV_B32: return AMDGPU::V_BFREV_B32_e32;
6179 case AMDGPU::S_NOT_B32: return AMDGPU::V_NOT_B32_e32;
6180 case AMDGPU::S_NOT_B64: return AMDGPU::V_NOT_B32_e32;
6181 case AMDGPU::S_CMP_EQ_I32: return AMDGPU::V_CMP_EQ_I32_e64;
6182 case AMDGPU::S_CMP_LG_I32: return AMDGPU::V_CMP_NE_I32_e64;
6183 case AMDGPU::S_CMP_GT_I32: return AMDGPU::V_CMP_GT_I32_e64;
6184 case AMDGPU::S_CMP_GE_I32: return AMDGPU::V_CMP_GE_I32_e64;
6185 case AMDGPU::S_CMP_LT_I32: return AMDGPU::V_CMP_LT_I32_e64;
6186 case AMDGPU::S_CMP_LE_I32: return AMDGPU::V_CMP_LE_I32_e64;
6187 case AMDGPU::S_CMP_EQ_U32: return AMDGPU::V_CMP_EQ_U32_e64;
6188 case AMDGPU::S_CMP_LG_U32: return AMDGPU::V_CMP_NE_U32_e64;
6189 case AMDGPU::S_CMP_GT_U32: return AMDGPU::V_CMP_GT_U32_e64;
6190 case AMDGPU::S_CMP_GE_U32: return AMDGPU::V_CMP_GE_U32_e64;
6191 case AMDGPU::S_CMP_LT_U32: return AMDGPU::V_CMP_LT_U32_e64;
6192 case AMDGPU::S_CMP_LE_U32: return AMDGPU::V_CMP_LE_U32_e64;
6193 case AMDGPU::S_CMP_EQ_U64: return AMDGPU::V_CMP_EQ_U64_e64;
6194 case AMDGPU::S_CMP_LG_U64: return AMDGPU::V_CMP_NE_U64_e64;
6195 case AMDGPU::S_BCNT1_I32_B32: return AMDGPU::V_BCNT_U32_B32_e64;
6196 case AMDGPU::S_FF1_I32_B32: return AMDGPU::V_FFBL_B32_e32;
6197 case AMDGPU::S_FLBIT_I32_B32: return AMDGPU::V_FFBH_U32_e32;
6198 case AMDGPU::S_FLBIT_I32: return AMDGPU::V_FFBH_I32_e64;
6199 case AMDGPU::S_CBRANCH_SCC0: return AMDGPU::S_CBRANCH_VCCZ;
6200 case AMDGPU::S_CBRANCH_SCC1: return AMDGPU::S_CBRANCH_VCCNZ;
6201 case AMDGPU::S_CVT_F32_I32: return AMDGPU::V_CVT_F32_I32_e64;
6202 case AMDGPU::S_CVT_F32_U32: return AMDGPU::V_CVT_F32_U32_e64;
6203 case AMDGPU::S_CVT_I32_F32: return AMDGPU::V_CVT_I32_F32_e64;
6204 case AMDGPU::S_CVT_U32_F32: return AMDGPU::V_CVT_U32_F32_e64;
6205 case AMDGPU::S_CVT_F32_F16:
6206 case AMDGPU::S_CVT_HI_F32_F16:
6207 return ST.useRealTrue16Insts() ? AMDGPU::V_CVT_F32_F16_t16_e64
6208 : AMDGPU::V_CVT_F32_F16_fake16_e64;
6209 case AMDGPU::S_CVT_F16_F32:
6210 return ST.useRealTrue16Insts() ? AMDGPU::V_CVT_F16_F32_t16_e64
6211 : AMDGPU::V_CVT_F16_F32_fake16_e64;
6212 case AMDGPU::S_CEIL_F32: return AMDGPU::V_CEIL_F32_e64;
6213 case AMDGPU::S_FLOOR_F32: return AMDGPU::V_FLOOR_F32_e64;
6214 case AMDGPU::S_TRUNC_F32: return AMDGPU::V_TRUNC_F32_e64;
6215 case AMDGPU::S_RNDNE_F32: return AMDGPU::V_RNDNE_F32_e64;
6216 case AMDGPU::S_CEIL_F16:
6217 return ST.useRealTrue16Insts() ? AMDGPU::V_CEIL_F16_t16_e64
6218 : AMDGPU::V_CEIL_F16_fake16_e64;
6219 case AMDGPU::S_FLOOR_F16:
6220 return ST.useRealTrue16Insts() ? AMDGPU::V_FLOOR_F16_t16_e64
6221 : AMDGPU::V_FLOOR_F16_fake16_e64;
6222 case AMDGPU::S_TRUNC_F16:
6223 return ST.useRealTrue16Insts() ? AMDGPU::V_TRUNC_F16_t16_e64
6224 : AMDGPU::V_TRUNC_F16_fake16_e64;
6225 case AMDGPU::S_RNDNE_F16:
6226 return ST.useRealTrue16Insts() ? AMDGPU::V_RNDNE_F16_t16_e64
6227 : AMDGPU::V_RNDNE_F16_fake16_e64;
6228 case AMDGPU::S_ADD_F32: return AMDGPU::V_ADD_F32_e64;
6229 case AMDGPU::S_SUB_F32: return AMDGPU::V_SUB_F32_e64;
6230 case AMDGPU::S_MIN_F32: return AMDGPU::V_MIN_F32_e64;
6231 case AMDGPU::S_MAX_F32: return AMDGPU::V_MAX_F32_e64;
6232 case AMDGPU::S_MINIMUM_F32: return AMDGPU::V_MINIMUM_F32_e64;
6233 case AMDGPU::S_MAXIMUM_F32: return AMDGPU::V_MAXIMUM_F32_e64;
6234 case AMDGPU::S_MUL_F32: return AMDGPU::V_MUL_F32_e64;
6235 case AMDGPU::S_ADD_F16:
6236 return ST.useRealTrue16Insts() ? AMDGPU::V_ADD_F16_t16_e64
6237 : AMDGPU::V_ADD_F16_fake16_e64;
6238 case AMDGPU::S_SUB_F16:
6239 return ST.useRealTrue16Insts() ? AMDGPU::V_SUB_F16_t16_e64
6240 : AMDGPU::V_SUB_F16_fake16_e64;
6241 case AMDGPU::S_MIN_F16:
6242 return ST.useRealTrue16Insts() ? AMDGPU::V_MIN_F16_t16_e64
6243 : AMDGPU::V_MIN_F16_fake16_e64;
6244 case AMDGPU::S_MAX_F16:
6245 return ST.useRealTrue16Insts() ? AMDGPU::V_MAX_F16_t16_e64
6246 : AMDGPU::V_MAX_F16_fake16_e64;
6247 case AMDGPU::S_MINIMUM_F16:
6248 return ST.useRealTrue16Insts() ? AMDGPU::V_MINIMUM_F16_t16_e64
6249 : AMDGPU::V_MINIMUM_F16_fake16_e64;
6250 case AMDGPU::S_MAXIMUM_F16:
6251 return ST.useRealTrue16Insts() ? AMDGPU::V_MAXIMUM_F16_t16_e64
6252 : AMDGPU::V_MAXIMUM_F16_fake16_e64;
6253 case AMDGPU::S_MUL_F16:
6254 return ST.useRealTrue16Insts() ? AMDGPU::V_MUL_F16_t16_e64
6255 : AMDGPU::V_MUL_F16_fake16_e64;
6256 case AMDGPU::S_CVT_PK_RTZ_F16_F32: return AMDGPU::V_CVT_PKRTZ_F16_F32_e64;
6257 case AMDGPU::S_FMAC_F32: return AMDGPU::V_FMAC_F32_e64;
6258 case AMDGPU::S_FMAC_F16:
6259 return ST.useRealTrue16Insts() ? AMDGPU::V_FMAC_F16_t16_e64
6260 : AMDGPU::V_FMAC_F16_fake16_e64;
6261 case AMDGPU::S_FMAMK_F32: return AMDGPU::V_FMAMK_F32;
6262 case AMDGPU::S_FMAAK_F32: return AMDGPU::V_FMAAK_F32;
6263 case AMDGPU::S_CMP_LT_F32: return AMDGPU::V_CMP_LT_F32_e64;
6264 case AMDGPU::S_CMP_EQ_F32: return AMDGPU::V_CMP_EQ_F32_e64;
6265 case AMDGPU::S_CMP_LE_F32: return AMDGPU::V_CMP_LE_F32_e64;
6266 case AMDGPU::S_CMP_GT_F32: return AMDGPU::V_CMP_GT_F32_e64;
6267 case AMDGPU::S_CMP_LG_F32: return AMDGPU::V_CMP_LG_F32_e64;
6268 case AMDGPU::S_CMP_GE_F32: return AMDGPU::V_CMP_GE_F32_e64;
6269 case AMDGPU::S_CMP_O_F32: return AMDGPU::V_CMP_O_F32_e64;
6270 case AMDGPU::S_CMP_U_F32: return AMDGPU::V_CMP_U_F32_e64;
6271 case AMDGPU::S_CMP_NGE_F32: return AMDGPU::V_CMP_NGE_F32_e64;
6272 case AMDGPU::S_CMP_NLG_F32: return AMDGPU::V_CMP_NLG_F32_e64;
6273 case AMDGPU::S_CMP_NGT_F32: return AMDGPU::V_CMP_NGT_F32_e64;
6274 case AMDGPU::S_CMP_NLE_F32: return AMDGPU::V_CMP_NLE_F32_e64;
6275 case AMDGPU::S_CMP_NEQ_F32: return AMDGPU::V_CMP_NEQ_F32_e64;
6276 case AMDGPU::S_CMP_NLT_F32: return AMDGPU::V_CMP_NLT_F32_e64;
6277 case AMDGPU::S_CMP_LT_F16:
6278 return ST.useRealTrue16Insts() ? AMDGPU::V_CMP_LT_F16_t16_e64
6279 : AMDGPU::V_CMP_LT_F16_fake16_e64;
6280 case AMDGPU::S_CMP_EQ_F16:
6281 return ST.useRealTrue16Insts() ? AMDGPU::V_CMP_EQ_F16_t16_e64
6282 : AMDGPU::V_CMP_EQ_F16_fake16_e64;
6283 case AMDGPU::S_CMP_LE_F16:
6284 return ST.useRealTrue16Insts() ? AMDGPU::V_CMP_LE_F16_t16_e64
6285 : AMDGPU::V_CMP_LE_F16_fake16_e64;
6286 case AMDGPU::S_CMP_GT_F16:
6287 return ST.useRealTrue16Insts() ? AMDGPU::V_CMP_GT_F16_t16_e64
6288 : AMDGPU::V_CMP_GT_F16_fake16_e64;
6289 case AMDGPU::S_CMP_LG_F16:
6290 return ST.useRealTrue16Insts() ? AMDGPU::V_CMP_LG_F16_t16_e64
6291 : AMDGPU::V_CMP_LG_F16_fake16_e64;
6292 case AMDGPU::S_CMP_GE_F16:
6293 return ST.useRealTrue16Insts() ? AMDGPU::V_CMP_GE_F16_t16_e64
6294 : AMDGPU::V_CMP_GE_F16_fake16_e64;
6295 case AMDGPU::S_CMP_O_F16:
6296 return ST.useRealTrue16Insts() ? AMDGPU::V_CMP_O_F16_t16_e64
6297 : AMDGPU::V_CMP_O_F16_fake16_e64;
6298 case AMDGPU::S_CMP_U_F16:
6299 return ST.useRealTrue16Insts() ? AMDGPU::V_CMP_U_F16_t16_e64
6300 : AMDGPU::V_CMP_U_F16_fake16_e64;
6301 case AMDGPU::S_CMP_NGE_F16:
6302 return ST.useRealTrue16Insts() ? AMDGPU::V_CMP_NGE_F16_t16_e64
6303 : AMDGPU::V_CMP_NGE_F16_fake16_e64;
6304 case AMDGPU::S_CMP_NLG_F16:
6305 return ST.useRealTrue16Insts() ? AMDGPU::V_CMP_NLG_F16_t16_e64
6306 : AMDGPU::V_CMP_NLG_F16_fake16_e64;
6307 case AMDGPU::S_CMP_NGT_F16:
6308 return ST.useRealTrue16Insts() ? AMDGPU::V_CMP_NGT_F16_t16_e64
6309 : AMDGPU::V_CMP_NGT_F16_fake16_e64;
6310 case AMDGPU::S_CMP_NLE_F16:
6311 return ST.useRealTrue16Insts() ? AMDGPU::V_CMP_NLE_F16_t16_e64
6312 : AMDGPU::V_CMP_NLE_F16_fake16_e64;
6313 case AMDGPU::S_CMP_NEQ_F16:
6314 return ST.useRealTrue16Insts() ? AMDGPU::V_CMP_NEQ_F16_t16_e64
6315 : AMDGPU::V_CMP_NEQ_F16_fake16_e64;
6316 case AMDGPU::S_CMP_NLT_F16:
6317 return ST.useRealTrue16Insts() ? AMDGPU::V_CMP_NLT_F16_t16_e64
6318 : AMDGPU::V_CMP_NLT_F16_fake16_e64;
6319 case AMDGPU::V_S_EXP_F32_e64: return AMDGPU::V_EXP_F32_e64;
6320 case AMDGPU::V_S_EXP_F16_e64:
6321 return ST.useRealTrue16Insts() ? AMDGPU::V_EXP_F16_t16_e64
6322 : AMDGPU::V_EXP_F16_fake16_e64;
6323 case AMDGPU::V_S_LOG_F32_e64: return AMDGPU::V_LOG_F32_e64;
6324 case AMDGPU::V_S_LOG_F16_e64:
6325 return ST.useRealTrue16Insts() ? AMDGPU::V_LOG_F16_t16_e64
6326 : AMDGPU::V_LOG_F16_fake16_e64;
6327 case AMDGPU::V_S_RCP_F32_e64: return AMDGPU::V_RCP_F32_e64;
6328 case AMDGPU::V_S_RCP_F16_e64:
6329 return ST.useRealTrue16Insts() ? AMDGPU::V_RCP_F16_t16_e64
6330 : AMDGPU::V_RCP_F16_fake16_e64;
6331 case AMDGPU::V_S_RSQ_F32_e64: return AMDGPU::V_RSQ_F32_e64;
6332 case AMDGPU::V_S_RSQ_F16_e64:
6333 return ST.useRealTrue16Insts() ? AMDGPU::V_RSQ_F16_t16_e64
6334 : AMDGPU::V_RSQ_F16_fake16_e64;
6335 case AMDGPU::V_S_SQRT_F32_e64: return AMDGPU::V_SQRT_F32_e64;
6336 case AMDGPU::V_S_SQRT_F16_e64:
6337 return ST.useRealTrue16Insts() ? AMDGPU::V_SQRT_F16_t16_e64
6338 : AMDGPU::V_SQRT_F16_fake16_e64;
6339 }
6341 "Unexpected scalar opcode without corresponding vector one!");
6342}
6343
6344// clang-format on
6345
6349 const DebugLoc &DL, Register Reg,
6350 bool IsSCCLive,
6351 SlotIndexes *Indexes) const {
6352 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
6353 const SIInstrInfo *TII = ST.getInstrInfo();
6355 if (IsSCCLive) {
6356 // Insert two move instructions, one to save the original value of EXEC and
6357 // the other to turn on all bits in EXEC. This is required as we can't use
6358 // the single instruction S_OR_SAVEEXEC that clobbers SCC.
6359 auto StoreExecMI = BuildMI(MBB, MBBI, DL, TII->get(LMC.MovOpc), Reg)
6361 auto FlipExecMI =
6362 BuildMI(MBB, MBBI, DL, TII->get(LMC.MovOpc), LMC.ExecReg).addImm(-1);
6363 if (Indexes) {
6364 Indexes->insertMachineInstrInMaps(*StoreExecMI);
6365 Indexes->insertMachineInstrInMaps(*FlipExecMI);
6366 }
6367 } else {
6368 auto SaveExec =
6369 BuildMI(MBB, MBBI, DL, TII->get(LMC.OrSaveExecOpc), Reg).addImm(-1);
6370 SaveExec->getOperand(3).setIsDead(); // Mark SCC as dead.
6371 if (Indexes)
6372 Indexes->insertMachineInstrInMaps(*SaveExec);
6373 }
6374}
6375
6378 const DebugLoc &DL, Register Reg,
6379 SlotIndexes *Indexes) const {
6381 auto ExecRestoreMI = BuildMI(MBB, MBBI, DL, get(LMC.MovOpc), LMC.ExecReg)
6382 .addReg(Reg, RegState::Kill);
6383 if (Indexes)
6384 Indexes->insertMachineInstrInMaps(*ExecRestoreMI);
6385}
6386
6390 "Not a whole wave func");
6391 MachineBasicBlock &MBB = *MF.begin();
6392 for (MachineInstr &MI : MBB)
6393 if (MI.getOpcode() == AMDGPU::SI_WHOLE_WAVE_FUNC_SETUP ||
6394 MI.getOpcode() == AMDGPU::G_AMDGPU_WHOLE_WAVE_FUNC_SETUP)
6395 return &MI;
6396
6397 llvm_unreachable("Couldn't find SI_SETUP_WHOLE_WAVE_FUNC instruction");
6398}
6399
6401 unsigned OpNo) const {
6402 const MCInstrDesc &Desc = get(MI.getOpcode());
6403 if (MI.isVariadic() || OpNo >= Desc.getNumOperands() ||
6404 Desc.operands()[OpNo].RegClass == -1) {
6405 Register Reg = MI.getOperand(OpNo).getReg();
6406
6407 if (Reg.isVirtual()) {
6408 const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
6409 return MRI.getRegClass(Reg);
6410 }
6411 return RI.getPhysRegBaseClass(Reg);
6412 }
6413
6414 int16_t RegClass = getOpRegClassID(Desc.operands()[OpNo]);
6415 return RegClass < 0 ? nullptr : RI.getRegClass(RegClass);
6416}
6417
6418// Convert VOP3 operand index to source number.
6419static unsigned VOP3OpIdxToSrcN(const MachineInstr &MI, unsigned OpIdx) {
6420 constexpr AMDGPU::OpName OpNames[] = {
6421 AMDGPU::OpName::src0, AMDGPU::OpName::src1, AMDGPU::OpName::src2};
6422
6423 for (auto [I, OpName] : enumerate(OpNames)) {
6424 int SrcIdx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpNames[I]);
6425 if (static_cast<unsigned>(SrcIdx) == OpIdx)
6426 return I;
6427 }
6428
6429 return UINT_MAX;
6430}
6431
6434 MachineBasicBlock *MBB = MI.getParent();
6435 MachineOperand &MO = MI.getOperand(OpIdx);
6436 MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
6437 unsigned RCID = getOpRegClassID(get(MI.getOpcode()).operands()[OpIdx]);
6438 const TargetRegisterClass *RC = RI.getRegClass(RCID);
6439 unsigned Size = RI.getRegSizeInBits(*RC);
6440 unsigned Opcode = (Size == 64) ? AMDGPU::V_MOV_B64_PSEUDO
6441 : Size == 16 ? AMDGPU::V_MOV_B16_t16_e64
6442 : AMDGPU::V_MOV_B32_e32;
6443 if (MO.isReg())
6444 Opcode = AMDGPU::COPY;
6445 else if (RI.isSGPRClass(RC))
6446 Opcode = (Size == 64) ? AMDGPU::S_MOV_B64 : AMDGPU::S_MOV_B32;
6447
6448 const TargetRegisterClass *VRC = RI.getEquivalentVGPRClass(RC);
6449 Register Reg = MRI.createVirtualRegister(VRC);
6450 DebugLoc DL = MBB->findDebugLoc(I);
6451
6452 if (Size == 128 && AMDGPU::isPackedSingleSGPR64BitInst(MI.getOpcode()) &&
6454 // Special case for V_PK_*64 instructions: these do not have OPSEL but SGPR
6455 // sources behave like OPSEL is set replicating low 64-bits into high. VGPR
6456 // sources in turn read actual 4 registers. To move operand from an SGPR to
6457 // a VGPR we need to replicate low half.
6458 // We also do not select immediates for these instructions so it always has
6459 // to be an SGPR register here.
6460 // Operands which are not legal as per isLegalSingleSGPRReadInstOperand()
6461 // sent here specifically to fix a non-splat SGPR and shall perform a full
6462 // copy.
6463
6464 const TargetRegisterClass *VRC64 = RI.getVGPRClassForBitWidth(64);
6465 Register Low64 = MRI.createVirtualRegister(VRC64);
6466 assert(MO.isReg() && RI.isSGPRReg(MRI, MO.getReg()));
6467 BuildMI(*MBB, I, DL, get(TargetOpcode::COPY), Low64)
6468 .addReg(MO.getReg(), {}, AMDGPU::sub0_sub1);
6469 BuildMI(*MBB, I, DL, get(TargetOpcode::REG_SEQUENCE), Reg)
6470 .addReg(Low64)
6471 .addImm(AMDGPU::sub0_sub1)
6472 .addReg(Low64, RegState::Kill)
6473 .addImm(AMDGPU::sub2_sub3);
6474 } else {
6475 BuildMI(*MBB, I, DL, get(Opcode), Reg).add(MO);
6476 }
6477
6478 MO.ChangeToRegister(Reg, false);
6479}
6480
6483 const MachineOperand &SuperReg, const TargetRegisterClass *SuperRC,
6484 unsigned SubIdx, const TargetRegisterClass *SubRC) const {
6485 if (!SuperReg.getReg().isVirtual())
6486 return RI.getSubReg(SuperReg.getReg(), SubIdx);
6487
6488 MachineBasicBlock *MBB = MI->getParent();
6489 const DebugLoc &DL = MI->getDebugLoc();
6490 Register SubReg = MRI.createVirtualRegister(SubRC);
6491
6492 unsigned NewSubIdx = RI.composeSubRegIndices(SuperReg.getSubReg(), SubIdx);
6493 BuildMI(*MBB, MI, DL, get(TargetOpcode::COPY), SubReg)
6494 .addReg(SuperReg.getReg(), {}, NewSubIdx);
6495 return SubReg;
6496}
6497
6500 const MachineOperand &Op, const TargetRegisterClass *SuperRC,
6501 unsigned SubIdx, const TargetRegisterClass *SubRC) const {
6502 if (Op.isImm()) {
6503 if (SubIdx == AMDGPU::sub0)
6504 return MachineOperand::CreateImm(static_cast<int32_t>(Op.getImm()));
6505 if (SubIdx == AMDGPU::sub1)
6506 return MachineOperand::CreateImm(static_cast<int32_t>(Op.getImm() >> 32));
6507
6508 llvm_unreachable("Unhandled register index for immediate");
6509 }
6510
6511 unsigned SubReg = buildExtractSubReg(MII, MRI, Op, SuperRC,
6512 SubIdx, SubRC);
6513 return MachineOperand::CreateReg(SubReg, false);
6514}
6515
6516// Change the order of operands from (0, 1, 2) to (0, 2, 1)
6517void SIInstrInfo::swapOperands(MachineInstr &Inst) const {
6518 assert(Inst.getNumExplicitOperands() == 3);
6519 MachineOperand Op1 = Inst.getOperand(1);
6520 Inst.removeOperand(1);
6521 Inst.addOperand(Op1);
6522}
6523
6525 const MCOperandInfo &OpInfo,
6526 const MachineOperand &MO) const {
6527 if (!MO.isReg())
6528 return false;
6529
6530 Register Reg = MO.getReg();
6531
6532 const TargetRegisterClass *DRC = RI.getRegClass(getOpRegClassID(OpInfo));
6533 if (Reg.isPhysical())
6534 return DRC->contains(Reg);
6535
6536 const TargetRegisterClass *RC = MRI.getRegClass(Reg);
6537
6538 if (MO.getSubReg()) {
6539 const TargetRegisterClass *SuperRC =
6540 RI.getLargestLegalSuperClass(RC, MRI.getMF());
6541 if (!SuperRC)
6542 return false;
6543 return RI.getMatchingSuperRegClass(SuperRC, DRC, MO.getSubReg()) != nullptr;
6544 }
6545
6546 return RI.getCommonSubClass(DRC, RC) != nullptr;
6547}
6548
6550 const MachineOperand &MO) const {
6551 const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
6552 const MCOperandInfo OpInfo = MI.getDesc().operands()[OpIdx];
6553 unsigned Opc = MI.getOpcode();
6554
6555 // See SIInstrInfo::isLegalSingleSGPRReadInstOperand for more information.
6556 if (MO.isReg() && RI.isSGPRReg(MRI, MO.getReg()) &&
6557 AMDGPU::isSingleSGPRReadInst(MI.getOpcode()) &&
6559 &MO))
6560 return false;
6561
6562 if (!isLegalRegOperand(MRI, OpInfo, MO))
6563 return false;
6564
6565 // check Accumulate GPR operand
6566 bool IsAGPR = RI.isAGPR(MRI, MO.getReg());
6567 if (IsAGPR && !ST.hasMAIInsts())
6568 return false;
6569 if (IsAGPR && (!ST.hasGFX90AInsts() || !MRI.reservedRegsFrozen()) &&
6570 (MI.mayLoad() || MI.mayStore() || isDS(Opc) || isMIMG(Opc)))
6571 return false;
6572 // Atomics should have both vdst and vdata either vgpr or agpr.
6573 const int VDstIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::vdst);
6574 const int DataIdx = AMDGPU::getNamedOperandIdx(
6575 Opc, isDS(Opc) ? AMDGPU::OpName::data0 : AMDGPU::OpName::vdata);
6576 if ((int)OpIdx == VDstIdx && DataIdx != -1 &&
6577 MI.getOperand(DataIdx).isReg() &&
6578 RI.isAGPR(MRI, MI.getOperand(DataIdx).getReg()) != IsAGPR)
6579 return false;
6580 if ((int)OpIdx == DataIdx) {
6581 if (VDstIdx != -1 &&
6582 RI.isAGPR(MRI, MI.getOperand(VDstIdx).getReg()) != IsAGPR)
6583 return false;
6584 // DS instructions with 2 src operands also must have tied RC.
6585 const int Data1Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::data1);
6586 if (Data1Idx != -1 && MI.getOperand(Data1Idx).isReg() &&
6587 RI.isAGPR(MRI, MI.getOperand(Data1Idx).getReg()) != IsAGPR)
6588 return false;
6589 }
6590
6591 // Check V_ACCVGPR_WRITE_B32_e64
6592 if (Opc == AMDGPU::V_ACCVGPR_WRITE_B32_e64 && !ST.hasGFX90AInsts() &&
6593 (int)OpIdx == AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0) &&
6594 RI.isSGPRReg(MRI, MO.getReg()))
6595 return false;
6596
6597 if (ST.hasFlatScratchHiInB64InstHazard() &&
6598 MO.getReg() == AMDGPU::SRC_FLAT_SCRATCH_BASE_HI && isSALU(MI)) {
6599 if (const MachineOperand *Dst = getNamedOperand(MI, AMDGPU::OpName::sdst)) {
6600 if (AMDGPU::getRegBitWidth(*RI.getRegClassForReg(MRI, Dst->getReg())) ==
6601 64)
6602 return false;
6603 }
6604 if (Opc == AMDGPU::S_BITCMP0_B64 || Opc == AMDGPU::S_BITCMP1_B64)
6605 return false;
6606 }
6607 if (!ST.hasDPPSrc1SGPR() && isDPP(MI) && RI.isSGPRReg(MRI, MO.getReg()) &&
6608 (int)OpIdx == AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src1))
6609 return false;
6610
6611 return true;
6612}
6613
6615 const MCOperandInfo &OpInfo,
6616 const MachineOperand &MO) const {
6617 if (MO.isReg())
6618 return isLegalRegOperand(MRI, OpInfo, MO);
6619
6620 // Handle non-register types that are treated like immediates.
6621 assert(MO.isImm() || MO.isTargetIndex() || MO.isFI() || MO.isGlobal());
6622 return true;
6623}
6624
6626 const MachineRegisterInfo &MRI, const MachineInstr &MI, unsigned SrcN,
6627 const MachineOperand *MO) const {
6628 constexpr unsigned NumOps = 3;
6629 constexpr AMDGPU::OpName OpNames[NumOps * 2] = {
6630 AMDGPU::OpName::src0, AMDGPU::OpName::src1,
6631 AMDGPU::OpName::src2, AMDGPU::OpName::src0_modifiers,
6632 AMDGPU::OpName::src1_modifiers, AMDGPU::OpName::src2_modifiers};
6633
6634 assert(SrcN < NumOps);
6635
6636 if (!MO) {
6637 int SrcIdx = AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpNames[SrcN]);
6638 if (SrcIdx == -1)
6639 return true;
6640 MO = &MI.getOperand(SrcIdx);
6641 }
6642
6643 if (!MO->isReg() || !RI.isSGPRReg(MRI, MO->getReg()))
6644 return true;
6645
6646 int ModsIdx =
6647 AMDGPU::getNamedOperandIdx(MI.getOpcode(), OpNames[NumOps + SrcN]);
6648 if (ModsIdx == -1)
6649 return false;
6650
6651 unsigned Mods = MI.getOperand(ModsIdx).getImm();
6652 bool OpSel = Mods & SISrcMods::OP_SEL_0;
6653 bool OpSelHi = Mods & SISrcMods::OP_SEL_1;
6654
6655 return !OpSel && !OpSelHi;
6656}
6657
6658bool SIInstrInfo::isOperandLegal(const MachineInstr &MI, unsigned OpIdx,
6659 const MachineOperand *MO) const {
6660 const MachineFunction &MF = *MI.getMF();
6661 const MachineRegisterInfo &MRI = MF.getRegInfo();
6662 const MCInstrDesc &InstDesc = MI.getDesc();
6663 const MCOperandInfo &OpInfo = InstDesc.operands()[OpIdx];
6664 int64_t RegClass = getOpRegClassID(OpInfo);
6665 const TargetRegisterClass *DefinedRC =
6666 RegClass != -1 ? RI.getRegClass(RegClass) : nullptr;
6667 if (!MO)
6668 MO = &MI.getOperand(OpIdx);
6669
6670 const bool IsInlineConst = !MO->isReg() && isInlineConstant(*MO, OpInfo);
6671
6672 if (isVALU(MI, /*AllowLDSDMA=*/true) && !IsInlineConst &&
6673 usesConstantBus(MRI, *MO, OpInfo)) {
6674 const MachineOperand *UsedLiteral = nullptr;
6675
6676 int ConstantBusLimit = ST.getConstantBusLimit(MI.getOpcode());
6677 int LiteralLimit = !isVOP3(MI) || ST.hasVOP3Literal() ? 1 : 0;
6678
6679 // TODO: Be more permissive with frame indexes.
6680 if (!MO->isReg() && !isInlineConstant(*MO, OpInfo)) {
6681 if (!LiteralLimit--)
6682 return false;
6683
6684 UsedLiteral = MO;
6685 }
6686
6688 if (MO->isReg())
6689 SGPRsUsed.insert(RegSubRegPair(MO->getReg(), MO->getSubReg()));
6690
6691 for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
6692 if (i == OpIdx)
6693 continue;
6694 const MachineOperand &Op = MI.getOperand(i);
6695 if (Op.isReg()) {
6696 if (Op.isUse()) {
6697 RegSubRegPair SGPR(Op.getReg(), Op.getSubReg());
6698 if (regUsesConstantBus(Op, MRI) && SGPRsUsed.insert(SGPR).second) {
6699 if (--ConstantBusLimit <= 0)
6700 return false;
6701 }
6702 }
6703 } else if (AMDGPU::isSISrcOperand(InstDesc.operands()[i]) &&
6704 !isInlineConstant(Op, InstDesc.operands()[i])) {
6705 // The same literal may be used multiple times.
6706 if (!UsedLiteral)
6707 UsedLiteral = &Op;
6708 else if (UsedLiteral->isIdenticalTo(Op))
6709 continue;
6710
6711 if (!LiteralLimit--)
6712 return false;
6713 if (--ConstantBusLimit <= 0)
6714 return false;
6715 }
6716 }
6717 } else if (!IsInlineConst && !MO->isReg() && isSALU(MI)) {
6718 // There can be at most one literal operand, but it can be repeated.
6719 for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
6720 if (i == OpIdx)
6721 continue;
6722 const MachineOperand &Op = MI.getOperand(i);
6723 if (!Op.isReg() && !Op.isFI() && !Op.isRegMask() &&
6724 !isInlineConstant(Op, InstDesc.operands()[i]) &&
6725 !Op.isIdenticalTo(*MO))
6726 return false;
6727
6728 // Do not fold a non-inlineable and non-register operand into an
6729 // instruction that already has a frame index. The frame index handling
6730 // code could not handle well when a frame index co-exists with another
6731 // non-register operand, unless that operand is an inlineable immediate.
6732 if (Op.isFI())
6733 return false;
6734 }
6735 } else if (IsInlineConst && ST.hasNoF16PseudoScalarTransInlineConstants() &&
6736 isF16PseudoScalarTrans(MI.getOpcode())) {
6737 return false;
6738 }
6739
6740 if (MO->isReg()) {
6741 if (!DefinedRC)
6742 return OpInfo.OperandType == MCOI::OPERAND_UNKNOWN;
6743 return isLegalRegOperand(MI, OpIdx, *MO);
6744 }
6745
6746 if (MO->isImm()) {
6747 uint64_t Imm = MO->getImm();
6748 bool Is64BitFPOp = OpInfo.OperandType == AMDGPU::OPERAND_REG_IMM_FP64 ||
6749 OpInfo.OperandType == AMDGPU::OPERAND_REG_IMM_V2FP64;
6750 bool Is64BitOp = Is64BitFPOp ||
6751 OpInfo.OperandType == AMDGPU::OPERAND_REG_IMM_INT64 ||
6752 OpInfo.OperandType == AMDGPU::OPERAND_REG_IMM_V2INT32 ||
6753 OpInfo.OperandType == AMDGPU::OPERAND_REG_IMM_V2FP32 ||
6754 OpInfo.OperandType == AMDGPU::OPERAND_REG_IMM_V2INT64;
6755 if (Is64BitOp &&
6756 !AMDGPU::isInlinableLiteral64(Imm, ST.hasInv2PiInlineImm())) {
6757 if (!AMDGPU::isValid32BitLiteral(Imm, Is64BitFPOp) &&
6758 (!ST.has64BitLiterals() || InstDesc.getSize() != 4))
6759 return false;
6760
6761 // FIXME: We can use sign extended 64-bit literals, but only for signed
6762 // operands. At the moment we do not know if an operand is signed.
6763 // Such operand will be encoded as its low 32 bits and then either
6764 // correctly sign extended or incorrectly zero extended by HW.
6765 // If 64-bit literals are supported and the literal will be encoded
6766 // as full 64 bit we still can use it.
6767 if (!Is64BitFPOp && (int32_t)Imm < 0 &&
6768 (!ST.has64BitLiterals() || AMDGPU::isValid32BitLiteral(Imm, false)))
6769 return false;
6770 }
6771 }
6772
6773 // Handle non-register types that are treated like immediates.
6774 assert(MO->isImm() || MO->isTargetIndex() || MO->isFI() || MO->isGlobal());
6775
6776 if (!DefinedRC) {
6777 // This operand expects an immediate.
6778 return true;
6779 }
6780
6781 return isImmOperandLegal(MI, OpIdx, *MO);
6782}
6783
6785 bool IsGFX950Only = ST.hasGFX950Insts();
6786 bool IsGFX940Only = ST.hasGFX940Insts();
6787
6788 if (!IsGFX950Only && !IsGFX940Only)
6789 return false;
6790
6791 if (!isVALU(MI, /*AllowLDSDMA=*/true))
6792 return false;
6793
6794 // V_COS, V_EXP, V_RCP, etc.
6795 if (isTRANS(MI))
6796 return true;
6797
6798 // DOT2, DOT2C, DOT4, etc.
6799 if (isDOT(MI))
6800 return true;
6801
6802 // MFMA, SMFMA
6803 if (isMFMA(MI))
6804 return true;
6805
6806 unsigned Opcode = MI.getOpcode();
6807 switch (Opcode) {
6808 case AMDGPU::V_CVT_PK_BF8_F32_e64:
6809 case AMDGPU::V_CVT_PK_FP8_F32_e64:
6810 case AMDGPU::V_MQSAD_PK_U16_U8_e64:
6811 case AMDGPU::V_MQSAD_U32_U8_e64:
6812 case AMDGPU::V_PK_ADD_F16:
6813 case AMDGPU::V_PK_ADD_F32:
6814 case AMDGPU::V_PK_ADD_I16:
6815 case AMDGPU::V_PK_ADD_U16:
6816 case AMDGPU::V_PK_ASHRREV_I16:
6817 case AMDGPU::V_PK_FMA_F16:
6818 case AMDGPU::V_PK_FMA_F32:
6819 case AMDGPU::V_PK_FMAC_F16_e32:
6820 case AMDGPU::V_PK_FMAC_F16_e64:
6821 case AMDGPU::V_PK_LSHLREV_B16:
6822 case AMDGPU::V_PK_LSHRREV_B16:
6823 case AMDGPU::V_PK_MAD_I16:
6824 case AMDGPU::V_PK_MAD_U16:
6825 case AMDGPU::V_PK_MAX_F16:
6826 case AMDGPU::V_PK_MAX_I16:
6827 case AMDGPU::V_PK_MAX_U16:
6828 case AMDGPU::V_PK_MIN_F16:
6829 case AMDGPU::V_PK_MIN_I16:
6830 case AMDGPU::V_PK_MIN_U16:
6831 case AMDGPU::V_PK_MOV_B32:
6832 case AMDGPU::V_PK_MUL_F16:
6833 case AMDGPU::V_PK_MUL_F32:
6834 case AMDGPU::V_PK_MUL_LO_U16:
6835 case AMDGPU::V_PK_SUB_I16:
6836 case AMDGPU::V_PK_SUB_U16:
6837 case AMDGPU::V_QSAD_PK_U16_U8_e64:
6838 return true;
6839 default:
6840 return false;
6841 }
6842}
6843
6845 MachineInstr &MI) const {
6846 unsigned Opc = MI.getOpcode();
6847 const MCInstrDesc &InstrDesc = get(Opc);
6848
6849 int Src0Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0);
6850 MachineOperand &Src0 = MI.getOperand(Src0Idx);
6851
6852 int Src1Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src1);
6853 MachineOperand &Src1 = MI.getOperand(Src1Idx);
6854
6855 // If there is an implicit SGPR use such as VCC use for v_addc_u32/v_subb_u32
6856 // we need to only have one constant bus use before GFX10.
6857 bool HasImplicitSGPR = findImplicitSGPRRead(MI);
6858 if (HasImplicitSGPR && ST.getConstantBusLimit(Opc) <= 1 && Src0.isReg() &&
6859 RI.isSGPRReg(MRI, Src0.getReg()))
6860 legalizeOpWithMove(MI, Src0Idx);
6861
6862 // Special case: V_WRITELANE_B32 accepts only immediate or SGPR operands for
6863 // both the value to write (src0) and lane select (src1). Fix up non-SGPR
6864 // src0/src1 with V_READFIRSTLANE.
6865 if (Opc == AMDGPU::V_WRITELANE_B32) {
6866 const DebugLoc &DL = MI.getDebugLoc();
6867 if (Src0.isReg() && RI.isVGPR(MRI, Src0.getReg())) {
6868 Register Reg = MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
6869 BuildMI(*MI.getParent(), MI, DL, get(AMDGPU::V_READFIRSTLANE_B32), Reg)
6870 .add(Src0);
6871 Src0.ChangeToRegister(Reg, false);
6872 }
6873 if (Src1.isReg() && RI.isVGPR(MRI, Src1.getReg())) {
6874 Register Reg = MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
6875 const DebugLoc &DL = MI.getDebugLoc();
6876 BuildMI(*MI.getParent(), MI, DL, get(AMDGPU::V_READFIRSTLANE_B32), Reg)
6877 .add(Src1);
6878 Src1.ChangeToRegister(Reg, false);
6879 }
6880 return;
6881 }
6882
6883 // Special case: V_FMAC_F32 and V_FMAC_F16 have src2.
6884 if (Opc == AMDGPU::V_FMAC_F32_e32 || Opc == AMDGPU::V_FMAC_F16_e32) {
6885 int Src2Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src2);
6886 if (!RI.isVGPR(MRI, MI.getOperand(Src2Idx).getReg()))
6887 legalizeOpWithMove(MI, Src2Idx);
6888 }
6889
6890 // VOP2 src0 instructions support all operand types, so we don't need to check
6891 // their legality. If src1 is already legal, we don't need to do anything.
6892 if (isLegalRegOperand(MRI, InstrDesc.operands()[Src1Idx], Src1))
6893 return;
6894
6895 // Special case: V_READLANE_B32 accepts only immediate or SGPR operands for
6896 // lane select. Fix up using V_READFIRSTLANE, since we assume that the lane
6897 // select is uniform.
6898 if (Opc == AMDGPU::V_READLANE_B32 && Src1.isReg() &&
6899 RI.isVGPR(MRI, Src1.getReg())) {
6900 Register Reg = MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
6901 const DebugLoc &DL = MI.getDebugLoc();
6902 BuildMI(*MI.getParent(), MI, DL, get(AMDGPU::V_READFIRSTLANE_B32), Reg)
6903 .add(Src1);
6904 Src1.ChangeToRegister(Reg, false);
6905 return;
6906 }
6907
6908 // We do not use commuteInstruction here because it is too aggressive and will
6909 // commute if it is possible. We only want to commute here if it improves
6910 // legality. This can be called a fairly large number of times so don't waste
6911 // compile time pointlessly swapping and checking legality again.
6912 if (HasImplicitSGPR || !MI.isCommutable()) {
6913 legalizeOpWithMove(MI, Src1Idx);
6914 return;
6915 }
6916
6917 // If src0 can be used as src1, commuting will make the operands legal.
6918 // Otherwise we have to give up and insert a move.
6919 //
6920 // TODO: Other immediate-like operand kinds could be commuted if there was a
6921 // MachineOperand::ChangeTo* for them.
6922 if ((!Src1.isImm() && !Src1.isReg()) ||
6923 !isLegalRegOperand(MRI, InstrDesc.operands()[Src1Idx], Src0)) {
6924 legalizeOpWithMove(MI, Src1Idx);
6925 return;
6926 }
6927
6928 int CommutedOpc = commuteOpcode(MI);
6929 if (CommutedOpc == -1) {
6930 legalizeOpWithMove(MI, Src1Idx);
6931 return;
6932 }
6933
6934 MI.setDesc(get(CommutedOpc));
6935
6936 Register Src0Reg = Src0.getReg();
6937 unsigned Src0SubReg = Src0.getSubReg();
6938 bool Src0Kill = Src0.isKill();
6939
6940 if (Src1.isImm())
6941 Src0.ChangeToImmediate(Src1.getImm());
6942 else if (Src1.isReg()) {
6943 Src0.ChangeToRegister(Src1.getReg(), false, false, Src1.isKill());
6944 Src0.setSubReg(Src1.getSubReg());
6945 } else
6946 llvm_unreachable("Should only have register or immediate operands");
6947
6948 Src1.ChangeToRegister(Src0Reg, false, false, Src0Kill);
6949 Src1.setSubReg(Src0SubReg);
6951}
6952
6953// Legalize VOP3 operands. All operand types are supported for any operand
6954// but only one literal constant and only starting from GFX10.
6956 MachineInstr &MI) const {
6957 unsigned Opc = MI.getOpcode();
6958
6959 int VOP3Idx[3] = {
6960 AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0),
6961 AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src1),
6962 AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src2)
6963 };
6964
6965 if (Opc == AMDGPU::V_PERMLANE16_B32_e64 ||
6966 Opc == AMDGPU::V_PERMLANEX16_B32_e64 ||
6967 Opc == AMDGPU::V_PERMLANE_BCAST_B32_e64 ||
6968 Opc == AMDGPU::V_PERMLANE_UP_B32_e64 ||
6969 Opc == AMDGPU::V_PERMLANE_DOWN_B32_e64 ||
6970 Opc == AMDGPU::V_PERMLANE_XOR_B32_e64 ||
6971 Opc == AMDGPU::V_PERMLANE_IDX_GEN_B32_e64) {
6972 // src1 and src2 must be scalar
6973 MachineOperand &Src1 = MI.getOperand(VOP3Idx[1]);
6974 const DebugLoc &DL = MI.getDebugLoc();
6975 if (Src1.isReg() && !RI.isSGPRClass(MRI.getRegClass(Src1.getReg()))) {
6976 Register Reg = MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
6977 BuildMI(*MI.getParent(), MI, DL, get(AMDGPU::V_READFIRSTLANE_B32), Reg)
6978 .add(Src1);
6979 Src1.ChangeToRegister(Reg, false);
6980 }
6981 if (VOP3Idx[2] != -1) {
6982 MachineOperand &Src2 = MI.getOperand(VOP3Idx[2]);
6983 if (Src2.isReg() && !RI.isSGPRClass(MRI.getRegClass(Src2.getReg()))) {
6984 Register Reg = MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
6985 BuildMI(*MI.getParent(), MI, DL, get(AMDGPU::V_READFIRSTLANE_B32), Reg)
6986 .add(Src2);
6987 Src2.ChangeToRegister(Reg, false);
6988 }
6989 }
6990 }
6991
6992 // Find the one SGPR operand we are allowed to use.
6993 int ConstantBusLimit = ST.getConstantBusLimit(Opc);
6994 int LiteralLimit = ST.hasVOP3Literal() ? 1 : 0;
6995 SmallDenseSet<unsigned> SGPRsUsed;
6996 Register SGPRReg = findUsedSGPR(MI, VOP3Idx);
6997 if (SGPRReg) {
6998 SGPRsUsed.insert(SGPRReg);
6999 --ConstantBusLimit;
7000 }
7001
7002 for (int Idx : VOP3Idx) {
7003 if (Idx == -1)
7004 break;
7005 MachineOperand &MO = MI.getOperand(Idx);
7006
7007 if (!MO.isReg()) {
7008 if (isInlineConstant(MO, get(Opc).operands()[Idx]))
7009 continue;
7010
7011 if (LiteralLimit > 0 && ConstantBusLimit > 0) {
7012 --LiteralLimit;
7013 --ConstantBusLimit;
7014 continue;
7015 }
7016
7017 --LiteralLimit;
7018 --ConstantBusLimit;
7019 legalizeOpWithMove(MI, Idx);
7020 continue;
7021 }
7022
7023 if (!RI.isSGPRClass(RI.getRegClassForReg(MRI, MO.getReg())))
7024 continue; // VGPRs are legal
7025
7026 // We can use one SGPR in each VOP3 instruction prior to GFX10
7027 // and two starting from GFX10.
7028 if (SGPRsUsed.count(MO.getReg()))
7029 continue;
7030 if (ConstantBusLimit > 0) {
7031 SGPRsUsed.insert(MO.getReg());
7032 --ConstantBusLimit;
7033 continue;
7034 }
7035
7036 // If we make it this far, then the operand is not legal and we must
7037 // legalize it.
7038 legalizeOpWithMove(MI, Idx);
7039 }
7040
7041 // Special case: V_FMAC_F32 and V_FMAC_F16 have src2 tied to vdst.
7042 if ((Opc == AMDGPU::V_FMAC_F32_e64 || Opc == AMDGPU::V_FMAC_F16_e64) &&
7043 !RI.isVGPR(MRI, MI.getOperand(VOP3Idx[2]).getReg()))
7044 legalizeOpWithMove(MI, VOP3Idx[2]);
7045
7046 // Fix the register class of single-sgpr-read instructions on gfx12+. See
7047 // SIInstrInfo::isLegalSingleSGPRReadInstOperand for more information.
7049 for (unsigned I = 0; I < 3; ++I) {
7050 if (!isLegalSingleSGPRReadInstOperand(MRI, MI, /*SrcN=*/I))
7051 legalizeOpWithMove(MI, VOP3Idx[I]);
7052 }
7053 }
7054}
7055
7058 const TargetRegisterClass *DstRC /*=nullptr*/) const {
7059 const TargetRegisterClass *VRC = MRI.getRegClass(SrcReg);
7060 const TargetRegisterClass *SRC = RI.getEquivalentSGPRClass(VRC);
7061 if (DstRC)
7062 SRC = RI.getCommonSubClass(SRC, DstRC);
7063
7064 Register DstReg = MRI.createVirtualRegister(SRC);
7065 unsigned SubRegs = RI.getRegSizeInBits(*VRC) / 32;
7066
7067 if (RI.hasAGPRs(VRC)) {
7068 VRC = RI.getEquivalentVGPRClass(VRC);
7069 Register NewSrcReg = MRI.createVirtualRegister(VRC);
7070 BuildMI(*UseMI.getParent(), UseMI, UseMI.getDebugLoc(),
7071 get(TargetOpcode::COPY), NewSrcReg)
7072 .addReg(SrcReg);
7073 SrcReg = NewSrcReg;
7074 }
7075
7076 if (SubRegs == 1) {
7077 BuildMI(*UseMI.getParent(), UseMI, UseMI.getDebugLoc(),
7078 get(AMDGPU::V_READFIRSTLANE_B32), DstReg)
7079 .addReg(SrcReg);
7080 return DstReg;
7081 }
7082
7084 for (unsigned i = 0; i < SubRegs; ++i) {
7085 Register SGPR = MRI.createVirtualRegister(&AMDGPU::SGPR_32RegClass);
7086 BuildMI(*UseMI.getParent(), UseMI, UseMI.getDebugLoc(),
7087 get(AMDGPU::V_READFIRSTLANE_B32), SGPR)
7088 .addReg(SrcReg, {}, RI.getSubRegFromChannel(i));
7089 SRegs.push_back(SGPR);
7090 }
7091
7093 BuildMI(*UseMI.getParent(), UseMI, UseMI.getDebugLoc(),
7094 get(AMDGPU::REG_SEQUENCE), DstReg);
7095 for (unsigned i = 0; i < SubRegs; ++i) {
7096 MIB.addReg(SRegs[i]);
7097 MIB.addImm(RI.getSubRegFromChannel(i));
7098 }
7099 return DstReg;
7100}
7101
7103 MachineInstr &MI) const {
7104
7105 // If the pointer is store in VGPRs, then we need to move them to
7106 // SGPRs using v_readfirstlane. This is safe because we only select
7107 // loads with uniform pointers to SMRD instruction so we know the
7108 // pointer value is uniform.
7109 MachineOperand *SBase = getNamedOperand(MI, AMDGPU::OpName::sbase);
7110 if (SBase && !RI.isSGPRClass(MRI.getRegClass(SBase->getReg()))) {
7111 Register SGPR = readlaneVGPRToSGPR(SBase->getReg(), MI, MRI);
7112 SBase->setReg(SGPR);
7113 }
7114 MachineOperand *SOff = getNamedOperand(MI, AMDGPU::OpName::soffset);
7115 if (SOff && !RI.isSGPRReg(MRI, SOff->getReg())) {
7116 Register SGPR = readlaneVGPRToSGPR(SOff->getReg(), MI, MRI);
7117 SOff->setReg(SGPR);
7118 }
7119}
7120
7122 unsigned Opc = Inst.getOpcode();
7123 int OldSAddrIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::saddr);
7124 if (OldSAddrIdx < 0)
7125 return false;
7126
7127 assert(isSegmentSpecificFLAT(Inst) || (isFLAT(Inst) && ST.hasFlatGVSMode()));
7128
7129 int NewOpc = AMDGPU::getGlobalVaddrOp(Opc);
7130 if (NewOpc < 0)
7132 if (NewOpc < 0)
7133 return false;
7134
7135 MachineRegisterInfo &MRI = Inst.getMF()->getRegInfo();
7136 MachineOperand &SAddr = Inst.getOperand(OldSAddrIdx);
7137 if (RI.isSGPRReg(MRI, SAddr.getReg()))
7138 return false;
7139
7140 int NewVAddrIdx = AMDGPU::getNamedOperandIdx(NewOpc, AMDGPU::OpName::vaddr);
7141 if (NewVAddrIdx < 0)
7142 return false;
7143
7144 int OldVAddrIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::vaddr);
7145
7146 // Check vaddr, it shall be zero or absent.
7147 MachineInstr *VAddrDef = nullptr;
7148 if (OldVAddrIdx >= 0) {
7149 MachineOperand &VAddr = Inst.getOperand(OldVAddrIdx);
7150 VAddrDef = MRI.getUniqueVRegDef(VAddr.getReg());
7151 if (!VAddrDef || !VAddrDef->isMoveImmediate() ||
7152 !VAddrDef->getOperand(1).isImm() ||
7153 VAddrDef->getOperand(1).getImm() != 0)
7154 return false;
7155 }
7156
7157 const MCInstrDesc &NewDesc = get(NewOpc);
7158 Inst.setDesc(NewDesc);
7159
7160 // Callers expect iterator to be valid after this call, so modify the
7161 // instruction in place.
7162 if (OldVAddrIdx == NewVAddrIdx) {
7163 MachineOperand &NewVAddr = Inst.getOperand(NewVAddrIdx);
7164 // Clear use list from the old vaddr holding a zero register.
7165 MRI.removeRegOperandFromUseList(&NewVAddr);
7166 MRI.moveOperands(&NewVAddr, &SAddr, 1);
7167 Inst.removeOperand(OldSAddrIdx);
7168 // Update the use list with the pointer we have just moved from vaddr to
7169 // saddr position. Otherwise new vaddr will be missing from the use list.
7170 MRI.removeRegOperandFromUseList(&NewVAddr);
7171 MRI.addRegOperandToUseList(&NewVAddr);
7172 } else {
7173 assert(OldSAddrIdx == NewVAddrIdx);
7174
7175 if (OldVAddrIdx >= 0) {
7176 int NewVDstIn = AMDGPU::getNamedOperandIdx(NewOpc,
7177 AMDGPU::OpName::vdst_in);
7178
7179 // removeOperand doesn't try to fixup tied operand indexes at it goes, so
7180 // it asserts. Untie the operands for now and retie them afterwards.
7181 if (NewVDstIn != -1) {
7182 int OldVDstIn = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::vdst_in);
7183 Inst.untieRegOperand(OldVDstIn);
7184 }
7185
7186 Inst.removeOperand(OldVAddrIdx);
7187
7188 if (NewVDstIn != -1) {
7189 int NewVDst = AMDGPU::getNamedOperandIdx(NewOpc, AMDGPU::OpName::vdst);
7190 Inst.tieOperands(NewVDst, NewVDstIn);
7191 }
7192 }
7193 }
7194
7195 if (VAddrDef && MRI.use_nodbg_empty(VAddrDef->getOperand(0).getReg()))
7196 VAddrDef->eraseFromParent();
7197
7198 return true;
7199}
7200
7201// FIXME: Remove this when SelectionDAG is obsoleted.
7203 MachineInstr &MI) const {
7204 if (!isSegmentSpecificFLAT(MI) && !ST.hasFlatGVSMode())
7205 return;
7206
7207 // Fixup SGPR operands in VGPRs. We only select these when the DAG divergence
7208 // thinks they are uniform, so a readfirstlane should be valid.
7209 MachineOperand *SAddr = getNamedOperand(MI, AMDGPU::OpName::saddr);
7210 if (!SAddr || RI.isSGPRClass(MRI.getRegClass(SAddr->getReg())))
7211 return;
7212
7214 return;
7215
7216 const TargetRegisterClass *DeclaredRC =
7217 getRegClass(MI.getDesc(), SAddr->getOperandNo());
7218
7219 Register ToSGPR = readlaneVGPRToSGPR(SAddr->getReg(), MI, MRI, DeclaredRC);
7220 SAddr->setReg(ToSGPR);
7221}
7222
7225 const TargetRegisterClass *DstRC,
7228 const DebugLoc &DL) const {
7229 Register OpReg = Op.getReg();
7230 unsigned OpSubReg = Op.getSubReg();
7231
7232 const TargetRegisterClass *OpRC = RI.getSubClassWithSubReg(
7233 RI.getRegClassForReg(MRI, OpReg), OpSubReg);
7234
7235 // Check if operand is already the correct register class.
7236 if (DstRC == OpRC)
7237 return;
7238
7239 Register DstReg = MRI.createVirtualRegister(DstRC);
7240 auto Copy = BuildMI(InsertMBB, I, DL, get(AMDGPU::COPY), DstReg)
7241 .addReg(OpReg, {}, OpSubReg);
7242 Op.setReg(DstReg);
7243 Op.setSubReg(AMDGPU::NoSubRegister);
7244
7245 MachineInstr *Def = MRI.getVRegDef(OpReg);
7246 if (!Def)
7247 return;
7248
7249 // Try to eliminate the copy if it is copying an immediate value.
7250 if (Def->isMoveImmediate() && DstRC != &AMDGPU::VReg_1RegClass)
7251 foldImmediate(*Copy, *Def, OpReg, &MRI);
7252
7253 bool ImpDef = Def->isImplicitDef();
7254 while (!ImpDef && Def && Def->isCopy()) {
7255 if (Def->getOperand(1).getReg().isPhysical())
7256 break;
7257 Def = MRI.getUniqueVRegDef(Def->getOperand(1).getReg());
7258 ImpDef = Def && Def->isImplicitDef();
7259 }
7260 if (!RI.isSGPRClass(DstRC) && !Copy->readsRegister(AMDGPU::EXEC, &RI) &&
7261 !ImpDef)
7262 Copy.addReg(AMDGPU::EXEC, RegState::Implicit);
7263}
7264
7265// Emit the actual waterfall loop, executing the wrapped instruction for each
7266// unique value of \p ScalarOps across all lanes. In the best case we execute 1
7267// iteration, in the worst case we execute 64 (once per lane).
7270 MachineBasicBlock &LoopBB, MachineBasicBlock &BodyBB, const DebugLoc &DL,
7271 ArrayRef<MachineOperand *> ScalarOps, ArrayRef<Register> PhySGPRs = {}) {
7272 MachineFunction &MF = *LoopBB.getParent();
7274 const SIRegisterInfo *TRI = ST.getRegisterInfo();
7276 const auto *BoolXExecRC = TRI->getWaveMaskRegClass();
7277
7278 // Emit v_cmpx_eq and s_andn2_wrexec when both instructions are
7279 // available. Otherwise, use the previous pattern of v_cmp_eq,
7280 // s_and_saveexec, and s_xor.
7281 bool UseNewExecInstructions =
7282 ST.hasNoSdstCMPX() && TII.pseudoToMCOpcode(LMC.AndN2WrExecOpc) != -1;
7283
7285 Register CondReg;
7286
7287 Register PhiExec;
7288 Register NewExec;
7289
7290 if (UseNewExecInstructions) {
7291 PhiExec = MRI.createVirtualRegister(BoolXExecRC);
7292 NewExec = MRI.createVirtualRegister(BoolXExecRC);
7293 Register InitExec = MRI.createVirtualRegister(BoolXExecRC);
7294 BuildMI(PredBB, PredBB.end(), DL, TII.get(LMC.MovOpc), InitExec)
7295 .addReg(LMC.ExecReg);
7296
7297 BuildMI(LoopBB, I, DL, TII.get(TargetOpcode::PHI), PhiExec)
7298 .addReg(InitExec)
7299 .addMBB(&PredBB)
7300 .addReg(NewExec)
7301 .addMBB(&BodyBB);
7302 }
7303
7304 // Placement of v_cmpx instructions (when index is longer than 64 bit)
7305 // involves a trade-off between register pressure and latency:
7306 // (a) Defering all v_cmpx after all v_readfirstlane may increase
7307 // register pressure because arguments and results of all
7308 // v_readfirstlane instructions must stay live until deferred v_cmpx use them.
7309 // (b) Interleaving v_cmpx with v_readfirstlanes may reduce live ranges and
7310 // increase latency by placing v_readfirstlane instructions
7311 // immediately before v_cmpx instruction that directly depend on it.
7312 ///
7313 // Emitting interleaved v_cmpx and v_readfirstlane requires
7314 // block splitting because v_cmpx changes EXEC mask and therefore for safety
7315 // v_cmpx needs to be treated as terminator until after register allocation
7316 // (spill placement) and instruction reordering.
7317 //
7318 // Current implementation defers v_cmpx and leaves other instruction
7319 // scheduling decisions to later passes, where register pressure is known or
7320 // easier to approximate.
7321 // Non-terminators (V_READFIRSTLANE and REG_SEQUENCE) are inserted before I;
7322 // v_cmpx instructions are inserted at the end of LoopBB.
7323 // After the first v_cmpx is emitted, I is updated to point to it
7324 // so subsequent non-terminators are inserted before all v_cmpx instructions.
7325 for (auto [Idx, ScalarOp] : enumerate(ScalarOps)) {
7326 unsigned RegSize = TRI->getRegSizeInBits(ScalarOp->getReg(), MRI);
7327 unsigned NumSubRegs = RegSize / 32;
7328 Register VScalarOp = ScalarOp->getReg();
7329
7330 const TargetRegisterClass *RFLSrcRC =
7331 TII.getRegClass(TII.get(AMDGPU::V_READFIRSTLANE_B32), 1);
7332
7333 if (NumSubRegs == 1) {
7334 const TargetRegisterClass *VScalarOpRC = MRI.getRegClass(VScalarOp);
7335 if (const TargetRegisterClass *Common =
7336 TRI->getCommonSubClass(VScalarOpRC, RFLSrcRC);
7337 Common != VScalarOpRC) {
7338 Register VRReg = MRI.createVirtualRegister(Common);
7339 BuildMI(LoopBB, I, DL, TII.get(AMDGPU::COPY), VRReg).addReg(VScalarOp);
7340 VScalarOp = VRReg;
7341 }
7342 Register CurReg = MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
7343
7344 BuildMI(LoopBB, I, DL, TII.get(AMDGPU::V_READFIRSTLANE_B32), CurReg)
7345 .addReg(VScalarOp);
7346
7347 if (UseNewExecInstructions) {
7348 auto CmpxMI = BuildMI(LoopBB, LoopBB.end(), DL,
7349 TII.get(AMDGPU::V_CMPX_EQ_U32_nosdst_e32_term))
7350 .addReg(CurReg)
7351 .addReg(VScalarOp);
7352 if (I == LoopBB.end())
7353 I = CmpxMI.getInstr()->getIterator();
7354 } else {
7355 Register NewCondReg = MRI.createVirtualRegister(BoolXExecRC);
7356
7357 BuildMI(LoopBB, I, DL, TII.get(AMDGPU::V_CMP_EQ_U32_e64), NewCondReg)
7358 .addReg(CurReg)
7359 .addReg(VScalarOp);
7360
7361 // Combine the comparison results with AND.
7362 if (!CondReg) { // First.
7363 CondReg = NewCondReg;
7364 } else { // If not the first, we create an AND.
7365 Register AndReg = MRI.createVirtualRegister(BoolXExecRC);
7366 BuildMI(LoopBB, I, DL, TII.get(LMC.AndOpc), AndReg)
7367 .addReg(CondReg)
7368 .addReg(NewCondReg);
7369 CondReg = AndReg;
7370 }
7371 }
7372
7373 // Update ScalarOp operand to use the SGPR ScalarOp.
7374 if (PhySGPRs.empty() || !PhySGPRs[Idx].isValid())
7375 ScalarOp->setReg(CurReg);
7376 else {
7377 // Insert into the same block of use
7378 BuildMI(*ScalarOp->getParent()->getParent(), ScalarOp->getParent(), DL,
7379 TII.get(AMDGPU::COPY), PhySGPRs[Idx])
7380 .addReg(CurReg);
7381 ScalarOp->setReg(PhySGPRs[Idx]);
7382 }
7383 ScalarOp->setIsKill();
7384 } else {
7385 SmallVector<Register, 8> ReadlanePieces;
7386 RegState VScalarOpUndef = getUndefRegState(ScalarOp->isUndef());
7387 assert(NumSubRegs % 2 == 0 && NumSubRegs <= 32 &&
7388 "Unhandled register size");
7389
7390 for (unsigned Idx = 0; Idx < NumSubRegs; Idx += 2) {
7391 Register CurRegLo =
7392 MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
7393 Register CurRegHi =
7394 MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
7395
7396 // Read the next variant <- also loop target.
7397 BuildMI(LoopBB, I, DL, TII.get(AMDGPU::V_READFIRSTLANE_B32), CurRegLo)
7398 .addReg(VScalarOp, VScalarOpUndef, TRI->getSubRegFromChannel(Idx));
7399
7400 // Read the next variant <- also loop target.
7401 BuildMI(LoopBB, I, DL, TII.get(AMDGPU::V_READFIRSTLANE_B32), CurRegHi)
7402 .addReg(VScalarOp, VScalarOpUndef,
7403 TRI->getSubRegFromChannel(Idx + 1));
7404
7405 ReadlanePieces.push_back(CurRegLo);
7406 ReadlanePieces.push_back(CurRegHi);
7407
7408 // Comparison is to be done as 64-bit.
7409 Register CurReg = MRI.createVirtualRegister(&AMDGPU::SGPR_64RegClass);
7410 BuildMI(LoopBB, I, DL, TII.get(AMDGPU::REG_SEQUENCE), CurReg)
7411 .addReg(CurRegLo)
7412 .addImm(AMDGPU::sub0)
7413 .addReg(CurRegHi)
7414 .addImm(AMDGPU::sub1);
7415
7416 unsigned SubReg =
7417 NumSubRegs <= 2 ? 0 : TRI->getSubRegFromChannel(Idx, 2);
7418
7419 if (UseNewExecInstructions) {
7420 auto CmpxMI = BuildMI(LoopBB, LoopBB.end(), DL,
7421 TII.get(AMDGPU::V_CMPX_EQ_U64_nosdst_e32_term))
7422 .addReg(CurReg)
7423 .addReg(VScalarOp, VScalarOpUndef, SubReg);
7424 if (I == LoopBB.end())
7425 I = CmpxMI.getInstr()->getIterator();
7426 } else {
7427 Register NewCondReg = MRI.createVirtualRegister(BoolXExecRC);
7428 BuildMI(LoopBB, I, DL, TII.get(AMDGPU::V_CMP_EQ_U64_e64), NewCondReg)
7429 .addReg(CurReg)
7430 .addReg(VScalarOp, VScalarOpUndef, SubReg);
7431
7432 // Combine the comparison results with AND.
7433 if (!CondReg) { // First.
7434 CondReg = NewCondReg;
7435 } else { // If not the first, we create an AND.
7436 Register AndReg = MRI.createVirtualRegister(BoolXExecRC);
7437 BuildMI(LoopBB, I, DL, TII.get(LMC.AndOpc), AndReg)
7438 .addReg(CondReg)
7439 .addReg(NewCondReg);
7440 CondReg = AndReg;
7441 }
7442 }
7443 } // End for loop.
7444
7445 const auto *SScalarOpRC =
7446 TRI->getEquivalentSGPRClass(MRI.getRegClass(VScalarOp));
7447 Register SScalarOp = MRI.createVirtualRegister(SScalarOpRC);
7448
7449 // Build scalar ScalarOp.
7450 auto Merge =
7451 BuildMI(LoopBB, I, DL, TII.get(AMDGPU::REG_SEQUENCE), SScalarOp);
7452 unsigned Channel = 0;
7453 for (Register Piece : ReadlanePieces) {
7454 Merge.addReg(Piece).addImm(TRI->getSubRegFromChannel(Channel++));
7455 }
7456
7457 // Update ScalarOp operand to use the SGPR ScalarOp.
7458 if (PhySGPRs.empty() || !PhySGPRs[Idx].isValid())
7459 ScalarOp->setReg(SScalarOp);
7460 else {
7461 BuildMI(*ScalarOp->getParent()->getParent(), ScalarOp->getParent(), DL,
7462 TII.get(AMDGPU::COPY), PhySGPRs[Idx])
7463 .addReg(SScalarOp);
7464 ScalarOp->setReg(PhySGPRs[Idx]);
7465 }
7466 ScalarOp->setIsKill();
7467 }
7468 }
7469
7470 // Instructions AndSaveExecOpc and AndN2WrExecOpc that modify EXEC mask
7471 // should have isTerminator=1 but terminators that define
7472 // virtual registers are not supported.
7473 Register SaveExec;
7474 if (!UseNewExecInstructions) {
7475 SaveExec = MRI.createVirtualRegister(BoolXExecRC);
7476 MRI.setSimpleHint(SaveExec, CondReg);
7477
7478 // Update EXEC to matching lanes, saving original to SaveExec.
7479 BuildMI(LoopBB, I, DL, TII.get(LMC.AndSaveExecOpc), SaveExec)
7480 .addReg(CondReg, RegState::Kill);
7481 }
7482
7483 // The original instruction is here; we insert the terminators after it.
7484 I = BodyBB.end();
7485
7486 if (UseNewExecInstructions) {
7487 MRI.setSimpleHint(NewExec, PhiExec);
7488 BuildMI(BodyBB, I, DL, TII.get(LMC.AndN2WrExecOpc), NewExec)
7489 .addReg(PhiExec);
7490 } else {
7491 // Update EXEC, switch all done bits to 0 and all todo bits to 1.
7492 BuildMI(BodyBB, I, DL, TII.get(LMC.XorTermOpc), LMC.ExecReg)
7493 .addReg(LMC.ExecReg)
7494 .addReg(SaveExec);
7495 }
7496
7497 BuildMI(BodyBB, I, DL, TII.get(AMDGPU::SI_WATERFALL_LOOP)).addMBB(&LoopBB);
7498}
7499
7500// Build a waterfall loop around \p MI, replacing the VGPR \p ScalarOp register
7501// with SGPRs by iterating over all unique values across all lanes.
7502// Returns the loop basic block that now contains \p MI.
7503static MachineBasicBlock *
7507 MachineBasicBlock::iterator Begin = nullptr,
7508 MachineBasicBlock::iterator End = nullptr,
7509 ArrayRef<Register> PhySGPRs = {}) {
7510 assert((PhySGPRs.empty() || PhySGPRs.size() == ScalarOps.size()) &&
7511 "Physical SGPRs must be empty or match the number of scalar operands");
7513 MachineFunction &MF = *MBB.getParent();
7515 const SIRegisterInfo *TRI = ST.getRegisterInfo();
7516 MachineRegisterInfo &MRI = MF.getRegInfo();
7517 if (!Begin.isValid())
7518 Begin = &MI;
7519 if (!End.isValid()) {
7520 End = &MI;
7521 ++End;
7522 }
7523 const DebugLoc &DL = MI.getDebugLoc();
7525 const auto *BoolXExecRC = TRI->getWaveMaskRegClass();
7526
7527 // Save SCC. Waterfall Loop may overwrite SCC.
7528 Register SaveSCCReg;
7529
7530 // FIXME: We should maintain SCC liveness while doing the FixSGPRCopies walk
7531 // rather than unlimited scan everywhere
7532 bool SCCNotDead =
7533 MBB.computeRegisterLiveness(TRI, AMDGPU::SCC, MI,
7534 std::numeric_limits<unsigned>::max()) !=
7536 if (SCCNotDead) {
7537 SaveSCCReg = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
7538 BuildMI(MBB, Begin, DL, TII.get(AMDGPU::S_CSELECT_B32), SaveSCCReg)
7539 .addImm(1)
7540 .addImm(0);
7541 }
7542
7543 Register SaveExec = MRI.createVirtualRegister(BoolXExecRC);
7544
7545 // Save the EXEC mask
7546 BuildMI(MBB, Begin, DL, TII.get(LMC.MovOpc), SaveExec).addReg(LMC.ExecReg);
7547
7548 // Killed uses in the instruction we are waterfalling around will be
7549 // incorrect due to the added control-flow.
7551 ++AfterMI;
7552 for (auto I = Begin; I != AfterMI; I++) {
7553 for (auto &MO : I->all_uses())
7554 MRI.clearKillFlags(MO.getReg());
7555 }
7556
7557 // To insert the loop we need to split the block. Move everything after this
7558 // point to a new block, and insert a new empty block between the two.
7561 MachineBasicBlock *RemainderBB = MF.CreateMachineBasicBlock();
7563 ++MBBI;
7564
7565 MF.insert(MBBI, LoopBB);
7566 MF.insert(MBBI, BodyBB);
7567 MF.insert(MBBI, RemainderBB);
7568
7569 LoopBB->addSuccessor(BodyBB);
7570 BodyBB->addSuccessor(LoopBB);
7571 BodyBB->addSuccessor(RemainderBB);
7572
7573 // Move Begin to MI to the BodyBB, and the remainder of the block to
7574 // RemainderBB.
7575 RemainderBB->transferSuccessorsAndUpdatePHIs(&MBB);
7576 RemainderBB->splice(RemainderBB->begin(), &MBB, End, MBB.end());
7577 BodyBB->splice(BodyBB->begin(), &MBB, Begin, MBB.end());
7578
7579 MBB.addSuccessor(LoopBB);
7580
7581 // Update dominators. We know that MBB immediately dominates LoopBB, that
7582 // LoopBB immediately dominates BodyBB, and BodyBB immediately dominates
7583 // RemainderBB. RemainderBB immediately dominates all of the successors
7584 // transferred to it from MBB that MBB used to properly dominate.
7585 if (MDT) {
7586 MDT->addNewBlock(LoopBB, &MBB);
7587 MDT->addNewBlock(BodyBB, LoopBB);
7588 MDT->addNewBlock(RemainderBB, BodyBB);
7589 for (auto &Succ : RemainderBB->successors()) {
7590 if (MDT->properlyDominates(&MBB, Succ)) {
7591 MDT->changeImmediateDominator(Succ, RemainderBB);
7592 }
7593 }
7594 }
7595
7596 emitLoadScalarOpsFromVGPRLoop(TII, MRI, MBB, *LoopBB, *BodyBB, DL, ScalarOps,
7597 PhySGPRs);
7598
7599 MachineBasicBlock::iterator First = RemainderBB->begin();
7600 // Restore SCC
7601 if (SCCNotDead) {
7602 BuildMI(*RemainderBB, First, DL, TII.get(AMDGPU::S_CMP_LG_U32))
7603 .addReg(SaveSCCReg, RegState::Kill)
7604 .addImm(0);
7605 }
7606
7607 // Restore the EXEC mask
7608 BuildMI(*RemainderBB, First, DL, TII.get(LMC.MovOpc), LMC.ExecReg)
7609 .addReg(SaveExec);
7610 return BodyBB;
7611}
7612
7613// Extract pointer from Rsrc and return a zero-value Rsrc replacement.
7614static std::tuple<unsigned, unsigned>
7616 MachineBasicBlock &MBB = *MI.getParent();
7617 MachineFunction &MF = *MBB.getParent();
7618 MachineRegisterInfo &MRI = MF.getRegInfo();
7619
7620 // Extract the ptr from the resource descriptor.
7621 unsigned RsrcPtr =
7622 TII.buildExtractSubReg(MI, MRI, Rsrc, &AMDGPU::VReg_128RegClass,
7623 AMDGPU::sub0_sub1, &AMDGPU::VReg_64RegClass);
7624
7625 // Create an empty resource descriptor
7626 Register Zero64 = MRI.createVirtualRegister(&AMDGPU::SReg_64RegClass);
7627 Register SRsrcFormatLo = MRI.createVirtualRegister(&AMDGPU::SGPR_32RegClass);
7628 Register SRsrcFormatHi = MRI.createVirtualRegister(&AMDGPU::SGPR_32RegClass);
7629 Register NewSRsrc = MRI.createVirtualRegister(&AMDGPU::SGPR_128RegClass);
7630 uint64_t RsrcDataFormat = TII.getDefaultRsrcDataFormat();
7631
7632 // Zero64 = 0
7633 BuildMI(MBB, MI, MI.getDebugLoc(), TII.get(AMDGPU::S_MOV_B64), Zero64)
7634 .addImm(0);
7635
7636 // SRsrcFormatLo = RSRC_DATA_FORMAT{31-0}
7637 BuildMI(MBB, MI, MI.getDebugLoc(), TII.get(AMDGPU::S_MOV_B32), SRsrcFormatLo)
7638 .addImm(Lo_32(RsrcDataFormat));
7639
7640 // SRsrcFormatHi = RSRC_DATA_FORMAT{63-32}
7641 BuildMI(MBB, MI, MI.getDebugLoc(), TII.get(AMDGPU::S_MOV_B32), SRsrcFormatHi)
7642 .addImm(Hi_32(RsrcDataFormat));
7643
7644 // NewSRsrc = {Zero64, SRsrcFormat}
7645 BuildMI(MBB, MI, MI.getDebugLoc(), TII.get(AMDGPU::REG_SEQUENCE), NewSRsrc)
7646 .addReg(Zero64)
7647 .addImm(AMDGPU::sub0_sub1)
7648 .addReg(SRsrcFormatLo)
7649 .addImm(AMDGPU::sub2)
7650 .addReg(SRsrcFormatHi)
7651 .addImm(AMDGPU::sub3);
7652
7653 return std::tuple(RsrcPtr, NewSRsrc);
7654}
7655
7658 MachineDominatorTree *MDT) const {
7659 MachineFunction &MF = *MI.getMF();
7660 MachineRegisterInfo &MRI = MF.getRegInfo();
7661 MachineBasicBlock *CreatedBB = nullptr;
7662
7663 // Legalize True16
7664 if (ST.useRealTrue16Insts())
7666
7667 // Legalize VOP2
7668 if (isVOP2(MI) || isVOPC(MI)) {
7670 return CreatedBB;
7671 }
7672
7673 // Legalize VOP3
7674 if (isVOP3(MI)) {
7676 return CreatedBB;
7677 }
7678
7679 // Legalize SMRD
7680 if (isSMRD(MI)) {
7682 return CreatedBB;
7683 }
7684
7685 // Legalize FLAT
7686 if (isFLAT(MI)) {
7688 return CreatedBB;
7689 }
7690
7691 // Legalize PHI
7692 // The register class of the operands must be the same type as the register
7693 // class of the output.
7694 if (MI.getOpcode() == AMDGPU::PHI) {
7695 const TargetRegisterClass *VRC = getOpRegClass(MI, 0);
7696 assert(!RI.isSGPRClass(VRC));
7697
7698 // Update all the operands so they have the same type.
7699 for (unsigned I = 1, E = MI.getNumOperands(); I != E; I += 2) {
7700 MachineOperand &Op = MI.getOperand(I);
7701 if (!Op.isReg() || !Op.getReg().isVirtual())
7702 continue;
7703
7704 // MI is a PHI instruction.
7705 MachineBasicBlock *InsertBB = MI.getOperand(I + 1).getMBB();
7707
7708 // Avoid creating no-op copies with the same src and dst reg class. These
7709 // confuse some of the machine passes.
7710 legalizeGenericOperand(*InsertBB, Insert, VRC, Op, MRI, MI.getDebugLoc());
7711 }
7712 }
7713
7714 // REG_SEQUENCE doesn't really require operand legalization, but if one has a
7715 // VGPR dest type and SGPR sources, insert copies so all operands are
7716 // VGPRs. This seems to help operand folding / the register coalescer.
7717 if (MI.getOpcode() == AMDGPU::REG_SEQUENCE) {
7718 MachineBasicBlock *MBB = MI.getParent();
7719 const TargetRegisterClass *DstRC = getOpRegClass(MI, 0);
7720 if (RI.hasVGPRs(DstRC)) {
7721 // Update all the operands so they are VGPR register classes. These may
7722 // not be the same register class because REG_SEQUENCE supports mixing
7723 // subregister index types e.g. sub0_sub1 + sub2 + sub3
7724 for (unsigned I = 1, E = MI.getNumOperands(); I != E; I += 2) {
7725 MachineOperand &Op = MI.getOperand(I);
7726 if (!Op.isReg() || !Op.getReg().isVirtual())
7727 continue;
7728
7729 const TargetRegisterClass *OpRC = MRI.getRegClass(Op.getReg());
7730 const TargetRegisterClass *VRC = RI.getEquivalentVGPRClass(OpRC);
7731 if (VRC == OpRC)
7732 continue;
7733
7734 legalizeGenericOperand(*MBB, MI, VRC, Op, MRI, MI.getDebugLoc());
7735 Op.setIsKill();
7736 }
7737 }
7738
7739 return CreatedBB;
7740 }
7741
7742 // Legalize INSERT_SUBREG
7743 // src0 must have the same register class as dst
7744 if (MI.getOpcode() == AMDGPU::INSERT_SUBREG) {
7745 Register Dst = MI.getOperand(0).getReg();
7746 Register Src0 = MI.getOperand(1).getReg();
7747 const TargetRegisterClass *DstRC = MRI.getRegClass(Dst);
7748 const TargetRegisterClass *Src0RC = MRI.getRegClass(Src0);
7749 if (DstRC != Src0RC) {
7750 MachineBasicBlock *MBB = MI.getParent();
7751 MachineOperand &Op = MI.getOperand(1);
7752 legalizeGenericOperand(*MBB, MI, DstRC, Op, MRI, MI.getDebugLoc());
7753 }
7754 return CreatedBB;
7755 }
7756
7757 // Legalize SI_INIT_M0
7758 if (MI.getOpcode() == AMDGPU::SI_INIT_M0) {
7759 MachineOperand &Src = MI.getOperand(0);
7760 if (Src.isReg() && RI.hasVectorRegisters(MRI.getRegClass(Src.getReg())))
7761 Src.setReg(readlaneVGPRToSGPR(Src.getReg(), MI, MRI));
7762 return CreatedBB;
7763 }
7764
7765 // Legalize S_BITREPLICATE, S_QUADMASK and S_WQM
7766 if (MI.getOpcode() == AMDGPU::S_BITREPLICATE_B64_B32 ||
7767 MI.getOpcode() == AMDGPU::S_QUADMASK_B32 ||
7768 MI.getOpcode() == AMDGPU::S_QUADMASK_B64 ||
7769 MI.getOpcode() == AMDGPU::S_WQM_B32 ||
7770 MI.getOpcode() == AMDGPU::S_WQM_B64 ||
7771 MI.getOpcode() == AMDGPU::S_INVERSE_BALLOT_U32 ||
7772 MI.getOpcode() == AMDGPU::S_INVERSE_BALLOT_U64) {
7773 MachineOperand &Src = MI.getOperand(1);
7774 if (Src.isReg() && RI.hasVectorRegisters(MRI.getRegClass(Src.getReg())))
7775 Src.setReg(readlaneVGPRToSGPR(Src.getReg(), MI, MRI));
7776 return CreatedBB;
7777 }
7778
7779 // Legalize MIMG/VIMAGE/VSAMPLE and MUBUF/MTBUF for shaders.
7780 //
7781 // Shaders only generate MUBUF/MTBUF instructions via intrinsics or via
7782 // scratch memory access. In both cases, the legalization never involves
7783 // conversion to the addr64 form.
7785 (isMUBUF(MI) || isMTBUF(MI)))) {
7786 AMDGPU::OpName RSrcOpName = (isVIMAGE(MI) || isVSAMPLE(MI))
7787 ? AMDGPU::OpName::rsrc
7788 : AMDGPU::OpName::srsrc;
7789 MachineOperand *SRsrc = getNamedOperand(MI, RSrcOpName);
7790 if (SRsrc && !RI.isSGPRClass(MRI.getRegClass(SRsrc->getReg())))
7791 CreatedBB = generateWaterFallLoop(*this, MI, {SRsrc}, MDT);
7792
7793 AMDGPU::OpName SampOpName =
7794 isMIMG(MI) ? AMDGPU::OpName::ssamp : AMDGPU::OpName::samp;
7795 MachineOperand *SSamp = getNamedOperand(MI, SampOpName);
7796 if (SSamp && !RI.isSGPRClass(MRI.getRegClass(SSamp->getReg())))
7797 CreatedBB = generateWaterFallLoop(*this, MI, {SSamp}, MDT);
7798
7799 return CreatedBB;
7800 }
7801
7802 // Legalize SI_CALL
7803 if (MI.getOpcode() == AMDGPU::SI_CALL_ISEL) {
7804 MachineOperand *Dest = &MI.getOperand(0);
7805 if (!RI.isSGPRClass(MRI.getRegClass(Dest->getReg()))) {
7806 createWaterFallForSiCall(&MI, MDT, {Dest});
7807 }
7808 }
7809
7810 // Legalize s_sleep_var.
7811 if (MI.getOpcode() == AMDGPU::S_SLEEP_VAR) {
7812 const DebugLoc &DL = MI.getDebugLoc();
7813 Register Reg = MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
7814 int Src0Idx =
7815 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::src0);
7816 MachineOperand &Src0 = MI.getOperand(Src0Idx);
7817 BuildMI(*MI.getParent(), MI, DL, get(AMDGPU::V_READFIRSTLANE_B32), Reg)
7818 .add(Src0);
7819 Src0.ChangeToRegister(Reg, false);
7820 return nullptr;
7821 }
7822
7823 // Legalize TENSOR_LOAD_TO_LDS_d2/_d4, TENSOR_STORE_FROM_LDS_d2/_d4. All their
7824 // operands are scalar.
7825 if (MI.getOpcode() == AMDGPU::TENSOR_LOAD_TO_LDS_d2 ||
7826 MI.getOpcode() == AMDGPU::TENSOR_LOAD_TO_LDS_d4 ||
7827 MI.getOpcode() == AMDGPU::TENSOR_STORE_FROM_LDS_d2 ||
7828 MI.getOpcode() == AMDGPU::TENSOR_STORE_FROM_LDS_d4) {
7829 for (MachineOperand &Src : MI.explicit_operands()) {
7830 if (Src.isReg() && RI.hasVectorRegisters(MRI.getRegClass(Src.getReg())))
7831 Src.setReg(readlaneVGPRToSGPR(Src.getReg(), MI, MRI));
7832 }
7833 return CreatedBB;
7834 }
7835
7836 // Legalize MUBUF instructions.
7837 bool isSoffsetLegal = true;
7838 int SoffsetIdx =
7839 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::soffset);
7840 if (SoffsetIdx != -1) {
7841 MachineOperand *Soffset = &MI.getOperand(SoffsetIdx);
7842 if (Soffset->isReg() && Soffset->getReg().isVirtual() &&
7843 !RI.isSGPRClass(MRI.getRegClass(Soffset->getReg()))) {
7844 isSoffsetLegal = false;
7845 }
7846 }
7847
7848 bool isRsrcLegal = true;
7849 int RsrcIdx =
7850 AMDGPU::getNamedOperandIdx(MI.getOpcode(), AMDGPU::OpName::srsrc);
7851 if (RsrcIdx != -1) {
7852 MachineOperand *Rsrc = &MI.getOperand(RsrcIdx);
7853 if (Rsrc->isReg() && !RI.isSGPRReg(MRI, Rsrc->getReg()))
7854 isRsrcLegal = false;
7855 }
7856
7857 // The operands are legal.
7858 if (isRsrcLegal && isSoffsetLegal)
7859 return CreatedBB;
7860
7861 if (!isRsrcLegal) {
7862 // Legalize a VGPR Rsrc
7863 //
7864 // If the instruction is _ADDR64, we can avoid a waterfall by extracting
7865 // the base pointer from the VGPR Rsrc, adding it to the VAddr, then using
7866 // a zero-value SRsrc.
7867 //
7868 // If the instruction is _OFFSET (both idxen and offen disabled), and we
7869 // support ADDR64 instructions, we can convert to ADDR64 and do the same as
7870 // above.
7871 //
7872 // Otherwise we are on non-ADDR64 hardware, and/or we have
7873 // idxen/offen/bothen and we fall back to a waterfall loop.
7874
7875 MachineOperand *Rsrc = &MI.getOperand(RsrcIdx);
7876 MachineBasicBlock &MBB = *MI.getParent();
7877
7878 MachineOperand *VAddr = getNamedOperand(MI, AMDGPU::OpName::vaddr);
7879 if (VAddr && AMDGPU::getIfAddr64Inst(MI.getOpcode()) != -1) {
7880 // This is already an ADDR64 instruction so we need to add the pointer
7881 // extracted from the resource descriptor to the current value of VAddr.
7882 Register NewVAddrLo = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
7883 Register NewVAddrHi = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
7884 Register NewVAddr = MRI.createVirtualRegister(&AMDGPU::VReg_64RegClass);
7885
7886 const auto *BoolXExecRC = RI.getWaveMaskRegClass();
7887 Register CondReg0 = MRI.createVirtualRegister(BoolXExecRC);
7888 Register CondReg1 = MRI.createVirtualRegister(BoolXExecRC);
7889
7890 unsigned RsrcPtr, NewSRsrc;
7891 std::tie(RsrcPtr, NewSRsrc) = extractRsrcPtr(*this, MI, *Rsrc);
7892
7893 // NewVaddrLo = RsrcPtr:sub0 + VAddr:sub0
7894 const DebugLoc &DL = MI.getDebugLoc();
7895 BuildMI(MBB, MI, DL, get(AMDGPU::V_ADD_CO_U32_e64), NewVAddrLo)
7896 .addDef(CondReg0)
7897 .addReg(RsrcPtr, {}, AMDGPU::sub0)
7898 .addReg(VAddr->getReg(), {}, AMDGPU::sub0)
7899 .addImm(0);
7900
7901 // NewVaddrHi = RsrcPtr:sub1 + VAddr:sub1
7902 BuildMI(MBB, MI, DL, get(AMDGPU::V_ADDC_U32_e64), NewVAddrHi)
7903 .addDef(CondReg1, RegState::Dead)
7904 .addReg(RsrcPtr, {}, AMDGPU::sub1)
7905 .addReg(VAddr->getReg(), {}, AMDGPU::sub1)
7906 .addReg(CondReg0, RegState::Kill)
7907 .addImm(0);
7908
7909 // NewVaddr = {NewVaddrHi, NewVaddrLo}
7910 BuildMI(MBB, MI, MI.getDebugLoc(), get(AMDGPU::REG_SEQUENCE), NewVAddr)
7911 .addReg(NewVAddrLo)
7912 .addImm(AMDGPU::sub0)
7913 .addReg(NewVAddrHi)
7914 .addImm(AMDGPU::sub1);
7915
7916 VAddr->setReg(NewVAddr);
7917 Rsrc->setReg(NewSRsrc);
7918 } else if (!VAddr && ST.hasAddr64()) {
7919 // This instructions is the _OFFSET variant, so we need to convert it to
7920 // ADDR64.
7921 assert(ST.getGeneration() < AMDGPUSubtarget::VOLCANIC_ISLANDS &&
7922 "FIXME: Need to emit flat atomics here");
7923
7924 unsigned RsrcPtr, NewSRsrc;
7925 std::tie(RsrcPtr, NewSRsrc) = extractRsrcPtr(*this, MI, *Rsrc);
7926
7927 Register NewVAddr = MRI.createVirtualRegister(&AMDGPU::VReg_64RegClass);
7928 MachineOperand *VData = getNamedOperand(MI, AMDGPU::OpName::vdata);
7929 MachineOperand *Offset = getNamedOperand(MI, AMDGPU::OpName::offset);
7930 MachineOperand *SOffset = getNamedOperand(MI, AMDGPU::OpName::soffset);
7931 unsigned Addr64Opcode = AMDGPU::getAddr64Inst(MI.getOpcode());
7932
7933 // Atomics with return have an additional tied operand and are
7934 // missing some of the special bits.
7935 MachineOperand *VDataIn = getNamedOperand(MI, AMDGPU::OpName::vdata_in);
7936 MachineInstr *Addr64;
7937
7938 if (!VDataIn) {
7939 // Regular buffer load / store.
7941 BuildMI(MBB, MI, MI.getDebugLoc(), get(Addr64Opcode))
7942 .add(*VData)
7943 .addReg(NewVAddr)
7944 .addReg(NewSRsrc)
7945 .add(*SOffset)
7946 .add(*Offset);
7947
7948 if (const MachineOperand *CPol =
7949 getNamedOperand(MI, AMDGPU::OpName::cpol)) {
7950 MIB.addImm(CPol->getImm());
7951 }
7952
7953 if (const MachineOperand *TFE =
7954 getNamedOperand(MI, AMDGPU::OpName::tfe)) {
7955 MIB.addImm(TFE->getImm());
7956 }
7957
7958 MIB.addImm(getNamedImmOperand(MI, AMDGPU::OpName::swz));
7959
7960 MIB.cloneMemRefs(MI);
7961 Addr64 = MIB;
7962 } else {
7963 // Atomics with return.
7964 Addr64 = BuildMI(MBB, MI, MI.getDebugLoc(), get(Addr64Opcode))
7965 .add(*VData)
7966 .add(*VDataIn)
7967 .addReg(NewVAddr)
7968 .addReg(NewSRsrc)
7969 .add(*SOffset)
7970 .add(*Offset)
7971 .addImm(getNamedImmOperand(MI, AMDGPU::OpName::cpol))
7972 .cloneMemRefs(MI);
7973 }
7974
7975 MI.removeFromParent();
7976
7977 // NewVaddr = {NewVaddrHi, NewVaddrLo}
7978 BuildMI(MBB, Addr64, Addr64->getDebugLoc(), get(AMDGPU::REG_SEQUENCE),
7979 NewVAddr)
7980 .addReg(RsrcPtr, {}, AMDGPU::sub0)
7981 .addImm(AMDGPU::sub0)
7982 .addReg(RsrcPtr, {}, AMDGPU::sub1)
7983 .addImm(AMDGPU::sub1);
7984 } else {
7985 // Legalize a VGPR Rsrc and soffset together.
7986 if (!isSoffsetLegal) {
7987 MachineOperand *Soffset = getNamedOperand(MI, AMDGPU::OpName::soffset);
7988 CreatedBB = generateWaterFallLoop(*this, MI, {Rsrc, Soffset}, MDT);
7989 return CreatedBB;
7990 }
7991 CreatedBB = generateWaterFallLoop(*this, MI, {Rsrc}, MDT);
7992 return CreatedBB;
7993 }
7994 }
7995
7996 // Legalize a VGPR soffset.
7997 if (!isSoffsetLegal) {
7998 MachineOperand *Soffset = getNamedOperand(MI, AMDGPU::OpName::soffset);
7999 CreatedBB = generateWaterFallLoop(*this, MI, {Soffset}, MDT);
8000 return CreatedBB;
8001 }
8002 return CreatedBB;
8003}
8004
8006 if (InSet.insert(MI).second)
8007 InstrList.push_back(MI);
8008 // Add MBUF instructiosn to deferred list.
8009 int RsrcIdx =
8010 AMDGPU::getNamedOperandIdx(MI->getOpcode(), AMDGPU::OpName::srsrc);
8011 if (RsrcIdx != -1) {
8012 DeferredList.insert(MI);
8013 }
8014}
8015
8017 return DeferredList.contains(MI);
8018}
8019
8020// Legalize size mismatches between 16bit and 32bit registers in v2s copy
8021// lowering (change sgpr to vgpr).
8022// This is mainly caused by 16bit SALU and 16bit VALU using reg with different
8023// size. Need to legalize the size of the operands during the vgpr lowering
8024// chain. This can be removed after we have sgpr16 in place
8026 MachineRegisterInfo &MRI) const {
8027 if (!ST.useRealTrue16Insts())
8028 return;
8029
8030 unsigned Opcode = MI.getOpcode();
8031 MachineBasicBlock *MBB = MI.getParent();
8032 // Legalize operands and check for size mismatch
8033 if (OpIdx >= MI.getNumExplicitOperands() ||
8034 OpIdx >= get(Opcode).getNumOperands() ||
8035 get(Opcode).operands()[OpIdx].RegClass == -1)
8036 return;
8037
8038 MachineOperand &Op = MI.getOperand(OpIdx);
8039 if (!Op.isReg() || !Op.getReg().isVirtual() || Op.isDef())
8040 return;
8041
8042 const TargetRegisterClass *CurrRC = MRI.getRegClass(Op.getReg());
8043 if (!RI.isVGPRClass(CurrRC))
8044 return;
8045
8046 int16_t RCID = getOpRegClassID(get(Opcode).operands()[OpIdx]);
8047 const TargetRegisterClass *ExpectedRC = RI.getRegClass(RCID);
8048 if (RI.getMatchingSuperRegClass(CurrRC, ExpectedRC, AMDGPU::lo16)) {
8049 // Default to the lo16 only if the subregister is not specified.
8050 if (Op.getSubReg() == AMDGPU::NoSubRegister)
8051 Op.setSubReg(AMDGPU::lo16);
8052 return;
8053 }
8054
8055 const TargetRegisterClass *CurrSRC =
8056 RI.getSubRegisterClass(CurrRC, Op.getSubReg());
8057 if (RI.getMatchingSuperRegClass(ExpectedRC, CurrSRC, AMDGPU::lo16)) {
8058 const DebugLoc &DL = MI.getDebugLoc();
8059 Register NewDstReg = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
8060 Register Undef = MRI.createVirtualRegister(&AMDGPU::VGPR_16RegClass);
8061 BuildMI(*MBB, MI, DL, get(AMDGPU::IMPLICIT_DEF), Undef);
8062 BuildMI(*MBB, MI, DL, get(AMDGPU::REG_SEQUENCE), NewDstReg)
8063 .addReg(Op.getReg(), {}, Op.getSubReg())
8064 .addImm(AMDGPU::lo16)
8065 .addReg(Undef)
8066 .addImm(AMDGPU::hi16);
8067 Op.setReg(NewDstReg);
8068 Op.setSubReg(AMDGPU::NoSubRegister);
8069 }
8070}
8072 MachineRegisterInfo &MRI) const {
8073 for (unsigned OpIdx = 0; OpIdx < MI.getNumExplicitOperands(); OpIdx++)
8074 legalizeOperandsVALUt16(MI, OpIdx, MRI);
8075}
8076
8080 ArrayRef<Register> PhySGPRs) const {
8081 assert(MI->getOpcode() == AMDGPU::SI_CALL_ISEL &&
8082 "This only handle waterfall for SI_CALL_ISEL");
8083 // Move everything between ADJCALLSTACKUP and ADJCALLSTACKDOWN and
8084 // following copies, we also need to move copies from and to physical
8085 // registers into the loop block.
8086 // Also move the copies to physical registers into the loop block
8087 MachineBasicBlock &MBB = *MI->getParent();
8089 while (Start->getOpcode() != AMDGPU::ADJCALLSTACKUP)
8090 --Start;
8092 while (End->getOpcode() != AMDGPU::ADJCALLSTACKDOWN)
8093 ++End;
8094
8095 // Also include following copies of the return value
8096 ++End;
8097 while (End != MBB.end() && End->isCopy() &&
8098 MI->definesRegister(End->getOperand(1).getReg(), &RI))
8099 ++End;
8100
8101 generateWaterFallLoop(*this, *MI, ScalarOps, MDT, Start, End, PhySGPRs);
8102}
8103
8105 MachineDominatorTree *MDT) const {
8107 DenseMap<MachineInstr *, bool> V2SPhyCopiesToErase;
8108 while (!Worklist.empty()) {
8109 MachineInstr &Inst = *Worklist.top();
8110 Worklist.erase_top();
8111 // Skip MachineInstr in the deferred list.
8112 if (Worklist.isDeferred(&Inst))
8113 continue;
8114 moveToVALUImpl(Worklist, MDT, Inst, WaterFalls, V2SPhyCopiesToErase);
8115 }
8116
8117 // Deferred list of instructions will be processed once
8118 // all the MachineInstr in the worklist are done.
8119 for (MachineInstr *Inst : Worklist.getDeferredList()) {
8120 moveToVALUImpl(Worklist, MDT, *Inst, WaterFalls, V2SPhyCopiesToErase);
8121 assert(Worklist.empty() &&
8122 "Deferred MachineInstr are not supposed to re-populate worklist");
8123 }
8124
8125 for (std::pair<MachineInstr *, V2PhysSCopyInfo> &Entry : WaterFalls) {
8126 if (Entry.first->getOpcode() == AMDGPU::SI_CALL_ISEL)
8127 createWaterFallForSiCall(Entry.first, MDT, Entry.second.MOs,
8128 Entry.second.SGPRs);
8129 }
8130
8131 for (std::pair<MachineInstr *, bool> Entry : V2SPhyCopiesToErase)
8132 if (Entry.second)
8133 Entry.first->eraseFromParent();
8134}
8136 MachineRegisterInfo &MRI, Register DstReg, MachineInstr &Inst) const {
8137 // If it's a copy of a VGPR to a physical SGPR, insert a V_READFIRSTLANE and
8138 // hope for the best.
8139 const TargetRegisterClass *DstRC = RI.getRegClassForReg(MRI, DstReg);
8140 ArrayRef<int16_t> SubRegIndices = RI.getRegSplitParts(DstRC, 4);
8141 if (SubRegIndices.size() <= 1) {
8142 Register NewDst = MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
8143 BuildMI(*Inst.getParent(), &Inst, Inst.getDebugLoc(),
8144 get(AMDGPU::V_READFIRSTLANE_B32), NewDst)
8145 .add(Inst.getOperand(1));
8146 BuildMI(*Inst.getParent(), &Inst, Inst.getDebugLoc(), get(AMDGPU::COPY),
8147 DstReg)
8148 .addReg(NewDst);
8149 } else {
8151 for (int16_t Indice : SubRegIndices) {
8152 Register NewDst = MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
8153 BuildMI(*Inst.getParent(), &Inst, Inst.getDebugLoc(),
8154 get(AMDGPU::V_READFIRSTLANE_B32), NewDst)
8155 .addReg(Inst.getOperand(1).getReg(), {}, Indice);
8156
8157 DstRegs.push_back(NewDst);
8158 }
8160 BuildMI(*Inst.getParent(), &Inst, Inst.getDebugLoc(),
8161 get(AMDGPU::REG_SEQUENCE), DstReg);
8162 for (unsigned i = 0; i < SubRegIndices.size(); ++i) {
8163 MIB.addReg(DstRegs[i]);
8164 MIB.addImm(RI.getSubRegFromChannel(i));
8165 }
8166 }
8167}
8168
8170 SIInstrWorklist &Worklist, Register DstReg, MachineInstr &Inst,
8173 DenseMap<MachineInstr *, bool> &V2SPhyCopiesToErase) const {
8174 if (DstReg == AMDGPU::M0) {
8175 createReadFirstLaneFromCopyToPhysReg(MRI, DstReg, Inst);
8176 V2SPhyCopiesToErase.try_emplace(&Inst, true);
8177 return;
8178 }
8179 Register SrcReg = Inst.getOperand(1).getReg();
8182 // Only search current block since phyreg's def & use cannot cross
8183 // blocks when MF.NoPhi = false.
8184 while (++I != E) {
8185 // For SI_CALL_ISEL users, replace the phys SGPR with the VGPR source
8186 // and record the operand for later waterfall loop generation.
8187 if (I->getOpcode() == AMDGPU::SI_CALL_ISEL) {
8188 MachineInstr *UseMI = &*I;
8189 for (unsigned i = 0; i < UseMI->getNumOperands(); ++i) {
8190 if (UseMI->getOperand(i).isReg() &&
8191 UseMI->getOperand(i).getReg() == DstReg) {
8192 MachineOperand *MO = &UseMI->getOperand(i);
8193 MO->setReg(SrcReg);
8194 V2PhysSCopyInfo &V2SCopyInfo = WaterFalls[UseMI];
8195 V2SCopyInfo.MOs.push_back(MO);
8196 V2SCopyInfo.SGPRs.push_back(DstReg);
8197 V2SPhyCopiesToErase.try_emplace(&Inst, true);
8198 }
8199 }
8200 } else if (I->getOpcode() == AMDGPU::SI_RETURN_TO_EPILOG &&
8201 I->getOperand(0).isReg() &&
8202 I->getOperand(0).getReg() == DstReg) {
8203 createReadFirstLaneFromCopyToPhysReg(MRI, DstReg, Inst);
8204 V2SPhyCopiesToErase.try_emplace(&Inst, true);
8205 } else if (I->readsRegister(DstReg, &RI)) {
8206 // COPY cannot be erased if other type of inst uses it.
8207 V2SPhyCopiesToErase[&Inst] = false;
8208 }
8209 if (I->findRegisterDefOperand(DstReg, &RI))
8210 break;
8211 }
8212}
8213
8215 SIInstrWorklist &Worklist, MachineDominatorTree *MDT, MachineInstr &Inst,
8217 DenseMap<MachineInstr *, bool> &V2SPhyCopiesToErase) const {
8218
8220 if (!MBB)
8221 return;
8222 MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
8223 unsigned Opcode = Inst.getOpcode();
8224 unsigned NewOpcode = getVALUOp(Inst);
8225 const DebugLoc &DL = Inst.getDebugLoc();
8226
8227 // Handle some special cases
8228 switch (Opcode) {
8229 default:
8230 break;
8231 case AMDGPU::S_ADD_I32:
8232 case AMDGPU::S_SUB_I32: {
8233 // FIXME: The u32 versions currently selected use the carry.
8234 bool Changed;
8235 MachineBasicBlock *CreatedBBTmp = nullptr;
8236 std::tie(Changed, CreatedBBTmp) = moveScalarAddSub(Worklist, Inst, MDT);
8237 if (Changed)
8238 return;
8239
8240 // Default handling
8241 break;
8242 }
8243
8244 case AMDGPU::S_MUL_U64:
8245 if (ST.hasVMulU64Inst()) {
8246 NewOpcode = AMDGPU::V_MUL_U64_e64;
8247 break;
8248 }
8249 // Split s_mul_u64 in 32-bit vector multiplications.
8250 splitScalarSMulU64(Worklist, Inst, MDT);
8251 Inst.eraseFromParent();
8252 return;
8253
8254 case AMDGPU::S_MUL_U64_U32_PSEUDO:
8255 case AMDGPU::S_MUL_I64_I32_PSEUDO:
8256 // This is a special case of s_mul_u64 where all the operands are either
8257 // zero extended or sign extended.
8258 splitScalarSMulPseudo(Worklist, Inst, MDT);
8259 Inst.eraseFromParent();
8260 return;
8261
8262 case AMDGPU::S_AND_B64:
8263 splitScalar64BitBinaryOp(Worklist, Inst, AMDGPU::S_AND_B32, MDT);
8264 Inst.eraseFromParent();
8265 return;
8266
8267 case AMDGPU::S_OR_B64:
8268 splitScalar64BitBinaryOp(Worklist, Inst, AMDGPU::S_OR_B32, MDT);
8269 Inst.eraseFromParent();
8270 return;
8271
8272 case AMDGPU::S_XOR_B64:
8273 splitScalar64BitBinaryOp(Worklist, Inst, AMDGPU::S_XOR_B32, MDT);
8274 Inst.eraseFromParent();
8275 return;
8276
8277 case AMDGPU::S_NAND_B64:
8278 splitScalar64BitBinaryOp(Worklist, Inst, AMDGPU::S_NAND_B32, MDT);
8279 Inst.eraseFromParent();
8280 return;
8281
8282 case AMDGPU::S_NOR_B64:
8283 splitScalar64BitBinaryOp(Worklist, Inst, AMDGPU::S_NOR_B32, MDT);
8284 Inst.eraseFromParent();
8285 return;
8286
8287 case AMDGPU::S_XNOR_B64:
8288 if (ST.hasDLInsts())
8289 splitScalar64BitBinaryOp(Worklist, Inst, AMDGPU::S_XNOR_B32, MDT);
8290 else
8291 splitScalar64BitXnor(Worklist, Inst, MDT);
8292 Inst.eraseFromParent();
8293 return;
8294
8295 case AMDGPU::S_ANDN2_B64:
8296 splitScalar64BitBinaryOp(Worklist, Inst, AMDGPU::S_ANDN2_B32, MDT);
8297 Inst.eraseFromParent();
8298 return;
8299
8300 case AMDGPU::S_ORN2_B64:
8301 splitScalar64BitBinaryOp(Worklist, Inst, AMDGPU::S_ORN2_B32, MDT);
8302 Inst.eraseFromParent();
8303 return;
8304
8305 case AMDGPU::S_BREV_B64:
8306 splitScalar64BitUnaryOp(Worklist, Inst, AMDGPU::S_BREV_B32, true);
8307 Inst.eraseFromParent();
8308 return;
8309
8310 case AMDGPU::S_NOT_B64:
8311 splitScalar64BitUnaryOp(Worklist, Inst, AMDGPU::S_NOT_B32);
8312 Inst.eraseFromParent();
8313 return;
8314
8315 case AMDGPU::S_BCNT1_I32_B64:
8316 splitScalar64BitBCNT(Worklist, Inst);
8317 Inst.eraseFromParent();
8318 return;
8319
8320 case AMDGPU::S_BFE_I64:
8321 splitScalar64BitBFE(Worklist, Inst);
8322 Inst.eraseFromParent();
8323 return;
8324
8325 case AMDGPU::S_FLBIT_I32_B64:
8326 splitScalar64BitCountOp(Worklist, Inst, AMDGPU::V_FFBH_U32_e32);
8327 Inst.eraseFromParent();
8328 return;
8329 case AMDGPU::S_FF1_I32_B64:
8330 splitScalar64BitCountOp(Worklist, Inst, AMDGPU::V_FFBL_B32_e32);
8331 Inst.eraseFromParent();
8332 return;
8333
8334 case AMDGPU::S_LSHL_B32:
8335 if (ST.hasOnlyRevVALUShifts()) {
8336 NewOpcode = AMDGPU::V_LSHLREV_B32_e64;
8337 swapOperands(Inst);
8338 }
8339 break;
8340 case AMDGPU::S_ASHR_I32:
8341 if (ST.hasOnlyRevVALUShifts()) {
8342 NewOpcode = AMDGPU::V_ASHRREV_I32_e64;
8343 swapOperands(Inst);
8344 }
8345 break;
8346 case AMDGPU::S_LSHR_B32:
8347 if (ST.hasOnlyRevVALUShifts()) {
8348 NewOpcode = AMDGPU::V_LSHRREV_B32_e64;
8349 swapOperands(Inst);
8350 }
8351 break;
8352 case AMDGPU::S_LSHL_B64:
8353 if (ST.hasOnlyRevVALUShifts()) {
8354 NewOpcode = ST.getGeneration() >= AMDGPUSubtarget::GFX12
8355 ? AMDGPU::V_LSHLREV_B64_pseudo_e64
8356 : AMDGPU::V_LSHLREV_B64_e64;
8357 swapOperands(Inst);
8358 }
8359 break;
8360 case AMDGPU::S_ASHR_I64:
8361 if (ST.hasOnlyRevVALUShifts()) {
8362 NewOpcode = AMDGPU::V_ASHRREV_I64_e64;
8363 swapOperands(Inst);
8364 }
8365 break;
8366 case AMDGPU::S_LSHR_B64:
8367 if (ST.hasOnlyRevVALUShifts()) {
8368 NewOpcode = AMDGPU::V_LSHRREV_B64_e64;
8369 swapOperands(Inst);
8370 }
8371 break;
8372
8373 case AMDGPU::S_ABS_I32:
8374 lowerScalarAbs(Worklist, Inst);
8375 Inst.eraseFromParent();
8376 return;
8377
8378 case AMDGPU::S_ABSDIFF_I32:
8379 lowerScalarAbsDiff(Worklist, Inst);
8380 Inst.eraseFromParent();
8381 return;
8382
8383 case AMDGPU::S_CBRANCH_SCC0:
8384 case AMDGPU::S_CBRANCH_SCC1: {
8385 // Clear unused bits of vcc
8386 Register CondReg = Inst.getOperand(1).getReg();
8387 bool IsSCC = CondReg == AMDGPU::SCC;
8389 BuildMI(*MBB, Inst, Inst.getDebugLoc(), get(LMC.AndOpc), LMC.VccReg)
8390 .addReg(LMC.ExecReg)
8391 .addReg(IsSCC ? LMC.VccReg : CondReg);
8392 Inst.removeOperand(1);
8393 } break;
8394
8395 case AMDGPU::S_BFE_U64:
8396 case AMDGPU::S_BFM_B64:
8397 llvm_unreachable("Moving this op to VALU not implemented");
8398
8399 case AMDGPU::S_PACK_LL_B32_B16:
8400 case AMDGPU::S_PACK_LH_B32_B16:
8401 case AMDGPU::S_PACK_HL_B32_B16:
8402 case AMDGPU::S_PACK_HH_B32_B16:
8403 movePackToVALU(Worklist, MRI, Inst);
8404 Inst.eraseFromParent();
8405 return;
8406
8407 case AMDGPU::S_XNOR_B32:
8408 lowerScalarXnor(Worklist, Inst);
8409 Inst.eraseFromParent();
8410 return;
8411
8412 case AMDGPU::S_NAND_B32:
8413 splitScalarNotBinop(Worklist, Inst, AMDGPU::S_AND_B32);
8414 Inst.eraseFromParent();
8415 return;
8416
8417 case AMDGPU::S_NOR_B32:
8418 splitScalarNotBinop(Worklist, Inst, AMDGPU::S_OR_B32);
8419 Inst.eraseFromParent();
8420 return;
8421
8422 case AMDGPU::S_ANDN2_B32:
8423 splitScalarBinOpN2(Worklist, Inst, AMDGPU::S_AND_B32);
8424 Inst.eraseFromParent();
8425 return;
8426
8427 case AMDGPU::S_ORN2_B32:
8428 splitScalarBinOpN2(Worklist, Inst, AMDGPU::S_OR_B32);
8429 Inst.eraseFromParent();
8430 return;
8431
8432 // TODO: remove as soon as everything is ready
8433 // to replace VGPR to SGPR copy with V_READFIRSTLANEs.
8434 // S_ADD/SUB_CO_PSEUDO as well as S_UADDO/USUBO_PSEUDO
8435 // can only be selected from the uniform SDNode.
8436 case AMDGPU::S_ADD_CO_PSEUDO:
8437 case AMDGPU::S_SUB_CO_PSEUDO: {
8438 unsigned Opc = (Inst.getOpcode() == AMDGPU::S_ADD_CO_PSEUDO)
8439 ? AMDGPU::V_ADDC_U32_e64
8440 : AMDGPU::V_SUBB_U32_e64;
8441 const auto *CarryRC = RI.getWaveMaskRegClass();
8442
8443 Register CarryInReg = Inst.getOperand(4).getReg();
8444 if (!MRI.constrainRegClass(CarryInReg, CarryRC)) {
8445 Register NewCarryReg = MRI.createVirtualRegister(CarryRC);
8446 BuildMI(*MBB, Inst, Inst.getDebugLoc(), get(AMDGPU::COPY), NewCarryReg)
8447 .addReg(CarryInReg);
8448 }
8449
8450 Register CarryOutReg = Inst.getOperand(1).getReg();
8451
8452 Register DestReg = MRI.createVirtualRegister(RI.getEquivalentVGPRClass(
8453 MRI.getRegClass(Inst.getOperand(0).getReg())));
8454 MachineInstr *CarryOp =
8455 BuildMI(*MBB, &Inst, Inst.getDebugLoc(), get(Opc), DestReg)
8456 .addReg(CarryOutReg, RegState::Define)
8457 .add(Inst.getOperand(2))
8458 .add(Inst.getOperand(3))
8459 .addReg(CarryInReg)
8460 .addImm(0);
8461 legalizeOperands(*CarryOp);
8462 MRI.replaceRegWith(Inst.getOperand(0).getReg(), DestReg);
8463 addUsersToMoveToVALUWorklist(DestReg, MRI, Worklist);
8464 Inst.eraseFromParent();
8465 }
8466 return;
8467 case AMDGPU::S_UADDO_PSEUDO:
8468 case AMDGPU::S_USUBO_PSEUDO: {
8469 MachineOperand &Dest0 = Inst.getOperand(0);
8470 MachineOperand &Dest1 = Inst.getOperand(1);
8471 MachineOperand &Src0 = Inst.getOperand(2);
8472 MachineOperand &Src1 = Inst.getOperand(3);
8473
8474 unsigned Opc = (Inst.getOpcode() == AMDGPU::S_UADDO_PSEUDO)
8475 ? AMDGPU::V_ADD_CO_U32_e64
8476 : AMDGPU::V_SUB_CO_U32_e64;
8477 const TargetRegisterClass *NewRC =
8478 RI.getEquivalentVGPRClass(MRI.getRegClass(Dest0.getReg()));
8479 Register DestReg = MRI.createVirtualRegister(NewRC);
8480 MachineInstr *NewInstr = BuildMI(*MBB, &Inst, DL, get(Opc), DestReg)
8481 .addReg(Dest1.getReg(), RegState::Define)
8482 .add(Src0)
8483 .add(Src1)
8484 .addImm(0); // clamp bit
8485
8486 legalizeOperands(*NewInstr, MDT);
8487 MRI.replaceRegWith(Dest0.getReg(), DestReg);
8488 addUsersToMoveToVALUWorklist(DestReg, MRI, Worklist);
8489 Inst.eraseFromParent();
8490 }
8491 return;
8492 case AMDGPU::S_LSHL1_ADD_U32:
8493 case AMDGPU::S_LSHL2_ADD_U32:
8494 case AMDGPU::S_LSHL3_ADD_U32:
8495 case AMDGPU::S_LSHL4_ADD_U32: {
8496 MachineOperand &Dest = Inst.getOperand(0);
8497 MachineOperand &Src0 = Inst.getOperand(1);
8498 MachineOperand &Src1 = Inst.getOperand(2);
8499 unsigned ShiftAmt = (Opcode == AMDGPU::S_LSHL1_ADD_U32 ? 1
8500 : Opcode == AMDGPU::S_LSHL2_ADD_U32 ? 2
8501 : Opcode == AMDGPU::S_LSHL3_ADD_U32 ? 3
8502 : 4);
8503
8504 const TargetRegisterClass *NewRC =
8505 RI.getEquivalentVGPRClass(MRI.getRegClass(Dest.getReg()));
8506 Register DestReg = MRI.createVirtualRegister(NewRC);
8507 MachineInstr *NewInstr =
8508 BuildMI(*MBB, &Inst, DL, get(AMDGPU::V_LSHL_ADD_U32_e64), DestReg)
8509 .add(Src0)
8510 .addImm(ShiftAmt)
8511 .add(Src1);
8512
8513 legalizeOperands(*NewInstr, MDT);
8514 MRI.replaceRegWith(Dest.getReg(), DestReg);
8515 addUsersToMoveToVALUWorklist(DestReg, MRI, Worklist);
8516 Inst.eraseFromParent();
8517 }
8518 return;
8519 case AMDGPU::S_CSELECT_B32:
8520 case AMDGPU::S_CSELECT_B64:
8521 lowerSelect(Worklist, Inst, MDT);
8522 Inst.eraseFromParent();
8523 return;
8524 case AMDGPU::S_CMP_EQ_I32:
8525 case AMDGPU::S_CMP_LG_I32:
8526 case AMDGPU::S_CMP_GT_I32:
8527 case AMDGPU::S_CMP_GE_I32:
8528 case AMDGPU::S_CMP_LT_I32:
8529 case AMDGPU::S_CMP_LE_I32:
8530 case AMDGPU::S_CMP_EQ_U32:
8531 case AMDGPU::S_CMP_LG_U32:
8532 case AMDGPU::S_CMP_GT_U32:
8533 case AMDGPU::S_CMP_GE_U32:
8534 case AMDGPU::S_CMP_LT_U32:
8535 case AMDGPU::S_CMP_LE_U32:
8536 case AMDGPU::S_CMP_EQ_U64:
8537 case AMDGPU::S_CMP_LG_U64:
8538 case AMDGPU::S_CMP_LT_F32:
8539 case AMDGPU::S_CMP_EQ_F32:
8540 case AMDGPU::S_CMP_LE_F32:
8541 case AMDGPU::S_CMP_GT_F32:
8542 case AMDGPU::S_CMP_LG_F32:
8543 case AMDGPU::S_CMP_GE_F32:
8544 case AMDGPU::S_CMP_O_F32:
8545 case AMDGPU::S_CMP_U_F32:
8546 case AMDGPU::S_CMP_NGE_F32:
8547 case AMDGPU::S_CMP_NLG_F32:
8548 case AMDGPU::S_CMP_NGT_F32:
8549 case AMDGPU::S_CMP_NLE_F32:
8550 case AMDGPU::S_CMP_NEQ_F32:
8551 case AMDGPU::S_CMP_NLT_F32: {
8552 Register CondReg = MRI.createVirtualRegister(RI.getWaveMaskRegClass());
8553 auto NewInstr =
8554 BuildMI(*MBB, Inst, Inst.getDebugLoc(), get(NewOpcode), CondReg)
8555 .setMIFlags(Inst.getFlags());
8556 if (AMDGPU::getNamedOperandIdx(NewOpcode, AMDGPU::OpName::src0_modifiers) >=
8557 0) {
8558 NewInstr
8559 .addImm(0) // src0_modifiers
8560 .add(Inst.getOperand(0)) // src0
8561 .addImm(0) // src1_modifiers
8562 .add(Inst.getOperand(1)) // src1
8563 .addImm(0); // clamp
8564 } else {
8565 NewInstr.add(Inst.getOperand(0)).add(Inst.getOperand(1));
8566 }
8567 legalizeOperands(*NewInstr, MDT);
8568 int SCCIdx = Inst.findRegisterDefOperandIdx(AMDGPU::SCC, /*TRI=*/nullptr);
8569 const MachineOperand &SCCOp = Inst.getOperand(SCCIdx);
8570 addSCCDefUsersToVALUWorklist(SCCOp, Inst, Worklist, CondReg);
8571 Inst.eraseFromParent();
8572 return;
8573 }
8574 case AMDGPU::S_CMP_LT_F16:
8575 case AMDGPU::S_CMP_EQ_F16:
8576 case AMDGPU::S_CMP_LE_F16:
8577 case AMDGPU::S_CMP_GT_F16:
8578 case AMDGPU::S_CMP_LG_F16:
8579 case AMDGPU::S_CMP_GE_F16:
8580 case AMDGPU::S_CMP_O_F16:
8581 case AMDGPU::S_CMP_U_F16:
8582 case AMDGPU::S_CMP_NGE_F16:
8583 case AMDGPU::S_CMP_NLG_F16:
8584 case AMDGPU::S_CMP_NGT_F16:
8585 case AMDGPU::S_CMP_NLE_F16:
8586 case AMDGPU::S_CMP_NEQ_F16:
8587 case AMDGPU::S_CMP_NLT_F16: {
8588 Register CondReg = MRI.createVirtualRegister(RI.getWaveMaskRegClass());
8589 auto NewInstr =
8590 BuildMI(*MBB, Inst, Inst.getDebugLoc(), get(NewOpcode), CondReg)
8591 .setMIFlags(Inst.getFlags());
8592 if (AMDGPU::hasNamedOperand(NewOpcode, AMDGPU::OpName::src0_modifiers)) {
8593 NewInstr
8594 .addImm(0) // src0_modifiers
8595 .add(Inst.getOperand(0)) // src0
8596 .addImm(0) // src1_modifiers
8597 .add(Inst.getOperand(1)) // src1
8598 .addImm(0); // clamp
8599 if (AMDGPU::hasNamedOperand(NewOpcode, AMDGPU::OpName::op_sel))
8600 NewInstr.addImm(0); // op_sel0
8601 } else {
8602 NewInstr
8603 .add(Inst.getOperand(0))
8604 .add(Inst.getOperand(1));
8605 }
8606 legalizeOperands(*NewInstr, MDT);
8607 int SCCIdx = Inst.findRegisterDefOperandIdx(AMDGPU::SCC, /*TRI=*/nullptr);
8608 const MachineOperand &SCCOp = Inst.getOperand(SCCIdx);
8609 addSCCDefUsersToVALUWorklist(SCCOp, Inst, Worklist, CondReg);
8610 Inst.eraseFromParent();
8611 return;
8612 }
8613 case AMDGPU::S_CVT_HI_F32_F16: {
8614 Register TmpReg = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
8615 Register NewDst = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
8616 if (ST.useRealTrue16Insts()) {
8617 BuildMI(*MBB, Inst, DL, get(AMDGPU::COPY), TmpReg)
8618 .add(Inst.getOperand(1));
8619 BuildMI(*MBB, Inst, DL, get(NewOpcode), NewDst)
8620 .addImm(0) // src0_modifiers
8621 .addReg(TmpReg, {}, AMDGPU::hi16)
8622 .addImm(0) // clamp
8623 .addImm(0) // omod
8624 .addImm(0); // op_sel0
8625 } else {
8626 BuildMI(*MBB, Inst, DL, get(AMDGPU::V_LSHRREV_B32_e64), TmpReg)
8627 .addImm(16)
8628 .add(Inst.getOperand(1));
8629 BuildMI(*MBB, Inst, DL, get(NewOpcode), NewDst)
8630 .addImm(0) // src0_modifiers
8631 .addReg(TmpReg)
8632 .addImm(0) // clamp
8633 .addImm(0); // omod
8634 }
8635
8636 MRI.replaceRegWith(Inst.getOperand(0).getReg(), NewDst);
8637 addUsersToMoveToVALUWorklist(NewDst, MRI, Worklist);
8638 Inst.eraseFromParent();
8639 return;
8640 }
8641 case AMDGPU::S_MINIMUM_F32:
8642 case AMDGPU::S_MAXIMUM_F32: {
8643 Register NewDst = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
8644 MachineInstr *NewInstr = BuildMI(*MBB, Inst, DL, get(NewOpcode), NewDst)
8645 .addImm(0) // src0_modifiers
8646 .add(Inst.getOperand(1))
8647 .addImm(0) // src1_modifiers
8648 .add(Inst.getOperand(2))
8649 .addImm(0) // clamp
8650 .addImm(0); // omod
8651 MRI.replaceRegWith(Inst.getOperand(0).getReg(), NewDst);
8652
8653 legalizeOperands(*NewInstr, MDT);
8654 addUsersToMoveToVALUWorklist(NewDst, MRI, Worklist);
8655 Inst.eraseFromParent();
8656 return;
8657 }
8658 case AMDGPU::S_MINIMUM_F16:
8659 case AMDGPU::S_MAXIMUM_F16: {
8660 Register NewDst = MRI.createVirtualRegister(ST.useRealTrue16Insts()
8661 ? &AMDGPU::VGPR_16RegClass
8662 : &AMDGPU::VGPR_32RegClass);
8663 MachineInstr *NewInstr = BuildMI(*MBB, Inst, DL, get(NewOpcode), NewDst)
8664 .addImm(0) // src0_modifiers
8665 .add(Inst.getOperand(1))
8666 .addImm(0) // src1_modifiers
8667 .add(Inst.getOperand(2))
8668 .addImm(0) // clamp
8669 .addImm(0) // omod
8670 .addImm(0); // opsel0
8671 MRI.replaceRegWith(Inst.getOperand(0).getReg(), NewDst);
8672 legalizeOperands(*NewInstr, MDT);
8673 addUsersToMoveToVALUWorklist(NewDst, MRI, Worklist);
8674 Inst.eraseFromParent();
8675 return;
8676 }
8677 case AMDGPU::V_S_EXP_F16_e64:
8678 case AMDGPU::V_S_LOG_F16_e64:
8679 case AMDGPU::V_S_RCP_F16_e64:
8680 case AMDGPU::V_S_RSQ_F16_e64:
8681 case AMDGPU::V_S_SQRT_F16_e64: {
8682 Register NewDst = MRI.createVirtualRegister(ST.useRealTrue16Insts()
8683 ? &AMDGPU::VGPR_16RegClass
8684 : &AMDGPU::VGPR_32RegClass);
8685 auto NewInstr = BuildMI(*MBB, Inst, DL, get(NewOpcode), NewDst)
8686 .add(Inst.getOperand(1)) // src0_modifiers
8687 .add(Inst.getOperand(2))
8688 .add(Inst.getOperand(3)) // clamp
8689 .add(Inst.getOperand(4)) // omod
8690 .setMIFlags(Inst.getFlags());
8691 if (AMDGPU::hasNamedOperand(NewOpcode, AMDGPU::OpName::op_sel))
8692 NewInstr.addImm(0); // opsel0
8693 MRI.replaceRegWith(Inst.getOperand(0).getReg(), NewDst);
8694 legalizeOperands(*NewInstr, MDT);
8695 addUsersToMoveToVALUWorklist(NewDst, MRI, Worklist);
8696 Inst.eraseFromParent();
8697 return;
8698 }
8699 }
8700
8701 if (NewOpcode == AMDGPU::INSTRUCTION_LIST_END) {
8702 // We cannot move this instruction to the VALU, so we should try to
8703 // legalize its operands instead.
8704 legalizeOperands(Inst, MDT);
8705 return;
8706 }
8707 // Handle converting generic instructions like COPY-to-SGPR into
8708 // COPY-to-VGPR.
8709 if (NewOpcode == Opcode) {
8710 Register DstReg = Inst.getOperand(0).getReg();
8711 const TargetRegisterClass *NewDstRC = getDestEquivalentVGPRClass(Inst);
8712
8713 if (Inst.isCopy() && DstReg.isPhysical() &&
8714 Inst.getOperand(1).getReg().isVirtual()) {
8715 handleCopyToPhysHelper(Worklist, DstReg, Inst, MRI, WaterFalls,
8716 V2SPhyCopiesToErase);
8717 return;
8718 }
8719
8720 if (Inst.isCopy() && Inst.getOperand(1).getReg().isVirtual()) {
8721 Register NewDstReg = Inst.getOperand(1).getReg();
8722 const TargetRegisterClass *SrcRC = RI.getRegClassForReg(MRI, NewDstReg);
8723 if (const TargetRegisterClass *CommonRC =
8724 RI.getCommonSubClass(NewDstRC, SrcRC)) {
8725 // Instead of creating a copy where src and dst are the same register
8726 // class, we just replace all uses of dst with src. These kinds of
8727 // copies interfere with the heuristics MachineSink uses to decide
8728 // whether or not to split a critical edge. Since the pass assumes
8729 // that copies will end up as machine instructions and not be
8730 // eliminated.
8731 addUsersToMoveToVALUWorklist(DstReg, MRI, Worklist);
8732 unsigned SrcSubReg = Inst.getOperand(1).getSubReg();
8733 bool IsUndef = Inst.getOperand(1).isUndef();
8734 for (MachineOperand &UseMO :
8735 make_early_inc_range(MRI.use_operands(DstReg))) {
8736 UseMO.setSubReg(
8737 RI.composeSubRegIndices(SrcSubReg, UseMO.getSubReg()));
8738 UseMO.setReg(NewDstReg);
8739 if (IsUndef)
8740 UseMO.setIsUndef();
8741 }
8742 MRI.clearKillFlags(NewDstReg);
8743
8744 if (!MRI.constrainRegClass(NewDstReg, CommonRC))
8745 llvm_unreachable("failed to constrain register");
8746
8747 Inst.eraseFromParent();
8748
8749 for (MachineOperand &UseMO :
8750 make_early_inc_range(MRI.use_operands(NewDstReg))) {
8751 MachineInstr &UseMI = *UseMO.getParent();
8752
8753 // Legalize t16 operands since replaceReg is called after
8754 // addUsersToVALU.
8756
8757 unsigned OpIdx = UseMI.getOperandNo(&UseMO);
8758 if (const TargetRegisterClass *OpRC =
8759 getRegClass(UseMI.getDesc(), OpIdx))
8760 MRI.constrainRegClass(NewDstReg, OpRC);
8761 }
8762
8763 return;
8764 }
8765 }
8766
8767 // If this is a v2s copy between 16bit and 32bit reg,
8768 // replace vgpr copy to reg_sequence/extract_subreg
8769 // This can be remove after we have sgpr16 in place
8770 if (ST.useRealTrue16Insts() && Inst.isCopy() &&
8771 Inst.getOperand(1).getReg().isVirtual() &&
8772 RI.isVGPR(MRI, Inst.getOperand(1).getReg())) {
8773 const TargetRegisterClass *SrcRegRC = getOpRegClass(Inst, 1);
8774 if (RI.getMatchingSuperRegClass(NewDstRC, SrcRegRC, AMDGPU::lo16)) {
8775 Register NewDstReg = MRI.createVirtualRegister(NewDstRC);
8776 Register Undef = MRI.createVirtualRegister(&AMDGPU::VGPR_16RegClass);
8777 BuildMI(*Inst.getParent(), &Inst, Inst.getDebugLoc(),
8778 get(AMDGPU::IMPLICIT_DEF), Undef);
8779 BuildMI(*Inst.getParent(), &Inst, Inst.getDebugLoc(),
8780 get(AMDGPU::REG_SEQUENCE), NewDstReg)
8781 .addReg(Inst.getOperand(1).getReg())
8782 .addImm(AMDGPU::lo16)
8783 .addReg(Undef)
8784 .addImm(AMDGPU::hi16);
8785 Inst.eraseFromParent();
8786 MRI.replaceRegWith(DstReg, NewDstReg);
8787 addUsersToMoveToVALUWorklist(NewDstReg, MRI, Worklist);
8788 return;
8789 } else if (RI.getMatchingSuperRegClass(SrcRegRC, NewDstRC,
8790 AMDGPU::lo16)) {
8791 Inst.getOperand(1).setSubReg(AMDGPU::lo16);
8792 Register NewDstReg = MRI.createVirtualRegister(NewDstRC);
8793 MRI.replaceRegWith(DstReg, NewDstReg);
8794 addUsersToMoveToVALUWorklist(NewDstReg, MRI, Worklist);
8795 return;
8796 }
8797 }
8798
8799 Register NewDstReg = MRI.createVirtualRegister(NewDstRC);
8800 MRI.replaceRegWith(DstReg, NewDstReg);
8801 legalizeOperands(Inst, MDT);
8802 addUsersToMoveToVALUWorklist(NewDstReg, MRI, Worklist);
8803 return;
8804 }
8805
8806 // Use the new VALU Opcode.
8807 auto NewInstr = BuildMI(*MBB, Inst, Inst.getDebugLoc(), get(NewOpcode))
8808 .setMIFlags(Inst.getFlags());
8809 if (isVOP3(NewOpcode) && !isVOP3(Opcode)) {
8810 // Intersperse VOP3 modifiers among the SALU operands.
8811 NewInstr->addOperand(Inst.getOperand(0));
8812 if (AMDGPU::getNamedOperandIdx(NewOpcode,
8813 AMDGPU::OpName::src0_modifiers) >= 0)
8814 NewInstr.addImm(0);
8815 if (AMDGPU::hasNamedOperand(NewOpcode, AMDGPU::OpName::src0)) {
8816 const MachineOperand &Src = Inst.getOperand(1);
8817 NewInstr->addOperand(Src);
8818 }
8819
8820 if (Opcode == AMDGPU::S_SEXT_I32_I8 || Opcode == AMDGPU::S_SEXT_I32_I16) {
8821 // We are converting these to a BFE, so we need to add the missing
8822 // operands for the size and offset.
8823 unsigned Size = (Opcode == AMDGPU::S_SEXT_I32_I8) ? 8 : 16;
8824 NewInstr.addImm(0);
8825 NewInstr.addImm(Size);
8826 } else if (Opcode == AMDGPU::S_BCNT1_I32_B32) {
8827 // The VALU version adds the second operand to the result, so insert an
8828 // extra 0 operand.
8829 NewInstr.addImm(0);
8830 } else if (Opcode == AMDGPU::S_BFE_I32 || Opcode == AMDGPU::S_BFE_U32) {
8831 const MachineOperand &OffsetWidthOp = Inst.getOperand(2);
8832 // If we need to move this to VGPRs, we need to unpack the second
8833 // operand back into the 2 separate ones for bit offset and width.
8834 assert(OffsetWidthOp.isImm() &&
8835 "Scalar BFE is only implemented for constant width and offset");
8836 uint32_t Imm = OffsetWidthOp.getImm();
8837
8838 uint32_t Offset = Imm & 0x3f; // Extract bits [5:0].
8839 uint32_t BitWidth = (Imm & 0x7f0000) >> 16; // Extract bits [22:16].
8840 NewInstr.addImm(Offset);
8841 NewInstr.addImm(BitWidth);
8842 } else {
8843 if (AMDGPU::getNamedOperandIdx(NewOpcode,
8844 AMDGPU::OpName::src1_modifiers) >= 0)
8845 NewInstr.addImm(0);
8846 if (AMDGPU::getNamedOperandIdx(NewOpcode, AMDGPU::OpName::src1) >= 0)
8847 NewInstr->addOperand(Inst.getOperand(2));
8848 if (AMDGPU::getNamedOperandIdx(NewOpcode,
8849 AMDGPU::OpName::src2_modifiers) >= 0)
8850 NewInstr.addImm(0);
8851 if (AMDGPU::getNamedOperandIdx(NewOpcode, AMDGPU::OpName::src2) >= 0)
8852 NewInstr->addOperand(Inst.getOperand(3));
8853 if (AMDGPU::getNamedOperandIdx(NewOpcode, AMDGPU::OpName::clamp) >= 0)
8854 NewInstr.addImm(0);
8855 if (AMDGPU::getNamedOperandIdx(NewOpcode, AMDGPU::OpName::omod) >= 0)
8856 NewInstr.addImm(0);
8857 if (AMDGPU::getNamedOperandIdx(NewOpcode, AMDGPU::OpName::op_sel) >= 0)
8858 NewInstr.addImm(0);
8859 }
8860 } else {
8861 // Just copy the SALU operands.
8862 for (const MachineOperand &Op : Inst.explicit_operands())
8863 NewInstr->addOperand(Op);
8864 }
8865
8866 // Remove any references to SCC. Vector instructions can't read from it, and
8867 // We're just about to add the implicit use / defs of VCC, and we don't want
8868 // both.
8869 for (MachineOperand &Op : Inst.implicit_operands()) {
8870 if (Op.getReg() == AMDGPU::SCC) {
8871 // Only propagate through live-def of SCC.
8872 if (Op.isDef() && !Op.isDead())
8873 addSCCDefUsersToVALUWorklist(Op, Inst, Worklist);
8874 if (Op.isUse())
8875 addSCCDefsToVALUWorklist(NewInstr, Worklist);
8876 }
8877 }
8878 Inst.eraseFromParent();
8879 Register NewDstReg;
8880 if (NewInstr->getOperand(0).isReg() && NewInstr->getOperand(0).isDef()) {
8881 Register DstReg = NewInstr->getOperand(0).getReg();
8882 assert(DstReg.isVirtual());
8883 // Update the destination register class.
8884 const TargetRegisterClass *NewDstRC = getDestEquivalentVGPRClass(*NewInstr);
8885 assert(NewDstRC);
8886 NewDstReg = MRI.createVirtualRegister(NewDstRC);
8887 MRI.replaceRegWith(DstReg, NewDstReg);
8888 }
8889 fixImplicitOperands(*NewInstr);
8890
8891 // Legalize the operands
8892 legalizeOperands(*NewInstr, MDT);
8893 if (NewDstReg)
8894 addUsersToMoveToVALUWorklist(NewDstReg, MRI, Worklist);
8895}
8896
8897// Add/sub require special handling to deal with carry outs.
8898std::pair<bool, MachineBasicBlock *>
8899SIInstrInfo::moveScalarAddSub(SIInstrWorklist &Worklist, MachineInstr &Inst,
8900 MachineDominatorTree *MDT) const {
8901 if (ST.hasAddNoCarryInsts()) {
8902 // Assume there is no user of scc since we don't select this in that case.
8903 // Since scc isn't used, it doesn't really matter if the i32 or u32 variant
8904 // is used.
8905
8906 MachineBasicBlock &MBB = *Inst.getParent();
8907 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
8908
8909 Register OldDstReg = Inst.getOperand(0).getReg();
8910 Register ResultReg = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
8911
8912 unsigned Opc = Inst.getOpcode();
8913 assert(Opc == AMDGPU::S_ADD_I32 || Opc == AMDGPU::S_SUB_I32);
8914
8915 unsigned NewOpc = Opc == AMDGPU::S_ADD_I32 ?
8916 AMDGPU::V_ADD_U32_e64 : AMDGPU::V_SUB_U32_e64;
8917
8918 assert(Inst.getOperand(3).getReg() == AMDGPU::SCC);
8919 Inst.removeOperand(3);
8920
8921 Inst.setDesc(get(NewOpc));
8922 Inst.addOperand(MachineOperand::CreateImm(0)); // clamp bit
8923 Inst.addImplicitDefUseOperands(*MBB.getParent());
8924 MRI.replaceRegWith(OldDstReg, ResultReg);
8925 MachineBasicBlock *NewBB = legalizeOperands(Inst, MDT);
8926
8927 addUsersToMoveToVALUWorklist(ResultReg, MRI, Worklist);
8928 return std::pair(true, NewBB);
8929 }
8930
8931 return std::pair(false, nullptr);
8932}
8933
8934void SIInstrInfo::lowerSelect(SIInstrWorklist &Worklist, MachineInstr &Inst,
8935 MachineDominatorTree *MDT) const {
8936
8937 MachineBasicBlock &MBB = *Inst.getParent();
8938 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
8939 MachineBasicBlock::iterator MII = Inst;
8940 const DebugLoc &DL = Inst.getDebugLoc();
8941
8942 MachineOperand &Dest = Inst.getOperand(0);
8943 MachineOperand &Src0 = Inst.getOperand(1);
8944 MachineOperand &Src1 = Inst.getOperand(2);
8945 MachineOperand &Cond = Inst.getOperand(3);
8946
8947 Register CondReg = Cond.getReg();
8948 bool IsSCC = (CondReg == AMDGPU::SCC);
8949
8950 // Remove S_CSELECT instructions that we previously inserted to feed the SCC
8951 // condition output from S_CMP into the SGPR condition input of V_CNDMASK. If
8952 // the S_CMP has been promoted to V_CMP then we can feed its SGPR condition
8953 // output directly into the V_CNDMASK.
8954 if (!IsSCC && Src0.isImm() && (Src0.getImm() == -1) && Src1.isImm() &&
8955 (Src1.getImm() == 0)) {
8956 for (MachineOperand &UseMO :
8958 MachineInstr &UseMI = *UseMO.getParent();
8959 switch (UseMI.getOpcode()) {
8960 case AMDGPU::V_CNDMASK_B16_fake16_e32:
8961 case AMDGPU::V_CNDMASK_B16_fake16_e64:
8962 case AMDGPU::V_CNDMASK_B16_t16_e32:
8963 case AMDGPU::V_CNDMASK_B16_t16_e64:
8964 case AMDGPU::V_CNDMASK_B32_e32:
8965 case AMDGPU::V_CNDMASK_B32_e64:
8966 case AMDGPU::V_CNDMASK_B64_PSEUDO:
8967 if (UseMO.isImplicit() ||
8968 &UseMO == getNamedOperand(UseMI, AMDGPU::OpName::src2))
8969 UseMO.setReg(CondReg);
8970 }
8971 }
8972 if (MRI.use_nodbg_empty(Dest.getReg()))
8973 return;
8974 }
8975
8976 Register NewCondReg = CondReg;
8977 if (IsSCC) {
8978 const TargetRegisterClass *TC = RI.getWaveMaskRegClass();
8979 NewCondReg = MRI.createVirtualRegister(TC);
8980
8981 // Now look for the closest SCC def if it is a copy
8982 // replacing the CondReg with the COPY source register
8983 bool CopyFound = false;
8984 for (MachineInstr &CandI :
8986 Inst.getParent()->rend())) {
8987 if (CandI.findRegisterDefOperandIdx(AMDGPU::SCC, &RI, false, false) !=
8988 -1) {
8989 if (CandI.isCopy() && CandI.getOperand(0).getReg() == AMDGPU::SCC) {
8990 BuildMI(MBB, MII, DL, get(AMDGPU::COPY), NewCondReg)
8991 .addReg(CandI.getOperand(1).getReg());
8992 CopyFound = true;
8993 }
8994 break;
8995 }
8996 }
8997 if (!CopyFound) {
8998 // SCC def is not a copy
8999 // Insert a trivial select instead of creating a copy, because a copy from
9000 // SCC would semantically mean just copying a single bit, but we may need
9001 // the result to be a vector condition mask that needs preserving.
9002 unsigned Opcode =
9003 ST.isWave64() ? AMDGPU::S_CSELECT_B64 : AMDGPU::S_CSELECT_B32;
9004 auto NewSelect =
9005 BuildMI(MBB, MII, DL, get(Opcode), NewCondReg).addImm(-1).addImm(0);
9006 NewSelect->getOperand(3).setIsUndef(Cond.isUndef());
9007 }
9008 }
9009
9010 Register NewDestReg = MRI.createVirtualRegister(
9011 RI.getEquivalentVGPRClass(MRI.getRegClass(Dest.getReg())));
9012 MachineInstr *NewInst;
9013 if (Inst.getOpcode() == AMDGPU::S_CSELECT_B32) {
9014 NewInst = BuildMI(MBB, MII, DL, get(AMDGPU::V_CNDMASK_B32_e64), NewDestReg)
9015 .addImm(0)
9016 .add(Src1) // False
9017 .addImm(0)
9018 .add(Src0) // True
9019 .addReg(NewCondReg);
9020 } else {
9021 NewInst =
9022 BuildMI(MBB, MII, DL, get(AMDGPU::V_CNDMASK_B64_PSEUDO), NewDestReg)
9023 .add(Src1) // False
9024 .add(Src0) // True
9025 .addReg(NewCondReg);
9026 }
9027 MRI.replaceRegWith(Dest.getReg(), NewDestReg);
9028 legalizeOperands(*NewInst, MDT);
9029 addUsersToMoveToVALUWorklist(NewDestReg, MRI, Worklist);
9030}
9031
9032void SIInstrInfo::lowerScalarAbs(SIInstrWorklist &Worklist,
9033 MachineInstr &Inst) const {
9034 MachineBasicBlock &MBB = *Inst.getParent();
9035 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
9036 MachineBasicBlock::iterator MII = Inst;
9037 const DebugLoc &DL = Inst.getDebugLoc();
9038
9039 MachineOperand &Dest = Inst.getOperand(0);
9040 MachineOperand &Src = Inst.getOperand(1);
9041 Register TmpReg = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
9042 Register ResultReg = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
9043
9044 unsigned SubOp = ST.hasAddNoCarryInsts() ? AMDGPU::V_SUB_U32_e32
9045 : AMDGPU::V_SUB_CO_U32_e32;
9046
9047 BuildMI(MBB, MII, DL, get(SubOp), TmpReg)
9048 .addImm(0)
9049 .addReg(Src.getReg());
9050
9051 BuildMI(MBB, MII, DL, get(AMDGPU::V_MAX_I32_e64), ResultReg)
9052 .addReg(Src.getReg())
9053 .addReg(TmpReg);
9054
9055 MRI.replaceRegWith(Dest.getReg(), ResultReg);
9056 addUsersToMoveToVALUWorklist(ResultReg, MRI, Worklist);
9057}
9058
9059void SIInstrInfo::lowerScalarAbsDiff(SIInstrWorklist &Worklist,
9060 MachineInstr &Inst) const {
9061 MachineBasicBlock &MBB = *Inst.getParent();
9062 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
9063 MachineBasicBlock::iterator MII = Inst;
9064 const DebugLoc &DL = Inst.getDebugLoc();
9065
9066 MachineOperand &Dest = Inst.getOperand(0);
9067 MachineOperand &Src1 = Inst.getOperand(1);
9068 MachineOperand &Src2 = Inst.getOperand(2);
9069 Register SubResultReg = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
9070 Register TmpReg = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
9071 Register ResultReg = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
9072
9073 unsigned SubOp = ST.hasAddNoCarryInsts() ? AMDGPU::V_SUB_U32_e32
9074 : AMDGPU::V_SUB_CO_U32_e32;
9075
9076 BuildMI(MBB, MII, DL, get(SubOp), SubResultReg)
9077 .addReg(Src1.getReg())
9078 .addReg(Src2.getReg());
9079
9080 BuildMI(MBB, MII, DL, get(SubOp), TmpReg).addImm(0).addReg(SubResultReg);
9081
9082 BuildMI(MBB, MII, DL, get(AMDGPU::V_MAX_I32_e64), ResultReg)
9083 .addReg(SubResultReg)
9084 .addReg(TmpReg);
9085
9086 MRI.replaceRegWith(Dest.getReg(), ResultReg);
9087 addUsersToMoveToVALUWorklist(ResultReg, MRI, Worklist);
9088}
9089
9090void SIInstrInfo::lowerScalarXnor(SIInstrWorklist &Worklist,
9091 MachineInstr &Inst) const {
9092 MachineBasicBlock &MBB = *Inst.getParent();
9093 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
9094 MachineBasicBlock::iterator MII = Inst;
9095 const DebugLoc &DL = Inst.getDebugLoc();
9096
9097 MachineOperand &Dest = Inst.getOperand(0);
9098 MachineOperand &Src0 = Inst.getOperand(1);
9099 MachineOperand &Src1 = Inst.getOperand(2);
9100
9101 if (ST.hasDLInsts()) {
9102 Register NewDest = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
9103 legalizeGenericOperand(MBB, MII, &AMDGPU::VGPR_32RegClass, Src0, MRI, DL);
9104 legalizeGenericOperand(MBB, MII, &AMDGPU::VGPR_32RegClass, Src1, MRI, DL);
9105
9106 BuildMI(MBB, MII, DL, get(AMDGPU::V_XNOR_B32_e64), NewDest)
9107 .add(Src0)
9108 .add(Src1);
9109
9110 MRI.replaceRegWith(Dest.getReg(), NewDest);
9111 addUsersToMoveToVALUWorklist(NewDest, MRI, Worklist);
9112 } else {
9113 // Using the identity !(x ^ y) == (!x ^ y) == (x ^ !y), we can
9114 // invert either source and then perform the XOR. If either source is a
9115 // scalar register, then we can leave the inversion on the scalar unit to
9116 // achieve a better distribution of scalar and vector instructions.
9117 bool Src0IsSGPR = Src0.isReg() &&
9118 RI.isSGPRClass(MRI.getRegClass(Src0.getReg()));
9119 bool Src1IsSGPR = Src1.isReg() &&
9120 RI.isSGPRClass(MRI.getRegClass(Src1.getReg()));
9121 MachineInstr *Xor;
9122 Register Temp = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
9123 Register NewDest = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
9124
9125 // Build a pair of scalar instructions and add them to the work list.
9126 // The next iteration over the work list will lower these to the vector
9127 // unit as necessary.
9128 if (Src0IsSGPR) {
9129 BuildMI(MBB, MII, DL, get(AMDGPU::S_NOT_B32), Temp).add(Src0);
9130 Xor = BuildMI(MBB, MII, DL, get(AMDGPU::S_XOR_B32), NewDest)
9131 .addReg(Temp)
9132 .add(Src1);
9133 } else if (Src1IsSGPR) {
9134 BuildMI(MBB, MII, DL, get(AMDGPU::S_NOT_B32), Temp).add(Src1);
9135 Xor = BuildMI(MBB, MII, DL, get(AMDGPU::S_XOR_B32), NewDest)
9136 .add(Src0)
9137 .addReg(Temp);
9138 } else {
9139 Xor = BuildMI(MBB, MII, DL, get(AMDGPU::S_XOR_B32), Temp)
9140 .add(Src0)
9141 .add(Src1);
9142 MachineInstr *Not =
9143 BuildMI(MBB, MII, DL, get(AMDGPU::S_NOT_B32), NewDest).addReg(Temp);
9144 Worklist.insert(Not);
9145 }
9146
9147 MRI.replaceRegWith(Dest.getReg(), NewDest);
9148
9149 Worklist.insert(Xor);
9150
9151 addUsersToMoveToVALUWorklist(NewDest, MRI, Worklist);
9152 }
9153}
9154
9155void SIInstrInfo::splitScalarNotBinop(SIInstrWorklist &Worklist,
9156 MachineInstr &Inst,
9157 unsigned Opcode) const {
9158 MachineBasicBlock &MBB = *Inst.getParent();
9159 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
9160 MachineBasicBlock::iterator MII = Inst;
9161 const DebugLoc &DL = Inst.getDebugLoc();
9162
9163 MachineOperand &Dest = Inst.getOperand(0);
9164 MachineOperand &Src0 = Inst.getOperand(1);
9165 MachineOperand &Src1 = Inst.getOperand(2);
9166
9167 Register NewDest = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
9168 Register Interm = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
9169
9170 MachineInstr &Op = *BuildMI(MBB, MII, DL, get(Opcode), Interm)
9171 .add(Src0)
9172 .add(Src1);
9173
9174 MachineInstr &Not = *BuildMI(MBB, MII, DL, get(AMDGPU::S_NOT_B32), NewDest)
9175 .addReg(Interm);
9176
9177 Worklist.insert(&Op);
9178 Worklist.insert(&Not);
9179
9180 MRI.replaceRegWith(Dest.getReg(), NewDest);
9181 addUsersToMoveToVALUWorklist(NewDest, MRI, Worklist);
9182}
9183
9184void SIInstrInfo::splitScalarBinOpN2(SIInstrWorklist &Worklist,
9185 MachineInstr &Inst,
9186 unsigned Opcode) const {
9187 MachineBasicBlock &MBB = *Inst.getParent();
9188 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
9189 MachineBasicBlock::iterator MII = Inst;
9190 const DebugLoc &DL = Inst.getDebugLoc();
9191
9192 MachineOperand &Dest = Inst.getOperand(0);
9193 MachineOperand &Src0 = Inst.getOperand(1);
9194 MachineOperand &Src1 = Inst.getOperand(2);
9195
9196 Register NewDest = MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
9197 Register Interm = MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass);
9198
9199 MachineInstr &Not = *BuildMI(MBB, MII, DL, get(AMDGPU::S_NOT_B32), Interm)
9200 .add(Src1);
9201
9202 MachineInstr &Op = *BuildMI(MBB, MII, DL, get(Opcode), NewDest)
9203 .add(Src0)
9204 .addReg(Interm);
9205
9206 Worklist.insert(&Not);
9207 Worklist.insert(&Op);
9208
9209 MRI.replaceRegWith(Dest.getReg(), NewDest);
9210 addUsersToMoveToVALUWorklist(NewDest, MRI, Worklist);
9211}
9212
9213void SIInstrInfo::splitScalar64BitUnaryOp(SIInstrWorklist &Worklist,
9214 MachineInstr &Inst, unsigned Opcode,
9215 bool Swap) const {
9216 MachineBasicBlock &MBB = *Inst.getParent();
9217 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
9218
9219 MachineOperand &Dest = Inst.getOperand(0);
9220 MachineOperand &Src0 = Inst.getOperand(1);
9221 const DebugLoc &DL = Inst.getDebugLoc();
9222
9223 MachineBasicBlock::iterator MII = Inst;
9224
9225 const MCInstrDesc &InstDesc = get(Opcode);
9226 const TargetRegisterClass *Src0RC = Src0.isReg() ?
9227 MRI.getRegClass(Src0.getReg()) :
9228 &AMDGPU::SGPR_32RegClass;
9229
9230 const TargetRegisterClass *Src0SubRC =
9231 RI.getSubRegisterClass(Src0RC, AMDGPU::sub0);
9232
9233 MachineOperand SrcReg0Sub0 = buildExtractSubRegOrImm(MII, MRI, Src0, Src0RC,
9234 AMDGPU::sub0, Src0SubRC);
9235
9236 const TargetRegisterClass *DestRC = MRI.getRegClass(Dest.getReg());
9237 const TargetRegisterClass *NewDestRC = RI.getEquivalentVGPRClass(DestRC);
9238 const TargetRegisterClass *NewDestSubRC =
9239 RI.getSubRegisterClass(NewDestRC, AMDGPU::sub0);
9240
9241 Register DestSub0 = MRI.createVirtualRegister(NewDestSubRC);
9242 MachineInstr &LoHalf = *BuildMI(MBB, MII, DL, InstDesc, DestSub0).add(SrcReg0Sub0);
9243
9244 MachineOperand SrcReg0Sub1 = buildExtractSubRegOrImm(MII, MRI, Src0, Src0RC,
9245 AMDGPU::sub1, Src0SubRC);
9246
9247 Register DestSub1 = MRI.createVirtualRegister(NewDestSubRC);
9248 MachineInstr &HiHalf = *BuildMI(MBB, MII, DL, InstDesc, DestSub1).add(SrcReg0Sub1);
9249
9250 if (Swap)
9251 std::swap(DestSub0, DestSub1);
9252
9253 Register FullDestReg = MRI.createVirtualRegister(NewDestRC);
9254 BuildMI(MBB, MII, DL, get(TargetOpcode::REG_SEQUENCE), FullDestReg)
9255 .addReg(DestSub0)
9256 .addImm(AMDGPU::sub0)
9257 .addReg(DestSub1)
9258 .addImm(AMDGPU::sub1);
9259
9260 MRI.replaceRegWith(Dest.getReg(), FullDestReg);
9261
9262 Worklist.insert(&LoHalf);
9263 Worklist.insert(&HiHalf);
9264
9265 // We don't need to legalizeOperands here because for a single operand, src0
9266 // will support any kind of input.
9267
9268 // Move all users of this moved value.
9269 addUsersToMoveToVALUWorklist(FullDestReg, MRI, Worklist);
9270}
9271
9272// There is not a vector equivalent of s_mul_u64. For this reason, we need to
9273// split the s_mul_u64 in 32-bit vector multiplications.
9274void SIInstrInfo::splitScalarSMulU64(SIInstrWorklist &Worklist,
9275 MachineInstr &Inst,
9276 MachineDominatorTree *MDT) const {
9277 MachineBasicBlock &MBB = *Inst.getParent();
9278 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
9279
9280 Register FullDestReg = MRI.createVirtualRegister(&AMDGPU::VReg_64RegClass);
9281 Register DestSub0 = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
9282 Register DestSub1 = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
9283
9284 MachineOperand &Dest = Inst.getOperand(0);
9285 MachineOperand &Src0 = Inst.getOperand(1);
9286 MachineOperand &Src1 = Inst.getOperand(2);
9287 const DebugLoc &DL = Inst.getDebugLoc();
9288 MachineBasicBlock::iterator MII = Inst;
9289
9290 const TargetRegisterClass *Src0RC = MRI.getRegClass(Src0.getReg());
9291 const TargetRegisterClass *Src1RC = MRI.getRegClass(Src1.getReg());
9292 const TargetRegisterClass *Src0SubRC =
9293 RI.getSubRegisterClass(Src0RC, AMDGPU::sub0);
9294 if (RI.isSGPRClass(Src0SubRC))
9295 Src0SubRC = RI.getEquivalentVGPRClass(Src0SubRC);
9296 const TargetRegisterClass *Src1SubRC =
9297 RI.getSubRegisterClass(Src1RC, AMDGPU::sub0);
9298 if (RI.isSGPRClass(Src1SubRC))
9299 Src1SubRC = RI.getEquivalentVGPRClass(Src1SubRC);
9300
9301 // First, we extract the low 32-bit and high 32-bit values from each of the
9302 // operands.
9303 MachineOperand Op0L =
9304 buildExtractSubRegOrImm(MII, MRI, Src0, Src0RC, AMDGPU::sub0, Src0SubRC);
9305 MachineOperand Op1L =
9306 buildExtractSubRegOrImm(MII, MRI, Src1, Src1RC, AMDGPU::sub0, Src1SubRC);
9307 MachineOperand Op0H =
9308 buildExtractSubRegOrImm(MII, MRI, Src0, Src0RC, AMDGPU::sub1, Src0SubRC);
9309 MachineOperand Op1H =
9310 buildExtractSubRegOrImm(MII, MRI, Src1, Src1RC, AMDGPU::sub1, Src1SubRC);
9311
9312 // The multilication is done as follows:
9313 //
9314 // Op1H Op1L
9315 // * Op0H Op0L
9316 // --------------------
9317 // Op1H*Op0L Op1L*Op0L
9318 // + Op1H*Op0H Op1L*Op0H
9319 // -----------------------------------------
9320 // (Op1H*Op0L + Op1L*Op0H + carry) Op1L*Op0L
9321 //
9322 // We drop Op1H*Op0H because the result of the multiplication is a 64-bit
9323 // value and that would overflow.
9324 // The low 32-bit value is Op1L*Op0L.
9325 // The high 32-bit value is Op1H*Op0L + Op1L*Op0H + carry (from Op1L*Op0L).
9326
9327 Register Op1L_Op0H_Reg = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
9328 MachineInstr *Op1L_Op0H =
9329 BuildMI(MBB, MII, DL, get(AMDGPU::V_MUL_LO_U32_e64), Op1L_Op0H_Reg)
9330 .add(Op1L)
9331 .add(Op0H);
9332
9333 Register Op1H_Op0L_Reg = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
9334 MachineInstr *Op1H_Op0L =
9335 BuildMI(MBB, MII, DL, get(AMDGPU::V_MUL_LO_U32_e64), Op1H_Op0L_Reg)
9336 .add(Op1H)
9337 .add(Op0L);
9338
9339 Register CarryReg = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
9340 MachineInstr *Carry =
9341 BuildMI(MBB, MII, DL, get(AMDGPU::V_MUL_HI_U32_e64), CarryReg)
9342 .add(Op1L)
9343 .add(Op0L);
9344
9345 MachineInstr *LoHalf =
9346 BuildMI(MBB, MII, DL, get(AMDGPU::V_MUL_LO_U32_e64), DestSub0)
9347 .add(Op1L)
9348 .add(Op0L);
9349
9350 Register AddReg = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
9351 MachineInstr *Add = BuildMI(MBB, MII, DL, get(AMDGPU::V_ADD_U32_e32), AddReg)
9352 .addReg(Op1L_Op0H_Reg)
9353 .addReg(Op1H_Op0L_Reg);
9354
9355 MachineInstr *HiHalf =
9356 BuildMI(MBB, MII, DL, get(AMDGPU::V_ADD_U32_e32), DestSub1)
9357 .addReg(AddReg)
9358 .addReg(CarryReg);
9359
9360 BuildMI(MBB, MII, DL, get(TargetOpcode::REG_SEQUENCE), FullDestReg)
9361 .addReg(DestSub0)
9362 .addImm(AMDGPU::sub0)
9363 .addReg(DestSub1)
9364 .addImm(AMDGPU::sub1);
9365
9366 MRI.replaceRegWith(Dest.getReg(), FullDestReg);
9367
9368 // Try to legalize the operands in case we need to swap the order to keep it
9369 // valid.
9370 legalizeOperands(*Op1L_Op0H, MDT);
9371 legalizeOperands(*Op1H_Op0L, MDT);
9372 legalizeOperands(*Carry, MDT);
9373 legalizeOperands(*LoHalf, MDT);
9374 legalizeOperands(*Add, MDT);
9375 legalizeOperands(*HiHalf, MDT);
9376
9377 // Move all users of this moved value.
9378 addUsersToMoveToVALUWorklist(FullDestReg, MRI, Worklist);
9379}
9380
9381// Lower S_MUL_U64_U32_PSEUDO/S_MUL_I64_I32_PSEUDO in two 32-bit vector
9382// multiplications.
9383void SIInstrInfo::splitScalarSMulPseudo(SIInstrWorklist &Worklist,
9384 MachineInstr &Inst,
9385 MachineDominatorTree *MDT) const {
9386 MachineBasicBlock &MBB = *Inst.getParent();
9387 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
9388
9389 Register FullDestReg = MRI.createVirtualRegister(&AMDGPU::VReg_64RegClass);
9390 Register DestSub0 = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
9391 Register DestSub1 = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass);
9392
9393 MachineOperand &Dest = Inst.getOperand(0);
9394 MachineOperand &Src0 = Inst.getOperand(1);
9395 MachineOperand &Src1 = Inst.getOperand(2);
9396 const DebugLoc &DL = Inst.getDebugLoc();
9397 MachineBasicBlock::iterator MII = Inst;
9398
9399 const TargetRegisterClass *Src0RC = MRI.getRegClass(Src0.getReg());
9400 const TargetRegisterClass *Src1RC = MRI.getRegClass(Src1.getReg());
9401 const TargetRegisterClass *Src0SubRC =
9402 RI.getSubRegisterClass(Src0RC, AMDGPU::sub0);
9403 if (RI.isSGPRClass(Src0SubRC))
9404 Src0SubRC = RI.getEquivalentVGPRClass(Src0SubRC);
9405 const TargetRegisterClass *Src1SubRC =
9406 RI.getSubRegisterClass(Src1RC, AMDGPU::sub0);
9407 if (RI.isSGPRClass(Src1SubRC))
9408 Src1SubRC = RI.getEquivalentVGPRClass(Src1SubRC);
9409
9410 // First, we extract the low 32-bit and high 32-bit values from each of the
9411 // operands.
9412 MachineOperand Op0L =
9413 buildExtractSubRegOrImm(MII, MRI, Src0, Src0RC, AMDGPU::sub0, Src0SubRC);
9414 MachineOperand Op1L =
9415 buildExtractSubRegOrImm(MII, MRI, Src1, Src1RC, AMDGPU::sub0, Src1SubRC);
9416
9417 unsigned Opc = Inst.getOpcode();
9418 unsigned NewOpc = Opc == AMDGPU::S_MUL_U64_U32_PSEUDO
9419 ? AMDGPU::V_MUL_HI_U32_e64
9420 : AMDGPU::V_MUL_HI_I32_e64;
9421 MachineInstr *HiHalf =
9422 BuildMI(MBB, MII, DL,