[llvm] r235647 - [MachineCopyPropagation] Handle undef flags conservatively so that we do not

Quentin Colombet qcolombet at apple.com
Thu Apr 23 14:17:39 PDT 2015


Author: qcolombet
Date: Thu Apr 23 16:17:39 2015
New Revision: 235647

URL: http://llvm.org/viewvc/llvm-project?rev=235647&view=rev
Log:
[MachineCopyPropagation] Handle undef flags conservatively so that we do not
remove copies that are useful after breaking some hardware dependencies.
In other words, handle this kind of situations conservatively by assuming reg2
is redefined by the undef flag.
reg1 = copy reg2
= inst reg2<undef>
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<undef>
reg2 = copy reg1

This fixes PR21743.

Added:
    llvm/trunk/test/CodeGen/X86/copy-propagation.ll
Modified:
    llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp

Modified: llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp?rev=235647&r1=235646&r2=235647&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp Thu Apr 23 16:17:39 2015
@@ -252,7 +252,11 @@ bool MachineCopyPropagation::CopyPropaga
         report_fatal_error("MachineCopyPropagation should be run after"
                            " register allocation!");
 
-      if (MO.isDef()) {
+      // Treat undef use like defs.
+      // 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.isDef() || MO.isUndef()) {
         Defs.push_back(Reg);
         continue;
       }

Added: llvm/trunk/test/CodeGen/X86/copy-propagation.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/copy-propagation.ll?rev=235647&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/copy-propagation.ll (added)
+++ llvm/trunk/test/CodeGen/X86/copy-propagation.ll Thu Apr 23 16:17:39 2015
@@ -0,0 +1,44 @@
+; RUN: llc %s -mattr=+avx -o - | FileCheck %s
+; 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<undef>
+; 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<undef>
+; reg2 = copy reg1
+; Therefore, removing the last copy is wrong.
+;
+; 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.
+; CHECK-NEXT: 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) {
+top:
+  %tmp = call double inttoptr (i64 339752784 to double (double, double)*)(double 1.000000e+00, double 0.000000e+00)
+  %tmp1 = sitofp i64 %arg to double
+  call void inttoptr (i64 339772768 to void (double, double)*)(double %tmp, double %tmp1)
+  %tmp3 = fadd double %tmp1, %tmp
+  ret double %tmp3
+}





More information about the llvm-commits mailing list