Clear kill flags on all used registers when sinking instructions.
authorPete Cooper <peter_cooper@apple.com>
Fri, 8 May 2015 17:54:32 +0000 (17:54 +0000)
committerPete Cooper <peter_cooper@apple.com>
Fri, 8 May 2015 17:54:32 +0000 (17:54 +0000)
The test here was sinking the AND here to a lower BB:

%vreg7<def> = ANDWri %vreg8, 0; GPR32common:%vreg7,%vreg8
TBNZW %vreg8<kill>, 0, <BB#1>; GPR32common:%vreg8

which meant that vreg8 was read after it was killed.

This commit changes the code from clearing kill flags on the AND to clearing flags on all registers used by the AND.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236886 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/MachineSink.cpp
test/CodeGen/AArch64/machine-sink-kill-flags.ll [new file with mode: 0644]

index 58a9bbdb35795419d9d27afe8866401e65d881cb..90ca25a6cef3c8e1f4d86686ed4f43bd4c437ea8 100644 (file)
@@ -756,7 +756,13 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {
 
   // Conservatively, clear any kill flags, since it's possible that they are no
   // longer correct.
-  MI->clearKillInfo();
+  // Note that we have to clear the kill flags for any register this instruction
+  // uses as we may sink over another instruction which currently kills the
+  // used registers.
+  for (MachineOperand &MO : MI->operands()) {
+    if (MO.isReg() && MO.isUse())
+      MRI->clearKillFlags(MO.getReg());
+  }
 
   return true;
 }
diff --git a/test/CodeGen/AArch64/machine-sink-kill-flags.ll b/test/CodeGen/AArch64/machine-sink-kill-flags.ll
new file mode 100644 (file)
index 0000000..590e169
--- /dev/null
@@ -0,0 +1,29 @@
+; RUN: llc %s -o - -fast-isel=true -O1 -verify-machineinstrs | FileCheck %s
+
+target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+target triple = "arm64-apple-ios8.0.0"
+
+; The machine verifier was asserting on this test because the AND instruction was
+; sunk below the test which killed %tmp340.
+; The kill flags on the test had to be cleared because the AND was going to read
+; registers in a BB after the test instruction.
+
+; CHECK: %bb343
+; CHECK: and
+
+define i32 @test(i32* %ptr) {
+bb:
+  br label %.thread
+
+.thread:                                          ; preds = %.thread, %bb
+  %loc = phi i32 [ %next_iter, %.thread ], [ 0, %bb ]
+  %next_iter = lshr i32 %loc, 1
+  %tmp340 = sub i32 %loc, 1
+  %tmp341 = and i32 %tmp340, 1
+  %tmp342 = icmp eq i32 %tmp341, 0
+  br i1 %tmp342, label %bb343, label %.thread
+
+bb343:                                            ; preds = %.thread
+  store i32 %tmp341, i32* %ptr, align 4
+  ret i32 -1
+}