From 0a3d49dc94760c871d053298f1033414cbf81893 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Tue, 11 Aug 2009 06:25:12 +0000 Subject: Rebuild RegScavenger::DistanceMap each time it is needed. The register scavenger maintains a DistanceMap that maps MI pointers to their distance from the top of the current MBB. The DistanceMap is built incrementally in forward() and in bulk in findFirstUse(). It is used by scavengeRegister() to determine which candidate register has the longest unused interval. Unfortunately the DistanceMap contents can become outdated. The first time scavengeRegister() is called, the DistanceMap is filled to cover the MBB. If then instructions are inserted in the MBB (as they always are following scavengeRegister()), the recorded distances are too short. This causes bad behaviour in the included test case where a register use /after/ the current position is ignored because findFirstUse() thinks is is /before/ the current position. A "using an undefined register" assertion follows promptly. The fix is to build a fresh DistanceMap at the top of scavengeRegister(), and discard it after use. This means that DistanceMap is no longer needed as a RegScavenger member variable, and forward() doesn't need to update it. The fix then discloses issue number two in the same test case: The candidate search in scavengeRegister() finds a CSR that has been saved in the prologue, but is currently unused. It would be both inefficient and wrong to spill such a register in the emergency spill slot. In the present case, the emergency slot restore is placed immediately before the normal epilogue restore, leading to a "Redefining a live register" assertion. Fix number two: When scavengerRegister() stumbles upon an unused register that is overwritten later in the MBB, return that register early. It is important to verify that the register is defined later in the MBB, otherwise it might be an unspilled CSR. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78650 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/CodeGen/Blackfin/2009-08-11-RegScavenger-CSR.ll | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 test/CodeGen/Blackfin/2009-08-11-RegScavenger-CSR.ll (limited to 'test') diff --git a/test/CodeGen/Blackfin/2009-08-11-RegScavenger-CSR.ll b/test/CodeGen/Blackfin/2009-08-11-RegScavenger-CSR.ll new file mode 100644 index 0000000..ae08f0f --- /dev/null +++ b/test/CodeGen/Blackfin/2009-08-11-RegScavenger-CSR.ll @@ -0,0 +1,17 @@ +; RUN: llvm-as < %s | llc -march=bfin -verify-machineinstrs + +declare i64 @llvm.cttz.i64(i64) nounwind readnone + +declare i16 @llvm.cttz.i16(i16) nounwind readnone + +declare i8 @llvm.cttz.i8(i8) nounwind readnone + +define void @cttztest(i8 %A, i16 %B, i32 %C, i64 %D, i8* %AP, i16* %BP, i32* %CP, i64* %DP) { + %a = call i8 @llvm.cttz.i8(i8 %A) ; [#uses=1] + %b = call i16 @llvm.cttz.i16(i16 %B) ; [#uses=1] + %d = call i64 @llvm.cttz.i64(i64 %D) ; [#uses=1] + store i8 %a, i8* %AP + store i16 %b, i16* %BP + store i64 %d, i64* %DP + ret void +} -- cgit v1.1