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/MachineFunctionAnalysisManager.h"
31#include "llvm/CodeGen/MachineFunctionPass.h"
32#include "llvm/CodeGen/MachinePassManager.h"
33#include "llvm/CodeGen/MachineUniformityAnalysis.h"
34#include "llvm/CodeGen/TargetPassConfig.h"
35#include "llvm/InitializePasses.h"
36
37#define DEBUG_TYPE "amdgpu-reg-bank-legalize"
38
39using namespace llvm;
40using namespace AMDGPU;
41using namespace llvm::MIPatternMatch;
42
43namespace {
44
45// AMDGPU-specific pattern matchers
46template <typename SrcTy>
47inline UnaryOp_match<SrcTy, AMDGPU::G_AMDGPU_READANYLANE>
48m_GAMDGPUReadAnyLane(const SrcTy &Src) {
49 return UnaryOp_match<SrcTy, AMDGPU::G_AMDGPU_READANYLANE>(Src);
50}
51
52class AMDGPURegBankLegalizeLegacy : public MachineFunctionPass {
53public:
54 static char ID;
55
56public:
57 AMDGPURegBankLegalizeLegacy() : MachineFunctionPass(ID) {}
58
59 bool runOnMachineFunction(MachineFunction &MF) override;
60
61 StringRef getPassName() const override {
62 return "AMDGPU Register Bank Legalize";
63 }
64
65 void getAnalysisUsage(AnalysisUsage &AU) const override {
66 AU.addRequired<TargetPassConfig>();
67 AU.addRequired<GISelCSEAnalysisWrapperPass>();
68 AU.addRequired<MachineUniformityAnalysisPass>();
69 AU.addRequired<GISelValueTrackingAnalysisLegacy>();
70 MachineFunctionPass::getAnalysisUsage(AU);
71 }
72
73 // If there were no phis and we do waterfall expansion machine verifier would
74 // fail.
75 MachineFunctionProperties getClearedProperties() const override {
76 return MachineFunctionProperties().setNoPHIs();
77 }
78};
79
80} // End anonymous namespace.
81
82INITIALIZE_PASS_BEGIN(AMDGPURegBankLegalizeLegacy, DEBUG_TYPE,
83 "AMDGPU Register Bank Legalize", false, false)
84INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
85INITIALIZE_PASS_DEPENDENCY(GISelCSEAnalysisWrapperPass)
86INITIALIZE_PASS_DEPENDENCY(MachineUniformityAnalysisPass)
87INITIALIZE_PASS_DEPENDENCY(GISelValueTrackingAnalysisLegacy)
88INITIALIZE_PASS_END(AMDGPURegBankLegalizeLegacy, DEBUG_TYPE,
89 "AMDGPU Register Bank Legalize", false, false)
90
91char AMDGPURegBankLegalizeLegacy::ID = 0;
92
93char &llvm::AMDGPURegBankLegalizeLegacyID = AMDGPURegBankLegalizeLegacy::ID;
94
95FunctionPass *llvm::createAMDGPURegBankLegalizeLegacyPass() {
96 return new AMDGPURegBankLegalizeLegacy();
97}
98
99const RegBankLegalizeRules &getRules(const GCNSubtarget &ST,
100 MachineRegisterInfo &MRI) {
101 static std::mutex GlobalMutex;
102 static SmallDenseMap<unsigned, std::unique_ptr<RegBankLegalizeRules>>
103 CacheForRuleSet;
104 std::lock_guard<std::mutex> Lock(GlobalMutex);
105 auto [It, Inserted] = CacheForRuleSet.try_emplace(Key: ST.getGeneration());
106 if (Inserted)
107 It->second = std::make_unique<RegBankLegalizeRules>(args: ST, args&: MRI);
108 else
109 It->second->refreshRefs(ST: ST, MRI&: MRI);
110 return *It->second;
111}
112
113class AMDGPURegBankLegalizeCombiner {
114 MachineIRBuilder &B;
115 MachineRegisterInfo &MRI;
116 const SIRegisterInfo &TRI;
117 const RegisterBank *SgprRB;
118 const RegisterBank *VgprRB;
119 const RegisterBank *VccRB;
120
121 static constexpr LLT S1 = LLT::scalar(SizeInBits: 1);
122 static constexpr LLT S16 = LLT::scalar(SizeInBits: 16);
123 static constexpr LLT S32 = LLT::scalar(SizeInBits: 32);
124 static constexpr LLT S64 = LLT::scalar(SizeInBits: 64);
125
126public:
127 AMDGPURegBankLegalizeCombiner(MachineIRBuilder &B, const SIRegisterInfo &TRI,
128 const RegisterBankInfo &RBI)
129 : B(B), MRI(*B.getMRI()), TRI(TRI),
130 SgprRB(&RBI.getRegBank(ID: AMDGPU::SGPRRegBankID)),
131 VgprRB(&RBI.getRegBank(ID: AMDGPU::VGPRRegBankID)),
132 VccRB(&RBI.getRegBank(ID: AMDGPU::VCCRegBankID)) {};
133
134 bool isLaneMask(Register Reg);
135 std::pair<MachineInstr *, Register> tryMatch(Register Src, unsigned Opcode);
136 Register tryMatchUnmergeDefs(SmallVectorImpl<Register> &DefRegs);
137 SmallVector<Register> tryMatchMergeReadAnyLane(GMergeLikeInstr *Merge);
138 SmallVector<Register> getReadAnyLaneSrcs(Register Src);
139 void replaceRegWithOrBuildCopy(Register Dst, Register Src);
140
141 bool tryEliminateReadAnyLane(MachineInstr &Copy);
142 void tryCombineCopy(MachineInstr &MI);
143 void tryCombineS1AnyExt(MachineInstr &MI);
144};
145
146bool AMDGPURegBankLegalizeCombiner::isLaneMask(Register Reg) {
147 const RegisterBank *RB = MRI.getRegBankOrNull(Reg);
148 if (RB && RB->getID() == AMDGPU::VCCRegBankID)
149 return true;
150
151 const TargetRegisterClass *RC = MRI.getRegClassOrNull(Reg);
152 return RC && TRI.isSGPRClass(RC) && MRI.getType(Reg) == LLT::scalar(SizeInBits: 1);
153}
154
155std::pair<MachineInstr *, Register>
156AMDGPURegBankLegalizeCombiner::tryMatch(Register Src, unsigned Opcode) {
157 MachineInstr *MatchMI = MRI.getVRegDef(Reg: Src);
158 if (MatchMI->getOpcode() != Opcode)
159 return {nullptr, Register()};
160 return {MatchMI, MatchMI->getOperand(i: 1).getReg()};
161}
162
163// Check if all registers are from same unmerge and there is no shuffling.
164// Returns the unmerge source if both conditions are met.
165Register AMDGPURegBankLegalizeCombiner::tryMatchUnmergeDefs(
166 SmallVectorImpl<Register> &DefRegs) {
167 auto *UnMerge = getOpcodeDef<GUnmerge>(Reg: DefRegs[0], MRI);
168 if (!UnMerge || UnMerge->getNumDefs() != DefRegs.size())
169 return {};
170 for (unsigned I = 1; I < DefRegs.size(); ++I) {
171 if (UnMerge->getReg(Idx: I) != DefRegs[I])
172 return {};
173 }
174 return UnMerge->getSourceReg();
175}
176
177// Check if all merge sources are readanylanes and return the readanylane
178// sources if they are.
179SmallVector<Register> AMDGPURegBankLegalizeCombiner::tryMatchMergeReadAnyLane(
180 GMergeLikeInstr *Merge) {
181 SmallVector<Register> ReadAnyLaneSrcs;
182 for (unsigned i = 0; i < Merge->getNumSources(); ++i) {
183 Register Src;
184 if (!mi_match(R: Merge->getSourceReg(I: i), MRI,
185 P: m_GAMDGPUReadAnyLane(Src: m_Reg(R&: Src))))
186 return {};
187 ReadAnyLaneSrcs.push_back(Elt: Src);
188 }
189 return ReadAnyLaneSrcs;
190}
191
192SmallVector<Register>
193AMDGPURegBankLegalizeCombiner::getReadAnyLaneSrcs(Register Src) {
194 // Src = G_AMDGPU_READANYLANE RALSrc
195 Register RALSrc;
196 if (mi_match(R: Src, MRI, P: m_GAMDGPUReadAnyLane(Src: m_Reg(R&: RALSrc))))
197 return {RALSrc};
198
199 // RALSrc = G_ANYEXT S16Src
200 // TruncSrc = G_AMDGPU_READANYLANE RALSrc
201 // Src = G_TRUNC TruncSrc
202 if (mi_match(R: Src, MRI,
203 P: m_GTrunc(Src: m_GAMDGPUReadAnyLane(Src: m_GAnyExt(Src: m_Reg(R&: RALSrc)))))) {
204 return {RALSrc};
205 }
206
207 // TruncSrc = G_AMDGPU_READANYLANE RALSrc
208 // AextSrc = G_TRUNC TruncSrc
209 // Src = G_ANYEXT AextSrc
210 if (mi_match(R: Src, MRI,
211 P: m_GAnyExt(Src: m_GTrunc(Src: m_GAMDGPUReadAnyLane(Src: m_Reg(R&: RALSrc)))))) {
212 return {RALSrc};
213 }
214
215 // Sgpr0 = G_AMDGPU_READANYLANE Vgpr0
216 // Sgpr1 = G_AMDGPU_READANYLANE Vgpr1
217 // ...
218 // Src = G_MERGE_LIKE Sgpr0, Sgpr1, ...
219 // Dst = COPY Src
220 if (auto *Merge = getOpcodeDef<GMergeLikeInstr>(Reg: Src, MRI)) {
221 SmallVector<Register> ReadAnyLaneSrcs = tryMatchMergeReadAnyLane(Merge);
222 if (ReadAnyLaneSrcs.empty())
223 return {};
224
225 // Vgpr0, Vgpr1, ... = G_UNMERGE_VALUES UnmergeSrc
226 if (Register UnmergeSrc = tryMatchUnmergeDefs(DefRegs&: ReadAnyLaneSrcs))
227 return {UnmergeSrc};
228
229 // Multiple ReadAnyLane vgpr sources, need to merge Vgpr0, Vgpr1, ...
230 return ReadAnyLaneSrcs;
231 }
232
233 // SrcRegIdx = G_AMDGPU_READANYLANE RALElSrc
234 // SourceReg G_MERGE_VALUES ..., SrcRegIdx, ...
235 // ..., Src, ... = G_UNMERGE_VALUES SourceReg
236 auto *UnMerge = getOpcodeDef<GUnmerge>(Reg: Src, MRI);
237 if (!UnMerge)
238 return {};
239
240 int Idx = UnMerge->findRegisterDefOperandIdx(Reg: Src, TRI: nullptr);
241 auto *Merge = getOpcodeDef<GMergeLikeInstr>(Reg: UnMerge->getSourceReg(), MRI);
242 if (!Merge || UnMerge->getNumDefs() != Merge->getNumSources())
243 return {};
244
245 Register SrcRegIdx = Merge->getSourceReg(I: Idx);
246 if (MRI.getType(Reg: Src) != MRI.getType(Reg: SrcRegIdx))
247 return {};
248
249 auto [RALEl, RALElSrc] = tryMatch(Src: SrcRegIdx, Opcode: AMDGPU::G_AMDGPU_READANYLANE);
250 if (RALEl)
251 return {RALElSrc};
252
253 return {};
254}
255
256void AMDGPURegBankLegalizeCombiner::replaceRegWithOrBuildCopy(Register Dst,
257 Register Src) {
258 if (Dst.isVirtual())
259 MRI.replaceRegWith(FromReg: Dst, ToReg: Src);
260 else
261 B.buildCopy(Res: Dst, Op: Src);
262}
263
264bool AMDGPURegBankLegalizeCombiner::tryEliminateReadAnyLane(
265 MachineInstr &Copy) {
266 Register Dst = Copy.getOperand(i: 0).getReg();
267 Register Src = Copy.getOperand(i: 1).getReg();
268
269 // Skip non-vgpr Dst
270 if (Dst.isVirtual() ? (MRI.getRegBankOrNull(Reg: Dst) != VgprRB)
271 : !TRI.isVGPR(MRI, Reg: Dst))
272 return false;
273
274 // Skip physical source registers and source registers with register class
275 if (!Src.isVirtual() || MRI.getRegClassOrNull(Reg: Src))
276 return false;
277
278 Register RALDst = Src;
279 bool IsBitcast = mi_match(R: Src, MRI, P: m_GBitcast(Src: m_Reg(R&: RALDst)));
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 (!IsBitcast) {
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
421static bool
422runRegBankLegalize(MachineFunction &MF,
423 function_ref<GISelCSEInfo *()> GetCSEInfo,
424 function_ref<const MachineUniformityInfo *()> GetMUI,
425 function_ref<GISelValueTracking *()> GetVT) {
426 if (MF.getProperties().hasFailedISel())
427 return false;
428
429 GISelCSEInfo &CSEInfo = *GetCSEInfo();
430 const MachineUniformityInfo &MUI = *GetMUI();
431 GISelValueTracking &VT = *GetVT();
432
433 // Setup the instruction builder with CSE.
434 GISelObserverWrapper Observer;
435 Observer.addObserver(O: &CSEInfo);
436
437 CSEMIRBuilder B(MF);
438 B.setCSEInfo(&CSEInfo);
439 B.setChangeObserver(Observer);
440
441 RAIIDelegateInstaller DelegateInstaller(MF, &Observer);
442 RAIIMFObserverInstaller MFObserverInstaller(MF, Observer);
443
444 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
445 MachineRegisterInfo &MRI = MF.getRegInfo();
446 const RegisterBankInfo &RBI = *ST.getRegBankInfo();
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
515bool AMDGPURegBankLegalizeLegacy::runOnMachineFunction(MachineFunction &MF) {
516 return runRegBankLegalize(
517 MF,
518 GetCSEInfo: [&]() {
519 GISelCSEAnalysisWrapper &Wrapper =
520 getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
521 return &Wrapper.get(CSEOpt: getAnalysis<TargetPassConfig>().getCSEConfig());
522 },
523 GetMUI: [&]() {
524 return &getAnalysis<MachineUniformityAnalysisPass>()
525 .getUniformityInfo();
526 },
527 GetVT: [&]() {
528 return &getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
529 });
530}
531
532PreservedAnalyses
533AMDGPURegBankLegalizePass::run(MachineFunction &MF,
534 MachineFunctionAnalysisManager &MFAM) {
535 MFPropsModifier _(*this, MF);
536
537 if (!runRegBankLegalize(
538 MF, GetCSEInfo: [&]() { return MFAM.getResult<GISelCSEAnalysis>(IR&: MF).get(); },
539 GetMUI: [&]() { return &MFAM.getResult<MachineUniformityAnalysis>(IR&: MF); },
540 GetVT: [&]() { return &MFAM.getResult<GISelValueTrackingAnalysis>(IR&: MF); }))
541 return PreservedAnalyses::all();
542
543 return getMachineFunctionPassPreservedAnalyses();
544}
545