1//===-- AMDGPURegBankLegalize.cpp -----------------------------------------===//
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/// Lower G_ instructions that can't be inst-selected with register bank
10/// assignment from AMDGPURegBankSelect based on machine uniformity info.
11/// Given types on all operands, some register bank assignments require lowering
12/// while others do not.
13/// Note: cases where all register bank assignments would require lowering are
14/// lowered in legalizer.
15/// For example vgpr S64 G_AND requires lowering to S32 while sgpr S64 does not.
16/// Eliminate sgpr S1 by lowering to sgpr S32.
17//
18//===----------------------------------------------------------------------===//
19
20#include "AMDGPU.h"
21#include "AMDGPUGlobalISelUtils.h"
22#include "AMDGPURegBankLegalizeHelper.h"
23#include "GCNSubtarget.h"
24#include "llvm/CodeGen/GlobalISel/CSEInfo.h"
25#include "llvm/CodeGen/GlobalISel/CSEMIRBuilder.h"
26#include "llvm/CodeGen/GlobalISel/GISelValueTracking.h"
27#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
28#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
29#include "llvm/CodeGen/GlobalISel/Utils.h"
30#include "llvm/CodeGen/MachineFunctionPass.h"
31#include "llvm/CodeGen/MachineUniformityAnalysis.h"
32#include "llvm/CodeGen/TargetPassConfig.h"
33#include "llvm/InitializePasses.h"
34
35#define DEBUG_TYPE "amdgpu-reg-bank-legalize"
36
37using namespace llvm;
38using namespace AMDGPU;
39using namespace llvm::MIPatternMatch;
40
41namespace {
42
43// AMDGPU-specific pattern matchers
44template <typename SrcTy>
45inline UnaryOp_match<SrcTy, AMDGPU::G_AMDGPU_READANYLANE>
46m_GAMDGPUReadAnyLane(const SrcTy &Src) {
47 return UnaryOp_match<SrcTy, AMDGPU::G_AMDGPU_READANYLANE>(Src);
48}
49
50class AMDGPURegBankLegalize : public MachineFunctionPass {
51public:
52 static char ID;
53
54public:
55 AMDGPURegBankLegalize() : MachineFunctionPass(ID) {}
56
57 bool runOnMachineFunction(MachineFunction &MF) override;
58
59 StringRef getPassName() const override {
60 return "AMDGPU Register Bank Legalize";
61 }
62
63 void getAnalysisUsage(AnalysisUsage &AU) const override {
64 AU.addRequired<TargetPassConfig>();
65 AU.addRequired<GISelCSEAnalysisWrapperPass>();
66 AU.addRequired<MachineUniformityAnalysisPass>();
67 AU.addRequired<GISelValueTrackingAnalysisLegacy>();
68 MachineFunctionPass::getAnalysisUsage(AU);
69 }
70
71 // If there were no phis and we do waterfall expansion machine verifier would
72 // fail.
73 MachineFunctionProperties getClearedProperties() const override {
74 return MachineFunctionProperties().setNoPHIs();
75 }
76};
77
78} // End anonymous namespace.
79
80INITIALIZE_PASS_BEGIN(AMDGPURegBankLegalize, DEBUG_TYPE,
81 "AMDGPU Register Bank Legalize", false, false)
82INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
83INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
84INITIALIZE_PASS_DEPENDENCY(MachineUniformityAnalysisPass)
85INITIALIZE_PASS_DEPENDENCY(GISelValueTrackingAnalysisLegacy)
86INITIALIZE_PASS_END(AMDGPURegBankLegalize, DEBUG_TYPE,
87 "AMDGPU Register Bank Legalize", false, false)
88
89char AMDGPURegBankLegalize::ID = 0;
90
91char &llvm::AMDGPURegBankLegalizeID = AMDGPURegBankLegalize::ID;
92
93FunctionPass *llvm::createAMDGPURegBankLegalizePass() {
94 return new AMDGPURegBankLegalize();
95}
96
97const RegBankLegalizeRules &getRules(const GCNSubtarget &ST,
98 MachineRegisterInfo &MRI) {
99 static std::mutex GlobalMutex;
100 static SmallDenseMap<unsigned, std::unique_ptr<RegBankLegalizeRules>>
101 CacheForRuleSet;
102 std::lock_guard<std::mutex> Lock(GlobalMutex);
103 auto [It, Inserted] = CacheForRuleSet.try_emplace(Key: ST.getGeneration());
104 if (Inserted)
105 It->second = std::make_unique<RegBankLegalizeRules>(args: ST, args&: MRI);
106 else
107 It->second->refreshRefs(ST: ST, MRI&: MRI);
108 return *It->second;
109}
110
111class AMDGPURegBankLegalizeCombiner {
112 MachineIRBuilder &B;
113 MachineRegisterInfo &MRI;
114 const SIRegisterInfo &TRI;
115 const RegisterBank *SgprRB;
116 const RegisterBank *VgprRB;
117 const RegisterBank *VccRB;
118
119 static constexpr LLT S1 = LLT::scalar(SizeInBits: 1);
120 static constexpr LLT S16 = LLT::scalar(SizeInBits: 16);
121 static constexpr LLT S32 = LLT::scalar(SizeInBits: 32);
122 static constexpr LLT S64 = LLT::scalar(SizeInBits: 64);
123
124public:
125 AMDGPURegBankLegalizeCombiner(MachineIRBuilder &B, const SIRegisterInfo &TRI,
126 const RegisterBankInfo &RBI)
127 : B(B), MRI(*B.getMRI()), TRI(TRI),
128 SgprRB(&RBI.getRegBank(ID: AMDGPU::SGPRRegBankID)),
129 VgprRB(&RBI.getRegBank(ID: AMDGPU::VGPRRegBankID)),
130 VccRB(&RBI.getRegBank(ID: AMDGPU::VCCRegBankID)) {};
131
132 bool isLaneMask(Register Reg);
133 std::pair<MachineInstr *, Register> tryMatch(Register Src, unsigned Opcode);
134 Register tryMatchUnmergeDefs(SmallVectorImpl<Register> &DefRegs);
135 SmallVector<Register> tryMatchMergeReadAnyLane(GMergeLikeInstr *Merge);
136 SmallVector<Register> getReadAnyLaneSrcs(Register Src);
137 void replaceRegWithOrBuildCopy(Register Dst, Register Src);
138
139 bool tryEliminateReadAnyLane(MachineInstr &Copy);
140 void tryCombineCopy(MachineInstr &MI);
141 void tryCombineS1AnyExt(MachineInstr &MI);
142};
143
144bool AMDGPURegBankLegalizeCombiner::isLaneMask(Register Reg) {
145 const RegisterBank *RB = MRI.getRegBankOrNull(Reg);
146 if (RB && RB->getID() == AMDGPU::VCCRegBankID)
147 return true;
148
149 const TargetRegisterClass *RC = MRI.getRegClassOrNull(Reg);
150 return RC && TRI.isSGPRClass(RC) && MRI.getType(Reg) == LLT::scalar(SizeInBits: 1);
151}
152
153std::pair<MachineInstr *, Register>
154AMDGPURegBankLegalizeCombiner::tryMatch(Register Src, unsigned Opcode) {
155 MachineInstr *MatchMI = MRI.getVRegDef(Reg: Src);
156 if (MatchMI->getOpcode() != Opcode)
157 return {nullptr, Register()};
158 return {MatchMI, MatchMI->getOperand(i: 1).getReg()};
159}
160
161// Check if all registers are from same unmerge and there is no shuffling.
162// Returns the unmerge source if both conditions are met.
163Register AMDGPURegBankLegalizeCombiner::tryMatchUnmergeDefs(
164 SmallVectorImpl<Register> &DefRegs) {
165 auto *UnMerge = getOpcodeDef<GUnmerge>(Reg: DefRegs[0], MRI);
166 if (!UnMerge || UnMerge->getNumDefs() != DefRegs.size())
167 return {};
168 for (unsigned I = 1; I < DefRegs.size(); ++I) {
169 if (UnMerge->getReg(Idx: I) != DefRegs[I])
170 return {};
171 }
172 return UnMerge->getSourceReg();
173}
174
175// Check if all merge sources are readanylanes and return the readanylane
176// sources if they are.
177SmallVector<Register> AMDGPURegBankLegalizeCombiner::tryMatchMergeReadAnyLane(
178 GMergeLikeInstr *Merge) {
179 SmallVector<Register> ReadAnyLaneSrcs;
180 for (unsigned i = 0; i < Merge->getNumSources(); ++i) {
181 Register Src;
182 if (!mi_match(R: Merge->getSourceReg(I: i), MRI,
183 P: m_GAMDGPUReadAnyLane(Src: m_Reg(R&: Src))))
184 return {};
185 ReadAnyLaneSrcs.push_back(Elt: Src);
186 }
187 return ReadAnyLaneSrcs;
188}
189
190SmallVector<Register>
191AMDGPURegBankLegalizeCombiner::getReadAnyLaneSrcs(Register Src) {
192 // Src = G_AMDGPU_READANYLANE RALSrc
193 Register RALSrc;
194 if (mi_match(R: Src, MRI, P: m_GAMDGPUReadAnyLane(Src: m_Reg(R&: RALSrc))))
195 return {RALSrc};
196
197 // RALSrc = G_ANYEXT S16Src
198 // TruncSrc = G_AMDGPU_READANYLANE RALSrc
199 // Src = G_TRUNC TruncSrc
200 if (mi_match(R: Src, MRI,
201 P: m_GTrunc(Src: m_GAMDGPUReadAnyLane(Src: m_GAnyExt(Src: m_Reg(R&: RALSrc)))))) {
202 return {RALSrc};
203 }
204
205 // TruncSrc = G_AMDGPU_READANYLANE RALSrc
206 // AextSrc = G_TRUNC TruncSrc
207 // Src = G_ANYEXT AextSrc
208 if (mi_match(R: Src, MRI,
209 P: m_GAnyExt(Src: m_GTrunc(Src: m_GAMDGPUReadAnyLane(Src: m_Reg(R&: RALSrc)))))) {
210 return {RALSrc};
211 }
212
213 // Sgpr0 = G_AMDGPU_READANYLANE Vgpr0
214 // Sgpr1 = G_AMDGPU_READANYLANE Vgpr1
215 // ...
216 // Src = G_MERGE_LIKE Sgpr0, Sgpr1, ...
217 // Dst = COPY Src
218 if (auto *Merge = getOpcodeDef<GMergeLikeInstr>(Reg: Src, MRI)) {
219 SmallVector<Register> ReadAnyLaneSrcs = tryMatchMergeReadAnyLane(Merge);
220 if (ReadAnyLaneSrcs.empty())
221 return {};
222
223 // Vgpr0, Vgpr1, ... = G_UNMERGE_VALUES UnmergeSrc
224 if (Register UnmergeSrc = tryMatchUnmergeDefs(DefRegs&: ReadAnyLaneSrcs))
225 return {UnmergeSrc};
226
227 // Multiple ReadAnyLane vgpr sources, need to merge Vgpr0, Vgpr1, ...
228 return ReadAnyLaneSrcs;
229 }
230
231 // SrcRegIdx = G_AMDGPU_READANYLANE RALElSrc
232 // SourceReg G_MERGE_VALUES ..., SrcRegIdx, ...
233 // ..., Src, ... = G_UNMERGE_VALUES SourceReg
234 auto *UnMerge = getOpcodeDef<GUnmerge>(Reg: Src, MRI);
235 if (!UnMerge)
236 return {};
237
238 int Idx = UnMerge->findRegisterDefOperandIdx(Reg: Src, TRI: nullptr);
239 auto *Merge = getOpcodeDef<GMergeLikeInstr>(Reg: UnMerge->getSourceReg(), MRI);
240 if (!Merge || UnMerge->getNumDefs() != Merge->getNumSources())
241 return {};
242
243 Register SrcRegIdx = Merge->getSourceReg(I: Idx);
244 if (MRI.getType(Reg: Src) != MRI.getType(Reg: SrcRegIdx))
245 return {};
246
247 auto [RALEl, RALElSrc] = tryMatch(Src: SrcRegIdx, Opcode: AMDGPU::G_AMDGPU_READANYLANE);
248 if (RALEl)
249 return {RALElSrc};
250
251 return {};
252}
253
254void AMDGPURegBankLegalizeCombiner::replaceRegWithOrBuildCopy(Register Dst,
255 Register Src) {
256 if (Dst.isVirtual())
257 MRI.replaceRegWith(FromReg: Dst, ToReg: Src);
258 else
259 B.buildCopy(Res: Dst, Op: Src);
260}
261
262bool AMDGPURegBankLegalizeCombiner::tryEliminateReadAnyLane(
263 MachineInstr &Copy) {
264 Register Dst = Copy.getOperand(i: 0).getReg();
265 Register Src = Copy.getOperand(i: 1).getReg();
266
267 // Skip non-vgpr Dst
268 if (Dst.isVirtual() ? (MRI.getRegBankOrNull(Reg: Dst) != VgprRB)
269 : !TRI.isVGPR(MRI, Reg: Dst))
270 return false;
271
272 // Skip physical source registers and source registers with register class
273 if (!Src.isVirtual() || MRI.getRegClassOrNull(Reg: Src))
274 return false;
275
276 Register RALDst = Src;
277 bool IsBitcast = mi_match(R: Src, MRI, P: m_GBitcast(Src: m_Reg(R&: RALDst)));
278
279 B.setInstrAndDebugLoc(Copy);
280 SmallVector<Register> ReadAnyLaneSrcRegs = getReadAnyLaneSrcs(Src: RALDst);
281 if (ReadAnyLaneSrcRegs.empty())
282 return false;
283
284 Register ReadAnyLaneSrc;
285 if (ReadAnyLaneSrcRegs.size() == 1) {
286 ReadAnyLaneSrc = ReadAnyLaneSrcRegs[0];
287 } else {
288 // Multiple readanylane sources without a common unmerge, merge them.
289 auto Merge = B.buildMergeLikeInstr(Res: {VgprRB, MRI.getType(Reg: RALDst)},
290 Ops: ReadAnyLaneSrcRegs);
291 ReadAnyLaneSrc = Merge.getReg(Idx: 0);
292 }
293
294 if (!IsBitcast) {
295 // Src = READANYLANE RALSrc Src = READANYLANE RALSrc
296 // Dst = Copy Src $Dst = Copy Src
297 // -> ->
298 // Dst = RALSrc $Dst = Copy RALSrc
299 replaceRegWithOrBuildCopy(Dst, Src: ReadAnyLaneSrc);
300 } else {
301 // RALDst = READANYLANE RALSrc RALDst = READANYLANE RALSrc
302 // Src = G_BITCAST RALDst Src = G_BITCAST RALDst
303 // Dst = Copy Src Dst = Copy Src
304 // -> ->
305 // NewVgpr = G_BITCAST RALDst NewVgpr = G_BITCAST RALDst
306 // Dst = NewVgpr $Dst = Copy NewVgpr
307 auto Bitcast = B.buildBitcast(Dst: {VgprRB, MRI.getType(Reg: Src)}, Src: ReadAnyLaneSrc);
308 replaceRegWithOrBuildCopy(Dst, Src: Bitcast.getReg(Idx: 0));
309 }
310
311 eraseInstr(MI&: Copy, MRI);
312 return true;
313}
314
315void AMDGPURegBankLegalizeCombiner::tryCombineCopy(MachineInstr &MI) {
316 if (tryEliminateReadAnyLane(Copy&: MI))
317 return;
318
319 Register Dst = MI.getOperand(i: 0).getReg();
320 Register Src = MI.getOperand(i: 1).getReg();
321 // Skip copies of physical registers.
322 if (!Dst.isVirtual() || !Src.isVirtual())
323 return;
324
325 // This is a cross bank copy, sgpr S1 to lane mask.
326 //
327 // %Src:sgpr(s1) = G_TRUNC %TruncS32Src:sgpr(s32)
328 // %Dst:lane-mask(s1) = COPY %Src:sgpr(s1)
329 // ->
330 // %BoolSrc:sgpr(s32) = G_AND %TruncS32Src:sgpr(s32), 1
331 // %Dst:lane-mask(s1) = G_AMDGPU_COPY_VCC_SCC %BoolSrc:sgpr(s32)
332 if (isLaneMask(Reg: Dst) && MRI.getRegBankOrNull(Reg: Src) == SgprRB) {
333 auto [Trunc, TruncS32Src] = tryMatch(Src, Opcode: AMDGPU::G_TRUNC);
334 assert(Trunc && MRI.getType(TruncS32Src) == S32 &&
335 "sgpr S1 must be result of G_TRUNC of sgpr S32");
336
337 B.setInstr(MI);
338 // Ensure that truncated bits in BoolSrc are 0.
339 auto One = B.buildConstant(Res: {SgprRB, S32}, Val: 1);
340 auto BoolSrc = B.buildAnd(Dst: {SgprRB, S32}, Src0: TruncS32Src, Src1: One);
341 B.buildInstr(Opc: AMDGPU::G_AMDGPU_COPY_VCC_SCC, DstOps: {Dst}, SrcOps: {BoolSrc});
342 eraseInstr(MI, MRI);
343 }
344}
345
346void AMDGPURegBankLegalizeCombiner::tryCombineS1AnyExt(MachineInstr &MI) {
347 // %Src:sgpr(S1) = G_TRUNC %TruncSrc
348 // %Dst = G_ANYEXT %Src:sgpr(S1)
349 // ->
350 // %Dst = G_... %TruncSrc
351 Register Dst = MI.getOperand(i: 0).getReg();
352 Register Src = MI.getOperand(i: 1).getReg();
353 if (MRI.getType(Reg: Src) != S1)
354 return;
355
356 auto [Trunc, TruncSrc] = tryMatch(Src, Opcode: AMDGPU::G_TRUNC);
357 if (!Trunc)
358 return;
359
360 LLT DstTy = MRI.getType(Reg: Dst);
361 LLT TruncSrcTy = MRI.getType(Reg: TruncSrc);
362
363 if (DstTy == TruncSrcTy) {
364 MRI.replaceRegWith(FromReg: Dst, ToReg: TruncSrc);
365 eraseInstr(MI, MRI);
366 return;
367 }
368
369 B.setInstr(MI);
370
371 if (DstTy == S32 && TruncSrcTy == S64) {
372 auto Unmerge = B.buildUnmerge(Attrs: {.RCOrRB: SgprRB, .Ty: S32}, Op: TruncSrc);
373 MRI.replaceRegWith(FromReg: Dst, ToReg: Unmerge.getReg(Idx: 0));
374 eraseInstr(MI, MRI);
375 return;
376 }
377
378 if (DstTy == S64 && TruncSrcTy == S32) {
379 B.buildMergeLikeInstr(Res: MI.getOperand(i: 0).getReg(),
380 Ops: {TruncSrc, B.buildUndef(Res: {SgprRB, S32})});
381 eraseInstr(MI, MRI);
382 return;
383 }
384
385 if (DstTy == S32 && TruncSrcTy == S16) {
386 B.buildAnyExt(Res: Dst, Op: TruncSrc);
387 eraseInstr(MI, MRI);
388 return;
389 }
390
391 if (DstTy == S16 && TruncSrcTy == S32) {
392 B.buildTrunc(Res: Dst, Op: TruncSrc);
393 eraseInstr(MI, MRI);
394 return;
395 }
396
397 llvm_unreachable("missing anyext + trunc combine");
398}
399
400// Search through MRI for virtual registers with sgpr register bank and S1 LLT.
401[[maybe_unused]] static Register getAnySgprS1(const MachineRegisterInfo &MRI) {
402 const LLT S1 = LLT::scalar(SizeInBits: 1);
403 for (unsigned i = 0; i < MRI.getNumVirtRegs(); ++i) {
404 Register Reg = Register::index2VirtReg(Index: i);
405 if (MRI.def_empty(RegNo: Reg) || MRI.getType(Reg) != S1)
406 continue;
407
408 const RegisterBank *RB = MRI.getRegBankOrNull(Reg);
409 if (RB && RB->getID() == AMDGPU::SGPRRegBankID) {
410 LLVM_DEBUG(dbgs() << "Warning: detected sgpr S1 register in: ";
411 MRI.getVRegDef(Reg)->dump(););
412 return Reg;
413 }
414 }
415
416 return {};
417}
418
419bool AMDGPURegBankLegalize::runOnMachineFunction(MachineFunction &MF) {
420 if (MF.getProperties().hasFailedISel())
421 return false;
422
423 // Setup the instruction builder with CSE.
424 const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
425 GISelCSEAnalysisWrapper &Wrapper =
426 getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
427 GISelCSEInfo &CSEInfo = Wrapper.get(CSEOpt: TPC.getCSEConfig());
428 GISelObserverWrapper Observer;
429 Observer.addObserver(O: &CSEInfo);
430
431 CSEMIRBuilder B(MF);
432 B.setCSEInfo(&CSEInfo);
433 B.setChangeObserver(Observer);
434
435 RAIIDelegateInstaller DelegateInstaller(MF, &Observer);
436 RAIIMFObserverInstaller MFObserverInstaller(MF, Observer);
437
438 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
439 MachineRegisterInfo &MRI = MF.getRegInfo();
440 const RegisterBankInfo &RBI = *ST.getRegBankInfo();
441 const MachineUniformityInfo &MUI =
442 getAnalysis<MachineUniformityAnalysisPass>().getUniformityInfo();
443 GISelValueTracking &VT =
444 getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
445
446 // RegBankLegalizeRules is initialized with assigning sets of IDs to opcodes.
447 const RegBankLegalizeRules &RBLRules = getRules(ST, MRI);
448
449 // Logic that does legalization based on IDs assigned to Opcode.
450 RegBankLegalizeHelper RBLHelper(B, MUI, &VT, RBI, RBLRules);
451
452 SmallVector<MachineInstr *> AllInst;
453
454 for (MachineBasicBlock &MBB : MF) {
455 for (MachineInstr &MI : MBB) {
456 AllInst.push_back(Elt: &MI);
457 }
458 }
459
460 for (MachineInstr *MI : AllInst) {
461 if (!MI->isPreISelOpcode())
462 continue;
463
464 if (!RBLHelper.findRuleAndApplyMapping(MI&: *MI))
465 return false;
466 }
467
468 // Sgpr S1 clean up combines:
469 // - Sgpr S1(S32) to sgpr S1(S32) Copy: anyext + trunc combine.
470 // In RegBankLegalize 'S1 Dst' are legalized into S32 as
471 // 'S1Dst = Trunc S32Dst' and 'S1 Src' into 'S32Src = Anyext S1Src'.
472 // S1 Truncs and Anyexts that come from legalizer, that can have non-S32
473 // types e.g. S16 = Anyext S1 or S1 = Trunc S64, will also be cleaned up.
474 // - Sgpr S1(S32) to vcc Copy: G_AMDGPU_COPY_VCC_SCC combine.
475 // Divergent instruction uses sgpr S1 as input that should be lane mask(vcc)
476 // Legalizing this use creates sgpr S1(S32) to vcc Copy.
477
478 // Note: Remaining S1 copies, S1s are either sgpr S1(S32) or vcc S1:
479 // - Vcc to vcc Copy: nothing to do here, just a regular copy.
480 // - Vcc to sgpr S1 Copy: Should not exist in a form of COPY instruction(*).
481 // Note: For 'uniform-in-vcc to sgpr-S1 copy' G_AMDGPU_COPY_SCC_VCC is used
482 // instead. When only available instruction creates vcc result, use of
483 // UniformInVcc results in creating G_AMDGPU_COPY_SCC_VCC.
484
485 // (*)Explanation for 'sgpr S1(uniform) = COPY vcc(divergent)':
486 // Copy from divergent to uniform register indicates an error in either:
487 // - Uniformity analysis: Uniform instruction has divergent input. If one of
488 // the inputs is divergent, instruction should be divergent!
489 // - RegBankLegalizer not executing in waterfall loop (missing implementation)
490
491 AMDGPURegBankLegalizeCombiner Combiner(B, *ST.getRegisterInfo(), RBI);
492
493 for (MachineBasicBlock &MBB : MF) {
494 for (MachineInstr &MI : make_early_inc_range(Range&: MBB)) {
495 if (MI.getOpcode() == AMDGPU::COPY) {
496 Combiner.tryCombineCopy(MI);
497 continue;
498 }
499 if (MI.getOpcode() == AMDGPU::G_ANYEXT) {
500 Combiner.tryCombineS1AnyExt(MI);
501 continue;
502 }
503 }
504 }
505
506 assert(!getAnySgprS1(MRI).isValid() &&
507 "Registers with sgpr reg bank and S1 LLT are not legal after "
508 "AMDGPURegBankLegalize. Should lower to sgpr S32");
509
510 return true;
511}
512