diff options
Diffstat (limited to 'test/Transforms/Inline/frameescape.ll')
-rw-r--r-- | test/Transforms/Inline/frameescape.ll | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/test/Transforms/Inline/frameescape.ll b/test/Transforms/Inline/frameescape.ll new file mode 100644 index 0000000..fb33602 --- /dev/null +++ b/test/Transforms/Inline/frameescape.ll @@ -0,0 +1,44 @@ +; RUN: opt -inline -S < %s | FileCheck %s + +; PR23216: We can't inline functions using llvm.frameescape. + +declare void @llvm.frameescape(...) +declare i8* @llvm.frameaddress(i32) +declare i8* @llvm.framerecover(i8*, i8*, i32) + +define internal void @foo(i8* %fp) { + %a.i8 = call i8* @llvm.framerecover(i8* bitcast (i32 ()* @bar to i8*), i8* %fp, i32 0) + %a = bitcast i8* %a.i8 to i32* + store i32 42, i32* %a + ret void +} + +define internal i32 @bar() { +entry: + %a = alloca i32 + call void (...) @llvm.frameescape(i32* %a) + %fp = call i8* @llvm.frameaddress(i32 0) + tail call void @foo(i8* %fp) + %r = load i32, i32* %a + ret i32 %r +} + +; We even bail when someone marks it alwaysinline. +define internal i32 @bar_alwaysinline() alwaysinline { +entry: + %a = alloca i32 + call void (...) @llvm.frameescape(i32* %a) + tail call void @foo(i8* null) + ret i32 0 +} + +define i32 @bazz() { +entry: + %r = tail call i32 @bar() + %r1 = tail call i32 @bar_alwaysinline() + ret i32 %r +} + +; CHECK: define i32 @bazz() +; CHECK: call i32 @bar() +; CHECK: call i32 @bar_alwaysinline() |