diff --git a/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp b/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp index 8ae36db115d0..aa5cda02652a 100644 --- a/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp +++ b/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp @@ -554,6 +554,23 @@ void SimpleRegisterCoalescing::ShortenDeadCopyLiveRange(LiveInterval &li, } } +/// PropagateDeadness - Propagate the dead marker to the instruction which +/// defines the val#. +static void PropagateDeadness(LiveInterval &li, MachineInstr *CopyMI, + unsigned &LRStart, LiveIntervals *li_, + const TargetRegisterInfo* tri_) { + MachineInstr *DefMI = + li_->getInstructionFromIndex(li_->getDefIndex(LRStart)); + if (DefMI && DefMI != CopyMI) { + int DeadIdx = DefMI->findRegisterDefOperandIdx(li.reg, false, tri_); + if (DeadIdx != -1) { + DefMI->getOperand(DeadIdx).setIsDead(); + // A dead def should have a single cycle interval. + ++LRStart; + } + } +} + /// ShortenDeadCopyLiveRange - Shorten a live range as it's artificially /// extended by a dead copy. Mark the last use (if any) of the val# as kill /// as ends the live range there. If there isn't another use, then this @@ -613,23 +630,14 @@ SimpleRegisterCoalescing::ShortenDeadCopySrcLiveRange(LiveInterval &li, // Live-in to the function but dead. Remove it from entry live-in set. mf_->begin()->removeLiveIn(li.reg); } - removeRange(li, LR->start, LR->end, li_, tri_); // FIXME: Shorten intervals in BBs that reaches this BB. - } else { - // Not livein into BB. - MachineInstr *DefMI = - li_->getInstructionFromIndex(li_->getDefIndex(RemoveStart)); - if (DefMI && DefMI != CopyMI) { - int DeadIdx = DefMI->findRegisterDefOperandIdx(li.reg, false, tri_); - if (DeadIdx != -1) { - DefMI->getOperand(DeadIdx).setIsDead(); - // A dead def should have a single cycle interval. - ++RemoveStart; - } - } - removeRange(li, RemoveStart, LR->end, li_, tri_); } + if (LR->valno->def == RemoveStart) + // If the def MI defines the val#, propagate the dead marker. + PropagateDeadness(li, CopyMI, RemoveStart, li_, tri_); + + removeRange(li, RemoveStart, LR->end, li_, tri_); removeIntervalIfEmpty(li, li_, tri_); } diff --git a/llvm/test/CodeGen/PowerPC/2008-03-26-CoalescerBug.ll b/llvm/test/CodeGen/PowerPC/2008-03-26-CoalescerBug.ll new file mode 100644 index 000000000000..0b748d20b7ca --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/2008-03-26-CoalescerBug.ll @@ -0,0 +1,28 @@ +; RUN: llvm-as < %s | llc -mtriple=powerpc-apple-darwin + +define i32 @t(i64 %byteStart, i32 %activeIndex) nounwind { +entry: + %tmp50 = load i32* null, align 4 ; [#uses=1] + %tmp5051 = zext i32 %tmp50 to i64 ; [#uses=3] + %tmp53 = udiv i64 %byteStart, %tmp5051 ; [#uses=1] + %tmp5354 = trunc i64 %tmp53 to i32 ; [#uses=1] + %tmp62 = urem i64 %byteStart, %tmp5051 ; [#uses=1] + %tmp94 = add i32 0, 1 ; [#uses=1] + %tmp100 = urem i32 %tmp94, 0 ; [#uses=2] + %tmp108 = add i32 0, %activeIndex ; [#uses=1] + %tmp110 = sub i32 %tmp108, 0 ; [#uses=1] + %tmp112 = urem i32 %tmp110, 0 ; [#uses=2] + %tmp122 = icmp ult i32 %tmp112, %tmp100 ; [#uses=1] + %iftmp.175.0 = select i1 %tmp122, i32 %tmp112, i32 %tmp100 ; [#uses=1] + %tmp119 = add i32 %tmp5354, 0 ; [#uses=1] + %tmp131 = add i32 %tmp119, %iftmp.175.0 ; [#uses=1] + %tmp131132 = zext i32 %tmp131 to i64 ; [#uses=1] + %tmp147 = mul i64 %tmp131132, %tmp5051 ; [#uses=1] + br i1 false, label %bb164, label %bb190 +bb164: ; preds = %entry + %tmp171172 = and i64 %tmp62, 4294967295 ; [#uses=1] + %tmp173 = add i64 %tmp171172, %tmp147 ; [#uses=0] + ret i32 0 +bb190: ; preds = %entry + ret i32 0 +}