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-regbanklegalize"
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 MachineInstr &SrcMI = *MRI.getVRegDef(Reg: Src);
278 if (SrcMI.getOpcode() == AMDGPU::G_BITCAST)
279 RALDst = SrcMI.getOperand(i: 1).getReg();
280
281 B.setInstrAndDebugLoc(Copy);
282 SmallVector<Register> ReadAnyLaneSrcRegs = getReadAnyLaneSrcs(Src: RALDst);
283 if (ReadAnyLaneSrcRegs.empty())
284 return false;
285
286 Register ReadAnyLaneSrc;
287 if (ReadAnyLaneSrcRegs.size() == 1) {
288 ReadAnyLaneSrc = ReadAnyLaneSrcRegs[0];
289 } else {
290 // Multiple readanylane sources without a common unmerge, merge them.
291 auto Merge = B.buildMergeLikeInstr(Res: {VgprRB, MRI.getType(Reg: RALDst)},
292 Ops: ReadAnyLaneSrcRegs);
293 ReadAnyLaneSrc = Merge.getReg(Idx: 0);
294 }
295
296 if (SrcMI.getOpcode() != AMDGPU::G_BITCAST) {
297 // Src = READANYLANE RALSrc Src = READANYLANE RALSrc
298 // Dst = Copy Src $Dst = Copy Src
299 // -> ->
300 // Dst = RALSrc $Dst = Copy RALSrc
301 replaceRegWithOrBuildCopy(Dst, Src: ReadAnyLaneSrc);
302 } else {
303 // RALDst = READANYLANE RALSrc RALDst = READANYLANE RALSrc
304 // Src = G_BITCAST RALDst Src = G_BITCAST RALDst
305 // Dst = Copy Src Dst = Copy Src
306 // -> ->
307 // NewVgpr = G_BITCAST RALDst NewVgpr = G_BITCAST RALDst
308 // Dst = NewVgpr $Dst = Copy NewVgpr
309 auto Bitcast = B.buildBitcast(Dst: {VgprRB, MRI.getType(Reg: Src)}, Src: ReadAnyLaneSrc);
310 replaceRegWithOrBuildCopy(Dst, Src: Bitcast.getReg(Idx: 0));
311 }
312
313 eraseInstr(MI&: Copy, MRI);
314 return true;
315}
316
317void AMDGPURegBankLegalizeCombiner::tryCombineCopy(MachineInstr &MI) {
318 if (tryEliminateReadAnyLane(Copy&: MI))
319 return;
320
321 Register Dst = MI.getOperand(i: 0).getReg();
322 Register Src = MI.getOperand(i: 1).getReg();
323 // Skip copies of physical registers.
324 if (!Dst.isVirtual() || !Src.isVirtual())
325 return;
326
327 // This is a cross bank copy, sgpr S1 to lane mask.
328 //
329 // %Src:sgpr(s1) = G_TRUNC %TruncS32Src:sgpr(s32)
330 // %Dst:lane-mask(s1) = COPY %Src:sgpr(s1)
331 // ->
332 // %BoolSrc:sgpr(s32) = G_AND %TruncS32Src:sgpr(s32), 1
333 // %Dst:lane-mask(s1) = G_AMDGPU_COPY_VCC_SCC %BoolSrc:sgpr(s32)
334 if (isLaneMask(Reg: Dst) && MRI.getRegBankOrNull(Reg: Src) == SgprRB) {
335 auto [Trunc, TruncS32Src] = tryMatch(Src, Opcode: AMDGPU::G_TRUNC);
336 assert(Trunc && MRI.getType(TruncS32Src) == S32 &&
337 "sgpr S1 must be result of G_TRUNC of sgpr S32");
338
339 B.setInstr(MI);
340 // Ensure that truncated bits in BoolSrc are 0.
341 auto One = B.buildConstant(Res: {SgprRB, S32}, Val: 1);
342 auto BoolSrc = B.buildAnd(Dst: {SgprRB, S32}, Src0: TruncS32Src, Src1: One);
343 B.buildInstr(Opc: AMDGPU::G_AMDGPU_COPY_VCC_SCC, DstOps: {Dst}, SrcOps: {BoolSrc});
344 eraseInstr(MI, MRI);
345 }
346}
347
348void AMDGPURegBankLegalizeCombiner::tryCombineS1AnyExt(MachineInstr &MI) {
349 // %Src:sgpr(S1) = G_TRUNC %TruncSrc
350 // %Dst = G_ANYEXT %Src:sgpr(S1)
351 // ->
352 // %Dst = G_... %TruncSrc
353 Register Dst = MI.getOperand(i: 0).getReg();
354 Register Src = MI.getOperand(i: 1).getReg();
355 if (MRI.getType(Reg: Src) != S1)
356 return;
357
358 auto [Trunc, TruncSrc] = tryMatch(Src, Opcode: AMDGPU::G_TRUNC);
359 if (!Trunc)
360 return;
361
362 LLT DstTy = MRI.getType(Reg: Dst);
363 LLT TruncSrcTy = MRI.getType(Reg: TruncSrc);
364
365 if (DstTy == TruncSrcTy) {
366 MRI.replaceRegWith(FromReg: Dst, ToReg: TruncSrc);
367 eraseInstr(MI, MRI);
368 return;
369 }
370
371 B.setInstr(MI);
372
373 if (DstTy == S32 && TruncSrcTy == S64) {
374 auto Unmerge = B.buildUnmerge(Attrs: {.RCOrRB: SgprRB, .Ty: S32}, Op: TruncSrc);
375 MRI.replaceRegWith(FromReg: Dst, ToReg: Unmerge.getReg(Idx: 0));
376 eraseInstr(MI, MRI);
377 return;
378 }
379
380 if (DstTy == S64 && TruncSrcTy == S32) {
381 B.buildMergeLikeInstr(Res: MI.getOperand(i: 0).getReg(),
382 Ops: {TruncSrc, B.buildUndef(Res: {SgprRB, S32})});
383 eraseInstr(MI, MRI);
384 return;
385 }
386
387 if (DstTy == S32 && TruncSrcTy == S16) {
388 B.buildAnyExt(Res: Dst, Op: TruncSrc);
389 eraseInstr(MI, MRI);
390 return;
391 }
392
393 if (DstTy == S16 && TruncSrcTy == S32) {
394 B.buildTrunc(Res: Dst, Op: TruncSrc);
395 eraseInstr(MI, MRI);
396 return;
397 }
398
399 llvm_unreachable("missing anyext + trunc combine");
400}
401
402// Search through MRI for virtual registers with sgpr register bank and S1 LLT.
403[[maybe_unused]] static Register getAnySgprS1(const MachineRegisterInfo &MRI) {
404 const LLT S1 = LLT::scalar(SizeInBits: 1);
405 for (unsigned i = 0; i < MRI.getNumVirtRegs(); ++i) {
406 Register Reg = Register::index2VirtReg(Index: i);
407 if (MRI.def_empty(RegNo: Reg) || MRI.getType(Reg) != S1)
408 continue;
409
410 const RegisterBank *RB = MRI.getRegBankOrNull(Reg);
411 if (RB && RB->getID() == AMDGPU::SGPRRegBankID) {
412 LLVM_DEBUG(dbgs() << "Warning: detected sgpr S1 register in: ";
413 MRI.getVRegDef(Reg)->dump(););
414 return Reg;
415 }
416 }
417
418 return {};
419}
420
421bool AMDGPURegBankLegalize::runOnMachineFunction(MachineFunction &MF) {
422 if (MF.getProperties().hasFailedISel())
423 return false;
424
425 // Setup the instruction builder with CSE.
426 const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
427 GISelCSEAnalysisWrapper &Wrapper =
428 getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
429 GISelCSEInfo &CSEInfo = Wrapper.get(CSEOpt: TPC.getCSEConfig());
430 GISelObserverWrapper Observer;
431 Observer.addObserver(O: &CSEInfo);
432
433 CSEMIRBuilder B(MF);
434 B.setCSEInfo(&CSEInfo);
435 B.setChangeObserver(Observer);
436
437 RAIIDelegateInstaller DelegateInstaller(MF, &Observer);
438 RAIIMFObserverInstaller MFObserverInstaller(MF, Observer);
439
440 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
441 MachineRegisterInfo &MRI = MF.getRegInfo();
442 const RegisterBankInfo &RBI = *ST.getRegBankInfo();
443 const MachineUniformityInfo &MUI =
444 getAnalysis<MachineUniformityAnalysisPass>().getUniformityInfo();
445 GISelValueTracking &VT =
446 getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
447
448 // RegBankLegalizeRules is initialized with assigning sets of IDs to opcodes.
449 const RegBankLegalizeRules &RBLRules = getRules(ST, MRI);
450
451 // Logic that does legalization based on IDs assigned to Opcode.
452 RegBankLegalizeHelper RBLHelper(B, MUI, &VT, RBI, RBLRules);
453
454 SmallVector<MachineInstr *> AllInst;
455
456 for (MachineBasicBlock &MBB : MF) {
457 for (MachineInstr &MI : MBB) {
458 AllInst.push_back(Elt: &MI);
459 }
460 }
461
462 for (MachineInstr *MI : AllInst) {
463 if (!MI->isPreISelOpcode())
464 continue;
465
466 if (!RBLHelper.findRuleAndApplyMapping(MI&: *MI))
467 return false;
468 }
469
470 // Sgpr S1 clean up combines:
471 // - Sgpr S1(S32) to sgpr S1(S32) Copy: anyext + trunc combine.
472 // In RegBankLegalize 'S1 Dst' are legalized into S32 as
473 // 'S1Dst = Trunc S32Dst' and 'S1 Src' into 'S32Src = Anyext S1Src'.
474 // S1 Truncs and Anyexts that come from legalizer, that can have non-S32
475 // types e.g. S16 = Anyext S1 or S1 = Trunc S64, will also be cleaned up.
476 // - Sgpr S1(S32) to vcc Copy: G_AMDGPU_COPY_VCC_SCC combine.
477 // Divergent instruction uses sgpr S1 as input that should be lane mask(vcc)
478 // Legalizing this use creates sgpr S1(S32) to vcc Copy.
479
480 // Note: Remaining S1 copies, S1s are either sgpr S1(S32) or vcc S1:
481 // - Vcc to vcc Copy: nothing to do here, just a regular copy.
482 // - Vcc to sgpr S1 Copy: Should not exist in a form of COPY instruction(*).
483 // Note: For 'uniform-in-vcc to sgpr-S1 copy' G_AMDGPU_COPY_SCC_VCC is used
484 // instead. When only available instruction creates vcc result, use of
485 // UniformInVcc results in creating G_AMDGPU_COPY_SCC_VCC.
486
487 // (*)Explanation for 'sgpr S1(uniform) = COPY vcc(divergent)':
488 // Copy from divergent to uniform register indicates an error in either:
489 // - Uniformity analysis: Uniform instruction has divergent input. If one of
490 // the inputs is divergent, instruction should be divergent!
491 // - RegBankLegalizer not executing in waterfall loop (missing implementation)
492
493 AMDGPURegBankLegalizeCombiner Combiner(B, *ST.getRegisterInfo(), RBI);
494
495 for (MachineBasicBlock &MBB : MF) {
496 for (MachineInstr &MI : make_early_inc_range(Range&: MBB)) {
497 if (MI.getOpcode() == AMDGPU::COPY) {
498 Combiner.tryCombineCopy(MI);
499 continue;
500 }
501 if (MI.getOpcode() == AMDGPU::G_ANYEXT) {
502 Combiner.tryCombineS1AnyExt(MI);
503 continue;
504 }
505 }
506 }
507
508 assert(!getAnySgprS1(MRI).isValid() &&
509 "Registers with sgpr reg bank and S1 LLT are not legal after "
510 "AMDGPURegBankLegalize. Should lower to sgpr S32");
511
512 return true;
513}
514