From eed0ff147c40aa6a1550b331c6b4bb6ed994ff25 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Mon, 3 Aug 2009 08:41:59 +0000 Subject: [PATCH] Fix a coaelescer bug. If a copy val# is extended to eliminate a non-trivially coalesced copy, and the copy kills its source register. Trim the source register's live range to the last use if possible. This fixes up kill marker to make the scavenger happy. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@77967 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SimpleRegisterCoalescing.cpp | 9 +++- .../CodeGen/Thumb2/2009-08-02-CoalescerBug.ll | 46 +++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 test/CodeGen/Thumb2/2009-08-02-CoalescerBug.ll diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp index 1ff3af92fad..a2d521b139a 100644 --- a/lib/CodeGen/SimpleRegisterCoalescing.cpp +++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp @@ -123,7 +123,8 @@ bool SimpleRegisterCoalescing::AdjustCopiesBackFrom(LiveInterval &IntA, assert(BValNo->def == CopyIdx && "Copy doesn't define the value?"); // AValNo is the value number in A that defines the copy, A3 in the example. - LiveInterval::iterator ALR = IntA.FindLiveRangeContaining(CopyIdx-1); + unsigned CopyUseIdx = li_->getUseIndex(CopyIdx); + LiveInterval::iterator ALR = IntA.FindLiveRangeContaining(CopyUseIdx); assert(ALR != IntA.end() && "Live range not found!"); VNInfo *AValNo = ALR->valno; // If it's re-defined by an early clobber somewhere in the live range, then @@ -227,6 +228,12 @@ bool SimpleRegisterCoalescing::AdjustCopiesBackFrom(LiveInterval &IntA, IntB.removeKill(ValLR->valno, FillerStart); } + // If the copy instruction was killing the destination register before the + // merge, find the last use and trim the live range. That will also add the + // isKill marker. + if (CopyMI->killsRegister(IntA.reg)) + TrimLiveIntervalToLastUse(CopyUseIdx, CopyMI->getParent(), IntA, ALR); + ++numExtends; return true; } diff --git a/test/CodeGen/Thumb2/2009-08-02-CoalescerBug.ll b/test/CodeGen/Thumb2/2009-08-02-CoalescerBug.ll new file mode 100644 index 00000000000..2f4683a43f7 --- /dev/null +++ b/test/CodeGen/Thumb2/2009-08-02-CoalescerBug.ll @@ -0,0 +1,46 @@ +; RUN: llvm-as < %s | llc -mtriple=thumbv7-apple-darwin9 -mcpu=cortex-a8 -relocation-model=pic -disable-fp-elim + + type { void (%"struct.xalanc_1_8::FormatterToXML"*, i16)*, i32 } ; type %0 + type { void (%"struct.xalanc_1_8::FormatterToXML"*, i16*)*, i32 } ; type %1 + type { void (%"struct.xalanc_1_8::FormatterToXML"*, %"struct.xalanc_1_8::XalanDOMString"*)*, i32 } ; type %2 + type { void (%"struct.xalanc_1_8::FormatterToXML"*, i16*, i32, i32)*, i32 } ; type %3 + type { void (%"struct.xalanc_1_8::FormatterToXML"*)*, i32 } ; type %4 + %"struct.std::CharVectorType" = type { %"struct.std::_Vector_base >" } + %"struct.std::_Bit_const_iterator" = type { %"struct.std::_Bit_iterator_base" } + %"struct.std::_Bit_iterator_base" = type { i32*, i32 } + %"struct.std::_Bvector_base >" = type { %"struct.std::_Bvector_base >::_Bvector_impl" } + %"struct.std::_Bvector_base >::_Bvector_impl" = type { %"struct.std::_Bit_const_iterator", %"struct.std::_Bit_const_iterator", i32* } + %"struct.std::_Vector_base >" = type { %"struct.std::_Vector_base >::_Vector_impl" } + %"struct.std::_Vector_base >::_Vector_impl" = type { i8*, i8*, i8* } + %"struct.std::_Vector_base >" = type { %"struct.std::_Vector_base >::_Vector_impl" } + %"struct.std::_Vector_base >::_Vector_impl" = type { i16*, i16*, i16* } + %"struct.std::basic_ostream >.base" = type { i32 (...)** } + %"struct.std::vector >" = type { %"struct.std::_Bvector_base >" } + %"struct.std::vector >" = type { %"struct.std::_Vector_base >" } + %"struct.xalanc_1_8::FormatterListener" = type { %"struct.std::basic_ostream >.base", %"struct.std::basic_ostream >.base"*, i32 } + %"struct.xalanc_1_8::FormatterToXML" = type { %"struct.xalanc_1_8::FormatterListener", %"struct.std::basic_ostream >.base"*, %"struct.xalanc_1_8::XalanOutputStream"*, i16, [256 x i16], [256 x i16], i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, %"struct.xalanc_1_8::XalanDOMString", %"struct.xalanc_1_8::XalanDOMString", %"struct.xalanc_1_8::XalanDOMString", i32, i32, %"struct.std::vector >", %"struct.xalanc_1_8::XalanDOMString", i8, i8, i8, i8, i8, %"struct.xalanc_1_8::XalanDOMString", %"struct.xalanc_1_8::XalanDOMString", %"struct.xalanc_1_8::XalanDOMString", %"struct.xalanc_1_8::XalanDOMString", %"struct.std::vector >", i32, %"struct.std::CharVectorType", %"struct.std::vector >", %0, %1, %2, %3, %0, %1, %2, %3, %4, i16*, i32 } + %"struct.xalanc_1_8::XalanDOMString" = type { %"struct.std::vector >", i32 } + %"struct.xalanc_1_8::XalanOutputStream" = type { i32 (...)**, i32, %"struct.std::basic_ostream >.base"*, i32, %"struct.std::vector >", %"struct.xalanc_1_8::XalanDOMString", i8, i8, %"struct.std::CharVectorType" } + +declare arm_apcscc void @_ZN10xalanc_1_814FormatterToXML17writeParentTagEndEv(%"struct.xalanc_1_8::FormatterToXML"*) + +define arm_apcscc void @_ZN10xalanc_1_814FormatterToXML5cdataEPKtj(%"struct.xalanc_1_8::FormatterToXML"* %this, i16* %ch, i32 %length) { +entry: + %0 = getelementptr %"struct.xalanc_1_8::FormatterToXML"* %this, i32 0, i32 13 ; [#uses=1] + br i1 undef, label %bb4, label %bb + +bb: ; preds = %entry + store i8 0, i8* %0, align 1 + %1 = getelementptr %"struct.xalanc_1_8::FormatterToXML"* %this, i32 0, i32 0, i32 0, i32 0 ; [#uses=1] + %2 = load i32 (...)*** %1, align 4 ; [#uses=1] + %3 = getelementptr i32 (...)** %2, i32 11 ; [#uses=1] + %4 = load i32 (...)** %3, align 4 ; [#uses=1] + %5 = bitcast i32 (...)* %4 to void (%"struct.xalanc_1_8::FormatterToXML"*, i16*, i32)* ; [#uses=1] + tail call arm_apcscc void %5(%"struct.xalanc_1_8::FormatterToXML"* %this, i16* %ch, i32 %length) + ret void + +bb4: ; preds = %entry + tail call arm_apcscc void @_ZN10xalanc_1_814FormatterToXML17writeParentTagEndEv(%"struct.xalanc_1_8::FormatterToXML"* %this) + tail call arm_apcscc void undef(%"struct.xalanc_1_8::FormatterToXML"* %this, i16* %ch, i32 0, i32 %length, i8 zeroext undef) + ret void +}