From: Evan Cheng Date: Sat, 25 Apr 2009 09:25:19 +0000 (+0000) Subject: Do not share a single unknown val# for all the live ranges merged into a physical... X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=0adb527d169e1f557676fda35bc9abb735e5c912;p=oota-llvm.git Do not share a single unknown val# for all the live ranges merged into a physical sub-register live interval. When coalescer is merging in clobbered virtaul register live interval into a physical register live interval, give each virtual register val# a separate val# in the physical register live interval. Otherwise, the coalescer would have lost track of the definitions information it needs to make correct coalescing decisions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@70026 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h index 00b51a16f1e..d6f5c8484e4 100644 --- a/include/llvm/CodeGen/LiveInterval.h +++ b/include/llvm/CodeGen/LiveInterval.h @@ -213,10 +213,6 @@ namespace llvm { return VNI; } - /// getUnknownValNo - Find a value# for unknown values, if there isn't one - /// create a new one. - VNInfo *getUnknownValNo(BumpPtrAllocator &VNInfoAllocator); - /// addKill - Add a kill instruction index to the specified value /// number. static void addKill(VNInfo *VNI, unsigned KillIdx) { diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp index 68d9ad4b3e6..39d66117ad4 100644 --- a/lib/CodeGen/LiveInterval.cpp +++ b/lib/CodeGen/LiveInterval.cpp @@ -19,6 +19,7 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/LiveInterval.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Streams.h" @@ -567,20 +568,6 @@ void LiveInterval::MergeValueInAsValue(const LiveInterval &RHS, } } -VNInfo *LiveInterval::getUnknownValNo(BumpPtrAllocator &VNInfoAllocator) { - unsigned i = getNumValNums(); - if (i) { - do { - --i; - VNInfo *VNI = getValNumInfo(i); - if (VNI->def == ~0U && !VNI->copy && - !VNI->hasPHIKill && !VNI->redefByEC && VNI->kills.empty()) - return VNI; - } while (i != 0); - } - return getNextValue(~0U, 0, VNInfoAllocator); -} - /// MergeInClobberRanges - For any live ranges that are not defined in the /// current interval, but are defined in the Clobbers interval, mark them @@ -589,12 +576,19 @@ void LiveInterval::MergeInClobberRanges(const LiveInterval &Clobbers, BumpPtrAllocator &VNInfoAllocator) { if (Clobbers.empty()) return; - // Find a value # to use for the clobber ranges. If there is already a value# - // for unknown values, use it. - VNInfo *ClobberValNo = getUnknownValNo(VNInfoAllocator); - + DenseMap ValNoMaps; iterator IP = begin(); for (const_iterator I = Clobbers.begin(), E = Clobbers.end(); I != E; ++I) { + // For every val# in the Clobbers interval, create a new "unknown" val#. + VNInfo *ClobberValNo = 0; + DenseMap::iterator VI = ValNoMaps.find(I->valno); + if (VI != ValNoMaps.end()) + ClobberValNo = VI->second; + else { + ClobberValNo = getNextValue(~0U, 0, VNInfoAllocator); + ValNoMaps.insert(std::make_pair(I->valno, ClobberValNo)); + } + bool Done = false; unsigned Start = I->start, End = I->end; // If a clobber range starts before an existing range and ends after @@ -637,7 +631,7 @@ void LiveInterval::MergeInClobberRange(unsigned Start, unsigned End, BumpPtrAllocator &VNInfoAllocator) { // Find a value # to use for the clobber ranges. If there is already a value# // for unknown values, use it. - VNInfo *ClobberValNo = getUnknownValNo(VNInfoAllocator); + VNInfo *ClobberValNo = getNextValue(~0U, 0, VNInfoAllocator); iterator IP = begin(); IP = std::upper_bound(IP, end(), Start); diff --git a/test/CodeGen/X86/2009-04-25-CoalescerBug.ll b/test/CodeGen/X86/2009-04-25-CoalescerBug.ll new file mode 100644 index 00000000000..981d3277d34 --- /dev/null +++ b/test/CodeGen/X86/2009-04-25-CoalescerBug.ll @@ -0,0 +1,19 @@ +; RUN: llvm-as < %s | llc -march=x86-64 | grep mov | count 2 +; rdar://6806252 + +define i64 @test(i32* %tmp13) nounwind { +entry: + br label %while.cond + +while.cond: ; preds = %while.cond, %entry + %tmp15 = load i32* %tmp13 ; [#uses=2] + %bf.lo = lshr i32 %tmp15, 1 ; [#uses=1] + %bf.lo.cleared = and i32 %bf.lo, 2147483647 ; [#uses=1] + %conv = zext i32 %bf.lo.cleared to i64 ; [#uses=1] + %bf.lo.cleared25 = and i32 %tmp15, 1 ; [#uses=1] + %tobool = icmp ne i32 %bf.lo.cleared25, 0 ; [#uses=1] + br i1 %tobool, label %while.cond, label %while.end + +while.end: ; preds = %while.cond + ret i64 %conv +}