summaryrefslogtreecommitdiff
path: root/test/CodeGen/Thumb2/2010-11-22-EpilogueBug.ll
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2010-11-22 18:12:04 +0000
committerEvan Cheng <evan.cheng@apple.com>2010-11-22 18:12:04 +0000
commitab5c703fdb0b07c6d89271519fd1cca7105b3eae (patch)
tree52b8ff64598ea781f1e347405867c74989a11920 /test/CodeGen/Thumb2/2010-11-22-EpilogueBug.ll
parent4d5a29979000e1d5afc6c31239fe12d888027f4c (diff)
downloadllvm-ab5c703fdb0b07c6d89271519fd1cca7105b3eae.tar.gz
llvm-ab5c703fdb0b07c6d89271519fd1cca7105b3eae.tar.bz2
llvm-ab5c703fdb0b07c6d89271519fd1cca7105b3eae.tar.xz
Fix epilogue codegen to avoid leaving the stack pointer in an invalid
state. Previously Thumb2 would restore sp from fp like this: mov sp, r7 sub, sp, #4 If an interrupt is taken after the 'mov' but before the 'sub', callee-saved registers might be clobbered by the interrupt handler. Instead, try restoring directly from sp: add sp, #4 Or, if necessary (with VLA, etc.) use a scratch register to compute sp and then restore it: sub.w r4, r7, #8 mov sp, r7 rdar://8465407 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119977 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGen/Thumb2/2010-11-22-EpilogueBug.ll')
-rw-r--r--test/CodeGen/Thumb2/2010-11-22-EpilogueBug.ll34
1 files changed, 34 insertions, 0 deletions
diff --git a/test/CodeGen/Thumb2/2010-11-22-EpilogueBug.ll b/test/CodeGen/Thumb2/2010-11-22-EpilogueBug.ll
new file mode 100644
index 0000000000..313728c1b5
--- /dev/null
+++ b/test/CodeGen/Thumb2/2010-11-22-EpilogueBug.ll
@@ -0,0 +1,34 @@
+; rdar://8465407
+; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s
+
+%struct.buf = type opaque
+
+declare void @bar() nounwind optsize
+
+define void @foo() nounwind optsize {
+; CHECK: foo:
+; CHECK: push
+; CHECK: add r7, sp, #4
+; CHECK: sub sp, #4
+entry:
+ %m.i = alloca %struct.buf*, align 4
+ br label %bb
+
+bb:
+ br i1 undef, label %bb3, label %bb2
+
+bb2:
+ call void @bar() nounwind optsize
+ br i1 undef, label %bb, label %bb3
+
+bb3:
+ br i1 undef, label %return, label %bb
+
+return:
+; CHECK: %return
+; 'mov sp, r7' would have left sp in an invalid state
+; CHECK-NOT: mov sp, r7
+; CHECK-NOT: sub, sp, #4
+; CHECK: add sp, #4
+ ret void
+}