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