Index: lib/CodeGen/MachineCopyPropagation.cpp =================================================================== --- lib/CodeGen/MachineCopyPropagation.cpp +++ lib/CodeGen/MachineCopyPropagation.cpp @@ -280,14 +280,6 @@ MaybeDeadCopies.remove(CI->second); } } - // Treat undef use like defs for copy propagation but not for - // dead copy. We would need to do a liveness check to be sure the copy - // is dead for undef uses. - // The backends are allowed to do whatever they want with undef value - // and we cannot be sure this register will not be rewritten to break - // some false dependencies for the hardware for instance. - if (MO.isUndef()) - Defs.push_back(Reg); } // The instruction has a register mask operand which means that it clobbers Index: test/CodeGen/ARM/machine-copyprop.mir =================================================================== --- /dev/null +++ test/CodeGen/ARM/machine-copyprop.mir @@ -0,0 +1,22 @@ +# RUN: llc -o - %s -mtriple=armv7s-- -run-pass=machine-cp | FileCheck %s +--- +# Test that machine copy prop recognizes the implicit-def operands on a COPY +# as clobbering the register. +# CHECK-LABEL: name: func +# CHECK: %d2 = VMOVv2i32 2, 14, _ +# CHECK: %s5 = COPY %s0, implicit %q1, implicit-def %q1 +# CHECK: VST1q32 %r0, 0, %q1, 14, _ +# The following two COPYs must not be removed +# CHECK: %s4 = COPY %s20, implicit-def %q1 +# CHECK: %s5 = COPY %s0, implicit killed %d0, implicit %q1, implicit-def %q1 +# CHECK: VST1q32 %r2, 0, %q1, 14, _ +name: func +body: | + bb.0: + %d2 = VMOVv2i32 2, 14, _ + %s5 = COPY %s0, implicit %q1, implicit-def %q1 + VST1q32 %r0, 0, %q1, 14, _ + %s4 = COPY %s20, implicit-def %q1 + %s5 = COPY %s0, implicit killed %d0, implicit %q1, implicit-def %q1 + VST1q32 %r2, 0, %q1, 14, _ +... Index: test/CodeGen/X86/copy-propagation.ll =================================================================== --- test/CodeGen/X86/copy-propagation.ll +++ test/CodeGen/X86/copy-propagation.ll @@ -1,37 +1,20 @@ ; RUN: llc %s -mattr=+avx -o - | FileCheck %s -; PR21743. +; Originally from http://llvm.org/PR21743. target triple = "x86_64-pc-win32-elf" -; Check that copy propagation conservatively assumes that undef register -; can be rewritten by the backend to break false dependencies for the -; hardware. -; In this function we are in this situation: -; reg1 = copy reg2 -; = inst reg2 -; reg2 = copy reg1 -; Copy propagation used to remove the last copy. -; This is incorrect because the undef flag on reg2 in inst, allows next -; passes to put whatever trashed value in reg2 that may help. -; In practice we end up with this code: -; reg1 = copy reg2 -; reg2 = 0 -; = inst reg2 -; reg2 = copy reg1 -; Therefore, removing the last copy is wrong. +; Copy propagation may remove COPYs if the result is only used by undef +; operands. ; ; CHECK-LABEL: foo: ; CHECK: movl $339752784, %e[[INDIRECT_CALL1:[a-z]+]] ; CHECK: callq *%r[[INDIRECT_CALL1]] ; Copy the result in a temporary. -; Note: Technically the regalloc could have been smarter and this move not required, -; which would have hidden the bug. +; Note: Technically the regalloc could have been smarter and this move not +; required, which would have hidden the bug. ; CHECK: vmovapd %xmm0, [[TMP:%xmm[0-9]+]] -; Crush xmm0. -; CHECK-NEXT: vxorps %xmm0, %xmm0, %xmm0 ; CHECK: movl $339772768, %e[[INDIRECT_CALL2:[a-z]+]] ; Set TMP in the first argument of the second call. -; CHECK-NEXT: vmovapd [[TMP]], %xmm0 ; CHECK: callq *%r[[INDIRECT_CALL2]] ; CHECK: retq define double @foo(i64 %arg) {