diff --git a/lib/CodeGen/MachineSink.cpp b/lib/CodeGen/MachineSink.cpp index 58a9bbdb357..90ca25a6cef 100644 --- a/lib/CodeGen/MachineSink.cpp +++ b/lib/CodeGen/MachineSink.cpp @@ -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 index 00000000000..590e1692ef8 --- /dev/null +++ b/test/CodeGen/AArch64/machine-sink-kill-flags.ll @@ -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 +}