MachineInstr: Respect register aliases in clearRegiserKills()
This fixes bugs in copy elimination code in llvm. It slightly changes the semantics of clearRegisterKills(). This is appropriate because: - Users in lib/CodeGen/MachineCopyPropagation.cpp and lib/Target/AArch64RedundantCopyElimination.cpp and lib/Target/SystemZ/SystemZElimCompare.cpp are incorrect without it (see included testcase). - All other users in llvm are unaffected (they pass TRI==nullptr) - (Kill flags are optional anyway so removing too many shouldn't hurt.) Differential Revision: http://reviews.llvm.org/D17554 llvm-svn: 261763
This commit is contained in:
parent
e7e7c98f0b
commit
aca625a4fe
|
@ -1083,8 +1083,8 @@ public:
|
|||
const TargetRegisterInfo *RegInfo,
|
||||
bool AddIfNotFound = false);
|
||||
|
||||
/// Clear all kill flags affecting Reg. If RegInfo is
|
||||
/// provided, this includes super-register kills.
|
||||
/// Clear all kill flags affecting Reg. If RegInfo is provided, this includes
|
||||
/// all aliasing registers.
|
||||
void clearRegisterKills(unsigned Reg, const TargetRegisterInfo *RegInfo);
|
||||
|
||||
/// We have determined MI defined a register without a use.
|
||||
|
|
|
@ -1967,7 +1967,7 @@ void MachineInstr::clearRegisterKills(unsigned Reg,
|
|||
if (!MO.isReg() || !MO.isUse() || !MO.isKill())
|
||||
continue;
|
||||
unsigned OpReg = MO.getReg();
|
||||
if (OpReg == Reg || (RegInfo && RegInfo->isSuperRegister(Reg, OpReg)))
|
||||
if ((RegInfo && RegInfo->regsOverlap(Reg, OpReg)) || Reg == OpReg)
|
||||
MO.setIsKill(false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
# RUN: llc -march=x86 -run-pass machine-cp -verify-machineinstrs -o /dev/null %s 2>&1 | FileCheck %s
|
||||
|
||||
--- |
|
||||
declare void @foo()
|
||||
define void @copyprop_remove_kill0() { ret void }
|
||||
define void @copyprop_remove_kill1() { ret void }
|
||||
define void @copyprop_remove_kill2() { ret void }
|
||||
...
|
||||
---
|
||||
# The second copy is redundand and will be removed, check that we also remove
|
||||
# the kill flag of intermediate instructions.
|
||||
# CHECK-LABEL: name: copyprop_remove_kill0
|
||||
# CHECK: bb.0:
|
||||
# CHECK-NEXT: %rax = COPY %rdi
|
||||
# CHECK-NEXT: NOOP implicit %rdi
|
||||
# CHECK-NOT: COPY
|
||||
# CHECK-NEXT: NOOP implicit %rax, implicit %rdi
|
||||
name: copyprop_remove_kill0
|
||||
body: |
|
||||
bb.0:
|
||||
%rax = COPY %rdi
|
||||
NOOP implicit killed %rdi
|
||||
%rdi = COPY %rax
|
||||
NOOP implicit %rax, implicit %rdi
|
||||
...
|
||||
---
|
||||
# The second copy is redundand and will be removed, check that we also remove
|
||||
# the kill flag of intermediate instructions.
|
||||
# CHECK-LABEL: name: copyprop_remove_kill1
|
||||
# CHECK: bb.0:
|
||||
# CHECK-NEXT: %rax = COPY %rdi
|
||||
# CHECK-NEXT: NOOP implicit %edi
|
||||
# CHECK-NOT: COPY
|
||||
# CHECK-NEXT: NOOP implicit %rax, implicit %rdi
|
||||
name: copyprop_remove_kill1
|
||||
body: |
|
||||
bb.0:
|
||||
%rax = COPY %rdi
|
||||
NOOP implicit killed %edi
|
||||
%rdi = COPY %rax
|
||||
NOOP implicit %rax, implicit %rdi
|
||||
...
|
||||
---
|
||||
# The second copy is redundand and will be removed, check that we also remove
|
||||
# the kill flag of intermediate instructions.
|
||||
# CHECK-LABEL: name: copyprop_remove_kill2
|
||||
# CHECK: bb.0:
|
||||
# CHECK-NEXT: %ax = COPY %di
|
||||
# CHECK-NEXT: NOOP implicit %rdi
|
||||
# CHECK-NOT: COPY
|
||||
# CHECK-NEXT: NOOP implicit %rax, implicit %rdi
|
||||
name: copyprop_remove_kill2
|
||||
body: |
|
||||
bb.0:
|
||||
%ax = COPY %di
|
||||
NOOP implicit killed %rdi
|
||||
%di = COPY %ax
|
||||
NOOP implicit %rax, implicit %rdi
|
||||
...
|
Loading…
Reference in New Issue