Skip to content

Commit 785a365

Browse files
committed
Use LiveRegMatrix and only add necessary impdefs
We apparently need to detect interference with other assigned intervals to avoid clobbering the undef lanes defined in other intervals, since the undef def didn't count as interference. This is pretty ugly and adds a new dependency on LiveRegMatrix, keeping it live for one more pass. It also adds a lot of implicit operand spam (we really should have a better representation for this).
1 parent dce609b commit 785a365

10 files changed

+253
-72
lines changed

llvm/include/llvm/CodeGen/LiveRegMatrix.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,16 @@ class LiveRegMatrix : public MachineFunctionPass {
114114
/// the segment [Start, End).
115115
bool checkInterference(SlotIndex Start, SlotIndex End, MCRegister PhysReg);
116116

117+
/// Check for interference in the segment [Start, End) that may prevent
118+
/// assignment to PhysReg, like checkInterference. Returns a lane mask of
119+
/// which lanes of the physical register interfere in the segment [Start, End)
120+
/// of some other interval already assigned to PhysReg.
121+
///
122+
/// If this function returns LaneBitmask::getNone(), PhysReg is completely
123+
/// free at the segment [Start, End).
124+
LaneBitmask checkInterferenceLanes(SlotIndex Start, SlotIndex End,
125+
MCRegister PhysReg);
126+
117127
/// Assign VirtReg to PhysReg.
118128
/// This will mark VirtReg's live range as occupied in the LiveRegMatrix and
119129
/// update VirtRegMap. The live range is expected to be available in PhysReg.

llvm/lib/CodeGen/LiveRegMatrix.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,41 @@ bool LiveRegMatrix::checkInterference(SlotIndex Start, SlotIndex End,
237237
return false;
238238
}
239239

240+
LaneBitmask LiveRegMatrix::checkInterferenceLanes(SlotIndex Start,
241+
SlotIndex End,
242+
MCRegister PhysReg) {
243+
// Construct artificial live range containing only one segment [Start, End).
244+
VNInfo valno(0, Start);
245+
LiveRange::Segment Seg(Start, End, &valno);
246+
LiveRange LR;
247+
LR.addSegment(Seg);
248+
249+
LaneBitmask InterferingLanes;
250+
251+
// Check for interference with that segment
252+
for (MCRegUnitMaskIterator MCRU(PhysReg, TRI); MCRU.isValid(); ++MCRU) {
253+
auto [Unit, Lanes] = *MCRU;
254+
// LR is stack-allocated. LiveRegMatrix caches queries by a key that
255+
// includes the address of the live range. If (for the same reg unit) this
256+
// checkInterference overload is called twice, without any other query()
257+
// calls in between (on heap-allocated LiveRanges) - which would invalidate
258+
// the cached query - the LR address seen the second time may well be the
259+
// same as that seen the first time, while the Start/End/valno may not - yet
260+
// the same cached result would be fetched. To avoid that, we don't cache
261+
// this query.
262+
//
263+
// FIXME: the usability of the Query API needs to be improved to avoid
264+
// subtle bugs due to query identity. Avoiding caching, for example, would
265+
// greatly simplify things.
266+
LiveIntervalUnion::Query Q;
267+
Q.reset(UserTag, LR, Matrix[Unit]);
268+
if (Q.checkInterference())
269+
InterferingLanes |= Lanes;
270+
}
271+
272+
return InterferingLanes;
273+
}
274+
240275
Register LiveRegMatrix::getOneVReg(unsigned PhysReg) const {
241276
const LiveInterval *VRegInterval = nullptr;
242277
for (MCRegUnit Unit : TRI->regunits(PhysReg)) {

llvm/lib/CodeGen/VirtRegMap.cpp

Lines changed: 26 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "llvm/CodeGen/LiveDebugVariables.h"
2222
#include "llvm/CodeGen/LiveInterval.h"
2323
#include "llvm/CodeGen/LiveIntervals.h"
24+
#include "llvm/CodeGen/LiveRegMatrix.h"
2425
#include "llvm/CodeGen/LiveStacks.h"
2526
#include "llvm/CodeGen/MachineBasicBlock.h"
2627
#include "llvm/CodeGen/MachineFrameInfo.h"
@@ -187,6 +188,7 @@ class VirtRegRewriter : public MachineFunctionPass {
187188
MachineRegisterInfo *MRI = nullptr;
188189
SlotIndexes *Indexes = nullptr;
189190
LiveIntervals *LIS = nullptr;
191+
LiveRegMatrix *LRM = nullptr;
190192
VirtRegMap *VRM = nullptr;
191193
LiveDebugVariables *DebugVars = nullptr;
192194
DenseSet<Register> RewriteRegs;
@@ -199,9 +201,6 @@ class VirtRegRewriter : public MachineFunctionPass {
199201
void handleIdentityCopy(MachineInstr &MI);
200202
void expandCopyBundle(MachineInstr &MI) const;
201203
bool subRegLiveThrough(const MachineInstr &MI, MCRegister SuperPhysReg) const;
202-
bool needLiveOutUndefSubregDef(const LiveInterval &LI,
203-
const MachineBasicBlock &MBB, unsigned SubReg,
204-
MCPhysReg PhysReg) const;
205204
LaneBitmask liveOutUndefPhiLanesForUndefSubregDef(
206205
const LiveInterval &LI, const MachineBasicBlock &MBB, unsigned SubReg,
207206
MCPhysReg PhysReg, const MachineInstr &MI) const;
@@ -237,6 +236,7 @@ INITIALIZE_PASS_BEGIN(VirtRegRewriter, "virtregrewriter",
237236
INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass)
238237
INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
239238
INITIALIZE_PASS_DEPENDENCY(LiveDebugVariables)
239+
INITIALIZE_PASS_DEPENDENCY(LiveRegMatrix)
240240
INITIALIZE_PASS_DEPENDENCY(LiveStacks)
241241
INITIALIZE_PASS_DEPENDENCY(VirtRegMap)
242242
INITIALIZE_PASS_END(VirtRegRewriter, "virtregrewriter",
@@ -252,6 +252,7 @@ void VirtRegRewriter::getAnalysisUsage(AnalysisUsage &AU) const {
252252
AU.addRequired<LiveStacks>();
253253
AU.addPreserved<LiveStacks>();
254254
AU.addRequired<VirtRegMap>();
255+
AU.addRequired<LiveRegMatrix>();
255256

256257
if (!ClearVirtRegs)
257258
AU.addPreserved<LiveDebugVariables>();
@@ -266,6 +267,7 @@ bool VirtRegRewriter::runOnMachineFunction(MachineFunction &fn) {
266267
MRI = &MF->getRegInfo();
267268
Indexes = &getAnalysis<SlotIndexesWrapperPass>().getSI();
268269
LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
270+
LRM = &getAnalysis<LiveRegMatrix>();
269271
VRM = &getAnalysis<VirtRegMap>();
270272
DebugVars = &getAnalysis<LiveDebugVariables>();
271273
LLVM_DEBUG(dbgs() << "********** REWRITE VIRTUAL REGISTERS **********\n"
@@ -538,26 +540,6 @@ bool VirtRegRewriter::subRegLiveThrough(const MachineInstr &MI,
538540
return false;
539541
}
540542

541-
/// Check if we need to maintain liveness for undef subregister lanes that are
542-
/// live out of a block.
543-
bool VirtRegRewriter::needLiveOutUndefSubregDef(const LiveInterval &LI,
544-
const MachineBasicBlock &MBB,
545-
unsigned SubReg,
546-
MCPhysReg PhysReg) const {
547-
LaneBitmask UndefMask = ~TRI->getSubRegIndexLaneMask(SubReg);
548-
for (const LiveInterval::SubRange &SR : LI.subranges()) {
549-
LaneBitmask NeedImpDefLanes = UndefMask & SR.LaneMask;
550-
if (NeedImpDefLanes.any() && !LIS->isLiveOutOfMBB(SR, &MBB)) {
551-
for (const MachineBasicBlock *Succ : MBB.successors()) {
552-
if (LIS->isLiveInToMBB(SR, Succ))
553-
return true;
554-
}
555-
}
556-
}
557-
558-
return false;
559-
}
560-
561543
/// Compute a lanemask for undef lanes which need to be preserved out of the
562544
/// defining block for a register assignment.
563545
LaneBitmask VirtRegRewriter::liveOutUndefPhiLanesForUndefSubregDef(
@@ -575,20 +557,17 @@ LaneBitmask VirtRegRewriter::liveOutUndefPhiLanesForUndefSubregDef(
575557
}
576558
}
577559
}
578-
if (LiveOutUndefLanes.none())
579-
return LiveOutUndefLanes;
580560

581561
SlotIndex MIIndex = LIS->getInstructionIndex(MI);
582562
SlotIndex BeforeMIUses = MIIndex.getBaseIndex();
583-
SlotIndex AfterMIDefs = MIIndex.getBoundaryIndex();
584-
585-
for (MCRegUnitMaskIterator MCRU(PhysReg, TRI); MCRU.isValid(); ++MCRU) {
586-
auto [RU, PhysRegMask] = *MCRU;
563+
LaneBitmask InterferingLanes =
564+
LRM->checkInterferenceLanes(BeforeMIUses, MIIndex.getRegSlot(), PhysReg);
565+
LiveOutUndefLanes &= ~InterferingLanes;
587566

588-
const LiveRange &UnitRange = LIS->getRegUnit(RU);
589-
if (UnitRange.liveAt(AfterMIDefs) && UnitRange.liveAt(BeforeMIUses))
590-
LiveOutUndefLanes &= ~PhysRegMask;
591-
}
567+
LLVM_DEBUG(if (LiveOutUndefLanes.any()) {
568+
dbgs() << "Need live out undef defs for " << printReg(PhysReg)
569+
<< LiveOutUndefLanes << " from " << printMBBReference(MBB) << '\n';
570+
});
592571

593572
return LiveOutUndefLanes;
594573
}
@@ -656,33 +635,21 @@ void VirtRegRewriter::rewrite() {
656635
if (LiveOutUndefLanes.any()) {
657636
SmallVector<unsigned, 16> CoveringIndexes;
658637

659-
// TODO: Just use the super register if
660-
if (TRI->getCoveringSubRegIndexes(
638+
// TODO: Just use one super register def if none of the lanes
639+
// are needed?
640+
if (!TRI->getCoveringSubRegIndexes(
661641
*MRI, MRI->getRegClass(VirtReg), LiveOutUndefLanes,
662-
CoveringIndexes)) {
663-
// Try to represent the minimum needed live out def as a
664-
// sequence of subregister defs.
665-
//
666-
// FIXME: It would be better if we could directly represent
667-
// liveness with a lanemask instead of spamming operands.
668-
for (unsigned SubIdx : CoveringIndexes)
669-
SuperDefs.push_back(TRI->getSubReg(PhysReg, SubIdx));
670-
} else {
671-
// If we could not represent this as a sequence of
672-
// subregisters, it's safe to replace all the lanes with a
673-
// full def of the super register.
674-
SuperDefs.push_back(PhysReg);
675-
}
676-
}
677-
678-
if (false &&
679-
needLiveOutUndefSubregDef(LI, *MBBI, SubReg, PhysReg)) {
680-
SuperDefs.push_back(PhysReg);
681-
682-
for (MCRegister AssignedSubReg : TRI->subregs(PhysReg)) {
683-
if (subRegLiveThrough(MI, AssignedSubReg))
684-
SuperKills.push_back(AssignedSubReg);
685-
}
642+
CoveringIndexes))
643+
llvm_unreachable(
644+
"cannot represent required subregister defs");
645+
646+
// Try to represent the minimum needed live out def as a
647+
// sequence of subregister defs.
648+
//
649+
// FIXME: It would be better if we could directly represent
650+
// liveness with a lanemask instead of spamming operands.
651+
for (unsigned SubIdx : CoveringIndexes)
652+
SuperDefs.push_back(TRI->getSubReg(PhysReg, SubIdx));
686653
}
687654
}
688655
}

llvm/test/CodeGen/AMDGPU/indirect-call.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,7 @@ define i32 @test_indirect_call_vgpr_ptr_ret(ptr %fptr) {
603603
; GISEL-NEXT: s_mov_b32 s14, s43
604604
; GISEL-NEXT: s_mov_b32 s15, s42
605605
; GISEL-NEXT: s_swappc_b64 s[30:31], s[16:17]
606+
; GISEL-NEXT: v_mov_b32_e32 v1, v0
606607
; GISEL-NEXT: ; implicit-def: $vgpr0
607608
; GISEL-NEXT: ; implicit-def: $vgpr31
608609
; GISEL-NEXT: s_xor_b64 exec, exec, s[48:49]
@@ -1383,6 +1384,7 @@ define i32 @test_indirect_call_vgpr_ptr_arg_and_return(i32 %i, ptr %fptr) {
13831384
; GISEL-NEXT: v_cmp_eq_u64_e32 vcc, s[8:9], v[1:2]
13841385
; GISEL-NEXT: s_and_saveexec_b64 s[6:7], vcc
13851386
; GISEL-NEXT: s_swappc_b64 s[30:31], s[8:9]
1387+
; GISEL-NEXT: v_mov_b32_e32 v2, v0
13861388
; GISEL-NEXT: ; implicit-def: $vgpr1
13871389
; GISEL-NEXT: ; implicit-def: $vgpr0
13881390
; GISEL-NEXT: s_xor_b64 exec, exec, s[6:7]

llvm/test/CodeGen/AMDGPU/infloop-subrange-spill-inspect-subrange.mir

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ body: |
3030
; CHECK-NEXT: dead [[DEF1:%[0-9]+]]:vgpr_32 = IMPLICIT_DEF
3131
; CHECK-NEXT: dead undef [[DEF2:%[0-9]+]].sub0:vreg_64 = IMPLICIT_DEF
3232
; CHECK-NEXT: renamable $sgpr36_sgpr37_sgpr38_sgpr39_sgpr40_sgpr41_sgpr42_sgpr43_sgpr44_sgpr45_sgpr46_sgpr47_sgpr48_sgpr49_sgpr50_sgpr51 = S_LOAD_DWORDX16_IMM renamable $sgpr4_sgpr5, 0, 0 :: (invariant load (s512), align 32, addrspace 4)
33-
; CHECK-NEXT: renamable $sgpr24 = IMPLICIT_DEF implicit-def $sgpr24_sgpr25_sgpr26_sgpr27
33+
; CHECK-NEXT: renamable $sgpr24 = IMPLICIT_DEF implicit-def $sgpr25
3434
; CHECK-NEXT: renamable $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11_sgpr12_sgpr13_sgpr14_sgpr15_sgpr16_sgpr17_sgpr18_sgpr19 = S_LOAD_DWORDX16_IMM undef renamable $sgpr4_sgpr5, 0, 0 :: (invariant load (s512), align 32, addrspace 4)
3535
; CHECK-NEXT: $exec = S_MOV_B64_term undef renamable $sgpr4_sgpr5
3636
; CHECK-NEXT: S_CBRANCH_EXECZ %bb.6, implicit $exec
@@ -83,7 +83,7 @@ body: |
8383
; CHECK-NEXT: liveins: $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11_sgpr12_sgpr13_sgpr14_sgpr15_sgpr16_sgpr17_sgpr18_sgpr19:0x000000000000FFFF, $sgpr36_sgpr37_sgpr38_sgpr39_sgpr40_sgpr41_sgpr42_sgpr43_sgpr44_sgpr45_sgpr46_sgpr47_sgpr48_sgpr49_sgpr50_sgpr51:0x00000000FFFFFFFF
8484
; CHECK-NEXT: {{ $}}
8585
; CHECK-NEXT: dead [[IMAGE_SAMPLE_LZ_V1_V2_5:%[0-9]+]]:vgpr_32 = IMAGE_SAMPLE_LZ_V1_V2 undef [[DEF]], renamable $sgpr44_sgpr45_sgpr46_sgpr47_sgpr48_sgpr49_sgpr50_sgpr51, undef renamable $sgpr8_sgpr9_sgpr10_sgpr11, 1, 0, 0, 0, 0, 0, 0, 0, implicit $exec :: (dereferenceable load (s32), addrspace 8)
86-
; CHECK-NEXT: renamable $sgpr25 = COPY undef renamable $sgpr24, implicit-def $sgpr24_sgpr25_sgpr26_sgpr27
86+
; CHECK-NEXT: renamable $sgpr25 = COPY undef renamable $sgpr24, implicit-def $sgpr24
8787
; CHECK-NEXT: S_CBRANCH_VCCNZ %bb.7, implicit undef $vcc
8888
; CHECK-NEXT: S_BRANCH %bb.6
8989
; CHECK-NEXT: {{ $}}

llvm/test/CodeGen/AMDGPU/infloop-subrange-spill.mir

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ body: |
3030
; CHECK-NEXT: dead undef [[DEF3:%[0-9]+]].sub1:vreg_64 = IMPLICIT_DEF
3131
; CHECK-NEXT: dead renamable $sgpr5 = IMPLICIT_DEF
3232
; CHECK-NEXT: renamable $sgpr36_sgpr37_sgpr38_sgpr39_sgpr40_sgpr41_sgpr42_sgpr43_sgpr44_sgpr45_sgpr46_sgpr47_sgpr48_sgpr49_sgpr50_sgpr51 = S_LOAD_DWORDX16_IMM undef renamable $sgpr4_sgpr5, 0, 0 :: (invariant load (s512), align 32, addrspace 4)
33-
; CHECK-NEXT: renamable $sgpr24 = IMPLICIT_DEF implicit-def $sgpr24_sgpr25_sgpr26_sgpr27
33+
; CHECK-NEXT: renamable $sgpr24 = IMPLICIT_DEF implicit-def $sgpr25
3434
; CHECK-NEXT: renamable $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11_sgpr12_sgpr13_sgpr14_sgpr15_sgpr16_sgpr17_sgpr18_sgpr19 = S_LOAD_DWORDX16_IMM undef renamable $sgpr4_sgpr5, 0, 0 :: (invariant load (s512), align 32, addrspace 4)
3535
; CHECK-NEXT: $exec = S_MOV_B64_term undef renamable $sgpr4_sgpr5
3636
; CHECK-NEXT: S_CBRANCH_EXECZ %bb.5, implicit $exec
@@ -80,7 +80,7 @@ body: |
8080
; CHECK-NEXT: liveins: $sgpr4_sgpr5_sgpr6_sgpr7_sgpr8_sgpr9_sgpr10_sgpr11_sgpr12_sgpr13_sgpr14_sgpr15_sgpr16_sgpr17_sgpr18_sgpr19:0x000000000000FFFF, $sgpr36_sgpr37_sgpr38_sgpr39_sgpr40_sgpr41_sgpr42_sgpr43_sgpr44_sgpr45_sgpr46_sgpr47_sgpr48_sgpr49_sgpr50_sgpr51:0x00000000FFFFFFFF
8181
; CHECK-NEXT: {{ $}}
8282
; CHECK-NEXT: dead [[IMAGE_SAMPLE_LZ_V1_V2_5:%[0-9]+]]:vgpr_32 = IMAGE_SAMPLE_LZ_V1_V2 undef [[DEF]], renamable $sgpr44_sgpr45_sgpr46_sgpr47_sgpr48_sgpr49_sgpr50_sgpr51, undef renamable $sgpr8_sgpr9_sgpr10_sgpr11, 1, 0, 0, 0, 0, 0, 0, 0, implicit $exec :: (dereferenceable load (s32), addrspace 8)
83-
; CHECK-NEXT: renamable $sgpr25 = COPY undef renamable $sgpr24, implicit-def $sgpr24_sgpr25_sgpr26_sgpr27
83+
; CHECK-NEXT: renamable $sgpr25 = COPY undef renamable $sgpr24, implicit-def $sgpr24
8484
; CHECK-NEXT: S_CBRANCH_VCCNZ %bb.6, implicit undef $vcc
8585
; CHECK-NEXT: S_BRANCH %bb.5
8686
; CHECK-NEXT: {{ $}}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
2+
# RUN: llc -mtriple=amdgcn-amd-amdpal -mcpu=gfx900 -start-before=greedy,2 -stop-after=tailduplication -verify-machineinstrs -o - %s | FileCheck %s
3+
4+
---
5+
name: undef_subreg_def_live_out_tailduplicate_vreg96_undef_sub1_sub2_assigned_physreg_interference
6+
tracksRegLiveness: true
7+
machineFunctionInfo:
8+
isEntryFunction: true
9+
scratchRSrcReg: '$sgpr96_sgpr97_sgpr98_sgpr99'
10+
stackPtrOffsetReg: '$sgpr32'
11+
body: |
12+
; CHECK-LABEL: name: undef_subreg_def_live_out_tailduplicate_vreg96_undef_sub1_sub2_assigned_physreg_interference
13+
; CHECK: bb.0:
14+
; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.1(0x40000000)
15+
; CHECK-NEXT: liveins: $sgpr0, $vgpr2
16+
; CHECK-NEXT: {{ $}}
17+
; CHECK-NEXT: S_CMP_EQ_U32 $sgpr0, 0, implicit-def $scc
18+
; CHECK-NEXT: S_CBRANCH_SCC0 %bb.2, implicit killed $scc
19+
; CHECK-NEXT: {{ $}}
20+
; CHECK-NEXT: bb.1:
21+
; CHECK-NEXT: liveins: $vgpr2
22+
; CHECK-NEXT: {{ $}}
23+
; CHECK-NEXT: renamable $vgpr3 = V_MOV_B32_e32 0, implicit $exec, implicit-def $vgpr4_vgpr5
24+
; CHECK-NEXT: EXP 0, killed renamable $vgpr3, renamable $vgpr4, renamable $vgpr5, killed renamable $vgpr2, 0, 0, 0, implicit $exec
25+
; CHECK-NEXT: S_ENDPGM 0
26+
; CHECK-NEXT: {{ $}}
27+
; CHECK-NEXT: bb.2:
28+
; CHECK-NEXT: liveins: $vgpr2
29+
; CHECK-NEXT: {{ $}}
30+
; CHECK-NEXT: S_NOP 0, implicit-def $sgpr4_sgpr5_sgpr6_sgpr7
31+
; CHECK-NEXT: renamable $vgpr0 = V_MOV_B32_e32 0, implicit $exec
32+
; CHECK-NEXT: renamable $vgpr3_vgpr4_vgpr5 = BUFFER_LOAD_FORMAT_XYZ_IDXEN killed renamable $vgpr0, $sgpr4_sgpr5_sgpr6_sgpr7, 0, 0, 0, 0, implicit $exec :: (dereferenceable load (s96), align 16, addrspace 8)
33+
; CHECK-NEXT: EXP 0, killed renamable $vgpr3, renamable $vgpr4, renamable $vgpr5, killed renamable $vgpr2, 0, 0, 0, implicit $exec
34+
; CHECK-NEXT: S_ENDPGM 0
35+
bb.0:
36+
liveins: $sgpr0, $vgpr2
37+
38+
%2:vgpr_32 = COPY $vgpr2
39+
S_CMP_EQ_U32 killed $sgpr0, 0, implicit-def $scc
40+
S_CBRANCH_SCC0 %bb.2, implicit killed $scc
41+
42+
bb.1:
43+
undef %0.sub0:vreg_96 = V_MOV_B32_e32 0, implicit $exec
44+
S_BRANCH %bb.3
45+
46+
bb.2:
47+
S_NOP 0, implicit-def $sgpr4_sgpr5_sgpr6_sgpr7
48+
%1:vgpr_32 = V_MOV_B32_e32 0, implicit $exec
49+
%0:vreg_96 = BUFFER_LOAD_FORMAT_XYZ_IDXEN killed %1, $sgpr4_sgpr5_sgpr6_sgpr7, 0, 0, 0, 0, implicit $exec :: (dereferenceable load (s96), addrspace 8)
50+
51+
bb.3:
52+
EXP 0, killed %0.sub0, killed %0.sub1, killed %0.sub2, %2:vgpr_32, 0, 0, 0, implicit $exec
53+
S_ENDPGM 0
54+
55+
...

0 commit comments

Comments
 (0)