From ed70cbb3f367bc0f77d34d22163abbe4879526bc Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Wed, 26 Mar 2008 19:03:01 +0000 Subject: [PATCH] Avoid commuting a def MI in order to coalesce a copy instruction away if any use of the same val# is a copy instruction that has already been coalesced. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48833 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SimpleRegisterCoalescing.cpp | 14 +++++- lib/CodeGen/VirtRegMap.cpp | 1 + test/CodeGen/X86/2007-03-26-CoalescerBug.ll | 49 +++++++++++++++++++++ 3 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 test/CodeGen/X86/2007-03-26-CoalescerBug.ll diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp index 870fcc44080..8ae36db115d 100644 --- a/lib/CodeGen/SimpleRegisterCoalescing.cpp +++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp @@ -283,6 +283,17 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA, if (HasOtherReachingDefs(IntA, IntB, AValNo, BValNo)) return false; + // If some of the uses of IntA.reg is already coalesced away, return false. + // It's not possible to determine whether it's safe to perform the coalescing. + for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(IntA.reg), + UE = mri_->use_end(); UI != UE; ++UI) { + MachineInstr *UseMI = &*UI; + unsigned UseIdx = li_->getInstructionIndex(UseMI); + LiveInterval::iterator ULR = IntA.FindLiveRangeContaining(UseIdx); + if (ULR->valno == AValNo && JoinedCopies.count(UseMI)) + return false; + } + // At this point we have decided that it is legal to do this // transformation. Start by commuting the instruction. MachineBasicBlock *MBB = DefMI->getParent(); @@ -323,8 +334,7 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(LiveInterval &IntA, MachineInstr *UseMI = &*UI; ++UI; if (JoinedCopies.count(UseMI)) - // It'll no longer be "joined" after the change. - JoinedCopies.erase(UseMI); + continue; unsigned UseIdx = li_->getInstructionIndex(UseMI); LiveInterval::iterator ULR = IntA.FindLiveRangeContaining(UseIdx); if (ULR->valno != AValNo) diff --git a/lib/CodeGen/VirtRegMap.cpp b/lib/CodeGen/VirtRegMap.cpp index f89ef9a8b5d..264ab145693 100644 --- a/lib/CodeGen/VirtRegMap.cpp +++ b/lib/CodeGen/VirtRegMap.cpp @@ -1593,6 +1593,7 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) { } } + assert(PhysReg && "VR not assigned a physical register?"); RegInfo->setPhysRegUsed(PhysReg); unsigned RReg = SubIdx ? TRI->getSubReg(PhysReg, SubIdx) : PhysReg; ReusedOperands.markClobbered(RReg); diff --git a/test/CodeGen/X86/2007-03-26-CoalescerBug.ll b/test/CodeGen/X86/2007-03-26-CoalescerBug.ll new file mode 100644 index 00000000000..7ce0584c545 --- /dev/null +++ b/test/CodeGen/X86/2007-03-26-CoalescerBug.ll @@ -0,0 +1,49 @@ +; RUN: llvm-as < %s | llc -march=x86 + +@data = external global [339 x i64] + +define void @foo(...) { +bb1: + %t43 = load i64* getelementptr ([339 x i64]* @data, i32 0, i64 212), align 4 + br i1 false, label %bb80, label %bb6 +bb6: + br i1 false, label %bb38, label %bb265 +bb265: + ret void +bb38: + br i1 false, label %bb80, label %bb49 +bb80: + br i1 false, label %bb146, label %bb268 +bb49: + ret void +bb113: + ret void +bb268: + %t1062 = shl i64 %t43, 3 + %t1066 = shl i64 0, 3 + br label %bb85 +bb85: + %t1025 = phi i64 [ 0, %bb268 ], [ %t102.0, %bb234 ] + %t1028 = phi i64 [ 0, %bb268 ], [ %t1066, %bb234 ] + %t1031 = phi i64 [ 0, %bb268 ], [ %t103.0, %bb234 ] + %t1034 = phi i64 [ 0, %bb268 ], [ %t1066, %bb234 ] + %t102.0 = add i64 %t1028, %t1025 + %t103.0 = add i64 %t1034, %t1031 + br label %bb86 +bb86: + %t108.0 = phi i64 [ %t102.0, %bb85 ], [ %t1139, %bb248 ] + %t110.0 = phi i64 [ %t103.0, %bb85 ], [ %t1142, %bb248 ] + br label %bb193 +bb193: + %t1081 = add i64 %t110.0, -8 + %t1087 = add i64 %t108.0, -8 + br i1 false, label %bb193, label %bb248 +bb248: + %t1139 = add i64 %t108.0, %t1062 + %t1142 = add i64 %t110.0, %t1062 + br i1 false, label %bb86, label %bb234 +bb234: + br i1 false, label %bb85, label %bb113 +bb146: + ret void +} -- 2.34.1