From aca625a4fe812a13c1f4718996b0460d6e4d1faf Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Wed, 24 Feb 2016 19:21:48 +0000 Subject: [PATCH] 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 --- llvm/include/llvm/CodeGen/MachineInstr.h | 4 +- llvm/lib/CodeGen/MachineInstr.cpp | 2 +- llvm/test/CodeGen/X86/machine-copy-prop.mir | 59 +++++++++++++++++++++ 3 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 llvm/test/CodeGen/X86/machine-copy-prop.mir diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h index adb560970dd3..a654d9cd5933 100644 --- a/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/llvm/include/llvm/CodeGen/MachineInstr.h @@ -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. diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp index 4103253133ec..2d685ebc5274 100644 --- a/llvm/lib/CodeGen/MachineInstr.cpp +++ b/llvm/lib/CodeGen/MachineInstr.cpp @@ -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); } } diff --git a/llvm/test/CodeGen/X86/machine-copy-prop.mir b/llvm/test/CodeGen/X86/machine-copy-prop.mir new file mode 100644 index 000000000000..85d38225a469 --- /dev/null +++ b/llvm/test/CodeGen/X86/machine-copy-prop.mir @@ -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 +...