Skip to content

Commit 9deb4fd

Browse files
kezada94perlfu
andauthored
[CodeGen][AMDGPU] TwoAddress: Only skip undef COPY at REG_SEQUENCE lowering when there is Live info or no uses for subreg (#175598)
Currently, the compiler doesn't create a COPY for undef operands while lowering REG_SEQUENCE, and only if LIS information is available, it propagates the undef flag to the subreg uses. So, if LIS isn't available, we can end up with some uses without def of those lanes. Now, we check which lanes are used in a single scan of use_nodbg_operands() per REG_SEQ, and perform the skip of the COPY only if LIS is avaible (as undef will be propagated later) or if there are no uses for that lane. There is still a scan of the use list, but now it's only one per REG_SEQ and I think it's necessary, as there is no guarantee to have LIS or other analysis pass information at this stage. This is a proposal fix for issue: llvm/llvm-project#175596 --------- Co-authored-by: Carl Ritson <critson@perlfu.co.uk>
1 parent ede1a96 commit 9deb4fd

File tree

2 files changed

+86
-2
lines changed

2 files changed

+86
-2
lines changed

llvm/lib/CodeGen/TwoAddressInstructionPass.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2014,16 +2014,31 @@ void TwoAddressInstructionImpl::eliminateRegSequence(
20142014
}
20152015
}
20162016

2017+
// If there are no live intervals information, we scan the use list once
2018+
// in order to find which subregisters are used.
2019+
LaneBitmask UsedLanes = LaneBitmask::getNone();
2020+
if (!LIS) {
2021+
for (MachineOperand &Use : MRI->use_nodbg_operands(DstReg)) {
2022+
if (unsigned SubReg = Use.getSubReg())
2023+
UsedLanes |= TRI->getSubRegIndexLaneMask(SubReg);
2024+
}
2025+
}
2026+
20172027
LaneBitmask UndefLanes = LaneBitmask::getNone();
20182028
bool DefEmitted = false;
20192029
for (unsigned i = 1, e = MI.getNumOperands(); i < e; i += 2) {
20202030
MachineOperand &UseMO = MI.getOperand(i);
20212031
Register SrcReg = UseMO.getReg();
20222032
unsigned SubIdx = MI.getOperand(i+1).getImm();
20232033
// Nothing needs to be inserted for undef operands.
2034+
// Unless there are no live intervals, and they are used at a later
2035+
// instruction as operand.
20242036
if (UseMO.isUndef()) {
2025-
UndefLanes |= TRI->getSubRegIndexLaneMask(SubIdx);
2026-
continue;
2037+
LaneBitmask LaneMask = TRI->getSubRegIndexLaneMask(SubIdx);
2038+
if (LIS || (UsedLanes & LaneMask).none()) {
2039+
UndefLanes |= LaneMask;
2040+
continue;
2041+
}
20272042
}
20282043

20292044
// Defer any kill flag to the last operand using SrcReg. Otherwise, we
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# RUN: llc -mtriple=amdgcn-amd-amdhsa -verify-machineinstrs -run-pass=twoaddressinstruction -o - %s | FileCheck -check-prefix=CHECK %s
2+
# RUN: llc -mtriple=amdgcn-amd-amdhsa -verify-machineinstrs -run-pass=liveintervals,twoaddressinstruction -o - %s | FileCheck -check-prefix=LIS %s
3+
4+
# Checks that while lowering REG_SEQUENCE, undef COPY are not skipped if there is no LIS
5+
# information
6+
7+
---
8+
name: regsequence-undef-subreg-use
9+
noPhis: true
10+
body: |
11+
bb.0:
12+
13+
; CHECK-LABEL: name: regsequence-undef-subreg-use
14+
; CHECK: [[COPY:%[0-9]+]]:sgpr_32 = S_MOV_B32 0, implicit $exec
15+
; CHECK-NEXT: undef [[DEF:%[0-9]+]].sub0:sreg_64 = COPY [[COPY]]
16+
; CHECK-NEXT: [[DEF:%[0-9]+]].sub1:sreg_64 = COPY undef [[UND:%[0-9]+]]:sgpr_32
17+
; CHECK-NEXT: [[OTH:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 [[DEF]].sub1
18+
19+
; LIS-LABEL: name: regsequence-undef-subreg-use
20+
; LIS: [[COPY:%[0-9]+]]:sgpr_32 = S_MOV_B32 0, implicit $exec
21+
; LIS-NEXT: undef [[DEF:%[0-9]+]].sub0:sreg_64 = COPY [[COPY]]
22+
; LIS-NEXT: [[OTH:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 undef [[DEF]].sub1
23+
24+
%0:sgpr_32 = S_MOV_B32 0, implicit $exec
25+
26+
%1:sreg_64 = REG_SEQUENCE %0, %subreg.sub0, undef %2:sgpr_32, %subreg.sub1
27+
%3:vgpr_32 = V_MOV_B32_e32 %1.sub1, implicit $exec
28+
...
29+
30+
---
31+
name: regsequence-undef-subreg-without-use
32+
noPhis: true
33+
body: |
34+
bb.0:
35+
36+
; CHECK-LABEL: name: regsequence-undef-subreg-without-use
37+
; CHECK: [[COPY:%[0-9]+]]:sgpr_32 = S_MOV_B32 0, implicit $exec
38+
; CHECK-NEXT: undef [[DEF:%[0-9]+]].sub0:sreg_64 = COPY [[COPY]]
39+
40+
; LIS-LABEL: name: regsequence-undef-subreg-without-use
41+
; LIS: [[COPY:%[0-9]+]]:sgpr_32 = S_MOV_B32 0, implicit $exec
42+
; LIS-NEXT: undef [[DEF:%[0-9]+]].sub0:sreg_64 = COPY [[COPY]]
43+
44+
%0:sgpr_32 = S_MOV_B32 0, implicit $exec
45+
46+
%1:sreg_64 = REG_SEQUENCE %0, %subreg.sub0, undef %2:sgpr_32, %subreg.sub1
47+
...
48+
49+
---
50+
name: regsequence-undef-subreg-full-reg-use
51+
noPhis: true
52+
body: |
53+
bb.0:
54+
55+
; CHECK-LABEL: name: regsequence-undef-subreg-full-reg-use
56+
; CHECK: [[COPY:%[0-9]+]]:sgpr_32 = S_MOV_B32 0, implicit $exec
57+
; CHECK-NEXT: undef [[DEF:%[0-9]+]].sub0:sreg_64 = COPY [[COPY]]
58+
; CHECK-NEXT: [[OTH:%[0-9]+]]:vreg_64 = COPY [[DEF]], implicit $exec
59+
60+
; LIS-LABEL: name: regsequence-undef-subreg-full-reg-use
61+
; LIS: [[COPY:%[0-9]+]]:sgpr_32 = S_MOV_B32 0, implicit $exec
62+
; LIS-NEXT: undef [[DEF:%[0-9]+]].sub0:sreg_64 = COPY [[COPY]]
63+
; LIS-NEXT: [[OTH:%[0-9]+]]:vreg_64 = COPY [[DEF]], implicit $exec
64+
65+
%0:sgpr_32 = S_MOV_B32 0, implicit $exec
66+
67+
%1:sreg_64 = REG_SEQUENCE %0, %subreg.sub0, undef %2:sgpr_32, %subreg.sub1
68+
%3:vreg_64 = COPY %1, implicit $exec
69+
...

0 commit comments

Comments
 (0)