[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: https://github.com/llvm/llvm-project/issues/175596 --------- Co-authored-by: Carl Ritson <critson@perlfu.co.uk>
This commit is contained in:
parent
ede1a9626b
commit
9deb4fda30
@ -2014,6 +2014,16 @@ void TwoAddressInstructionImpl::eliminateRegSequence(
|
||||
}
|
||||
}
|
||||
|
||||
// If there are no live intervals information, we scan the use list once
|
||||
// in order to find which subregisters are used.
|
||||
LaneBitmask UsedLanes = LaneBitmask::getNone();
|
||||
if (!LIS) {
|
||||
for (MachineOperand &Use : MRI->use_nodbg_operands(DstReg)) {
|
||||
if (unsigned SubReg = Use.getSubReg())
|
||||
UsedLanes |= TRI->getSubRegIndexLaneMask(SubReg);
|
||||
}
|
||||
}
|
||||
|
||||
LaneBitmask UndefLanes = LaneBitmask::getNone();
|
||||
bool DefEmitted = false;
|
||||
for (unsigned i = 1, e = MI.getNumOperands(); i < e; i += 2) {
|
||||
@ -2021,9 +2031,14 @@ void TwoAddressInstructionImpl::eliminateRegSequence(
|
||||
Register SrcReg = UseMO.getReg();
|
||||
unsigned SubIdx = MI.getOperand(i+1).getImm();
|
||||
// Nothing needs to be inserted for undef operands.
|
||||
// Unless there are no live intervals, and they are used at a later
|
||||
// instruction as operand.
|
||||
if (UseMO.isUndef()) {
|
||||
UndefLanes |= TRI->getSubRegIndexLaneMask(SubIdx);
|
||||
continue;
|
||||
LaneBitmask LaneMask = TRI->getSubRegIndexLaneMask(SubIdx);
|
||||
if (LIS || (UsedLanes & LaneMask).none()) {
|
||||
UndefLanes |= LaneMask;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Defer any kill flag to the last operand using SrcReg. Otherwise, we
|
||||
|
||||
@ -0,0 +1,69 @@
|
||||
# RUN: llc -mtriple=amdgcn-amd-amdhsa -verify-machineinstrs -run-pass=twoaddressinstruction -o - %s | FileCheck -check-prefix=CHECK %s
|
||||
# RUN: llc -mtriple=amdgcn-amd-amdhsa -verify-machineinstrs -run-pass=liveintervals,twoaddressinstruction -o - %s | FileCheck -check-prefix=LIS %s
|
||||
|
||||
# Checks that while lowering REG_SEQUENCE, undef COPY are not skipped if there is no LIS
|
||||
# information
|
||||
|
||||
---
|
||||
name: regsequence-undef-subreg-use
|
||||
noPhis: true
|
||||
body: |
|
||||
bb.0:
|
||||
|
||||
; CHECK-LABEL: name: regsequence-undef-subreg-use
|
||||
; CHECK: [[COPY:%[0-9]+]]:sgpr_32 = S_MOV_B32 0, implicit $exec
|
||||
; CHECK-NEXT: undef [[DEF:%[0-9]+]].sub0:sreg_64 = COPY [[COPY]]
|
||||
; CHECK-NEXT: [[DEF:%[0-9]+]].sub1:sreg_64 = COPY undef [[UND:%[0-9]+]]:sgpr_32
|
||||
; CHECK-NEXT: [[OTH:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 [[DEF]].sub1
|
||||
|
||||
; LIS-LABEL: name: regsequence-undef-subreg-use
|
||||
; LIS: [[COPY:%[0-9]+]]:sgpr_32 = S_MOV_B32 0, implicit $exec
|
||||
; LIS-NEXT: undef [[DEF:%[0-9]+]].sub0:sreg_64 = COPY [[COPY]]
|
||||
; LIS-NEXT: [[OTH:%[0-9]+]]:vgpr_32 = V_MOV_B32_e32 undef [[DEF]].sub1
|
||||
|
||||
%0:sgpr_32 = S_MOV_B32 0, implicit $exec
|
||||
|
||||
%1:sreg_64 = REG_SEQUENCE %0, %subreg.sub0, undef %2:sgpr_32, %subreg.sub1
|
||||
%3:vgpr_32 = V_MOV_B32_e32 %1.sub1, implicit $exec
|
||||
...
|
||||
|
||||
---
|
||||
name: regsequence-undef-subreg-without-use
|
||||
noPhis: true
|
||||
body: |
|
||||
bb.0:
|
||||
|
||||
; CHECK-LABEL: name: regsequence-undef-subreg-without-use
|
||||
; CHECK: [[COPY:%[0-9]+]]:sgpr_32 = S_MOV_B32 0, implicit $exec
|
||||
; CHECK-NEXT: undef [[DEF:%[0-9]+]].sub0:sreg_64 = COPY [[COPY]]
|
||||
|
||||
; LIS-LABEL: name: regsequence-undef-subreg-without-use
|
||||
; LIS: [[COPY:%[0-9]+]]:sgpr_32 = S_MOV_B32 0, implicit $exec
|
||||
; LIS-NEXT: undef [[DEF:%[0-9]+]].sub0:sreg_64 = COPY [[COPY]]
|
||||
|
||||
%0:sgpr_32 = S_MOV_B32 0, implicit $exec
|
||||
|
||||
%1:sreg_64 = REG_SEQUENCE %0, %subreg.sub0, undef %2:sgpr_32, %subreg.sub1
|
||||
...
|
||||
|
||||
---
|
||||
name: regsequence-undef-subreg-full-reg-use
|
||||
noPhis: true
|
||||
body: |
|
||||
bb.0:
|
||||
|
||||
; CHECK-LABEL: name: regsequence-undef-subreg-full-reg-use
|
||||
; CHECK: [[COPY:%[0-9]+]]:sgpr_32 = S_MOV_B32 0, implicit $exec
|
||||
; CHECK-NEXT: undef [[DEF:%[0-9]+]].sub0:sreg_64 = COPY [[COPY]]
|
||||
; CHECK-NEXT: [[OTH:%[0-9]+]]:vreg_64 = COPY [[DEF]], implicit $exec
|
||||
|
||||
; LIS-LABEL: name: regsequence-undef-subreg-full-reg-use
|
||||
; LIS: [[COPY:%[0-9]+]]:sgpr_32 = S_MOV_B32 0, implicit $exec
|
||||
; LIS-NEXT: undef [[DEF:%[0-9]+]].sub0:sreg_64 = COPY [[COPY]]
|
||||
; LIS-NEXT: [[OTH:%[0-9]+]]:vreg_64 = COPY [[DEF]], implicit $exec
|
||||
|
||||
%0:sgpr_32 = S_MOV_B32 0, implicit $exec
|
||||
|
||||
%1:sreg_64 = REG_SEQUENCE %0, %subreg.sub0, undef %2:sgpr_32, %subreg.sub1
|
||||
%3:vreg_64 = COPY %1, implicit $exec
|
||||
...
|
||||
Loading…
x
Reference in New Issue
Block a user