aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/RegAllocLocal.cpp6
-rw-r--r--test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll12
2 files changed, 16 insertions, 2 deletions
diff --git a/lib/CodeGen/RegAllocLocal.cpp b/lib/CodeGen/RegAllocLocal.cpp
index 5ebecc3..e1cc20c 100644
--- a/lib/CodeGen/RegAllocLocal.cpp
+++ b/lib/CodeGen/RegAllocLocal.cpp
@@ -981,10 +981,12 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
}
}
- // Finally, if this is a noop copy instruction, zap it.
+ // Finally, if this is a noop copy instruction, zap it. (Except that if
+ // the copy is dead, it must be kept to avoid messing up liveness info for
+ // the register scavenger. See pr4100.)
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
if (TII->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) &&
- SrcReg == DstReg)
+ SrcReg == DstReg && DeadDefs.empty())
MBB.erase(MI);
}
diff --git a/test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll b/test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll
new file mode 100644
index 0000000..d03b7ce
--- /dev/null
+++ b/test/CodeGen/ARM/2009-05-07-RegAllocLocal.ll
@@ -0,0 +1,12 @@
+; RUN: llvm-as < %s | llc -mtriple=armv5-unknown-linux-gnueabi -O0 -regalloc=local
+; PR4100
+@.str = external constant [30 x i8] ; <[30 x i8]*> [#uses=1]
+
+define i16 @fn16(i16 %arg0.0, <2 x i16> %arg1, i16 %arg2.0) nounwind {
+entry:
+ store <2 x i16> %arg1, <2 x i16>* null
+ %0 = call i32 (i8*, ...)* @printf(i8* getelementptr ([30 x i8]* @.str, i32 0, i32 0), i32 0) nounwind ; <i32> [#uses=0]
+ ret i16 0
+}
+
+declare i32 @printf(i8*, ...) nounwind