diff --git a/llvm/lib/CodeGen/MachineCopyPropagation.cpp b/llvm/lib/CodeGen/MachineCopyPropagation.cpp --- a/llvm/lib/CodeGen/MachineCopyPropagation.cpp +++ b/llvm/lib/CodeGen/MachineCopyPropagation.cpp @@ -462,7 +462,8 @@ auto PrevCopyOperands = isCopyInstr(*PrevCopy, *TII, UseCopyInstr); // Check that the existing copy uses the correct sub registers. - if (PrevCopyOperands->Destination->isDead()) + if (PrevCopyOperands->Destination->isDead() || + PrevCopyOperands->Source->isUndef()) return false; if (!isNopCopy(*PrevCopy, Src, Def, TRI, TII, UseCopyInstr)) return false; diff --git a/llvm/test/CodeGen/X86/machine-copy-prop.mir b/llvm/test/CodeGen/X86/machine-copy-prop.mir --- a/llvm/test/CodeGen/X86/machine-copy-prop.mir +++ b/llvm/test/CodeGen/X86/machine-copy-prop.mir @@ -14,6 +14,7 @@ define void @nocopyprop3() { ret void } define void @nocopyprop4() { ret void } define void @nocopyprop5() { ret void } + define void @nocopyprop6() { ret void } ... --- # The second copy is redundant and will be removed, check that we also remove @@ -213,3 +214,24 @@ $rip = COPY $rax $rip = COPY $rax ... +--- +# The copies are obviously redundant, but the earlier COPY copies from "undef". +# That copy may be lowered to a KILL instead and thus we cannot remove the +# second COPY, otherwise we risk making $rax undef. +# CHECK-LABEL: name: nocopyprop6 +# CHECK: bb.0: +# CHECK: $rax = COPY undef $rdi +# CHECK-NEXT: NOOP implicit killed $rax +# CHECK-NEXT: $rax = COPY $rdi +# CHECK-NEXT: NOOP implicit $rax, implicit $rdi +name: nocopyprop6 +tracksRegLiveness: true +body: | + bb.0: + liveins: $rdi + + $rax = COPY undef $rdi + NOOP implicit killed $rax + $rax = COPY $rdi + NOOP implicit $rax, implicit $rdi +...