| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| ; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck %s | ||
|
|
||
| declare i8* @llvm.frameallocate(i32) | ||
| declare i8* @llvm.frameaddress(i32) | ||
| declare i8* @llvm.recoverframeallocation(i8*, i8*) | ||
| declare i32 @printf(i8*, ...) | ||
|
|
||
| @str = internal constant [10 x i8] c"asdf: %d\0A\00" | ||
|
|
||
| define void @print_framealloc_from_fp(i8* %fp) { | ||
| %alloc = call i8* @llvm.recoverframeallocation(i8* bitcast (void(i32*, i32*)* @alloc_func to i8*), i8* %fp) | ||
| %alloc_i32 = bitcast i8* %alloc to i32* | ||
| %r = load i32* %alloc_i32 | ||
| call i32 (i8*, ...)* @printf(i8* getelementptr ([10 x i8]* @str, i32 0, i32 0), i32 %r) | ||
| ret void | ||
| } | ||
|
|
||
| ; CHECK-LABEL: print_framealloc_from_fp: | ||
| ; CHECK: movabsq $.Lframeallocation_alloc_func, %[[offs:[a-z]+]] | ||
| ; CHECK: movl (%rcx,%[[offs]]), %edx | ||
| ; CHECK: leaq {{.*}}(%rip), %rcx | ||
| ; CHECK: callq printf | ||
| ; CHECK: retq | ||
|
|
||
| define void @alloc_func(i32* %s, i32* %d) { | ||
| %alloc = call i8* @llvm.frameallocate(i32 16) | ||
| %alloc_i32 = bitcast i8* %alloc to i32* | ||
| store i32 42, i32* %alloc_i32 | ||
| %fp = call i8* @llvm.frameaddress(i32 0) | ||
| call void @print_framealloc_from_fp(i8* %fp) | ||
| ret void | ||
| } | ||
|
|
||
| ; CHECK-LABEL: alloc_func: | ||
| ; CHECK: .Lframeallocation_alloc_func = -[[offs:[0-9]+]] | ||
| ; CHECK: movl $42, -[[offs]](%rbp) | ||
| ; CHECK: movq %rbp, %rcx | ||
| ; CHECK: callq print_framealloc_from_fp | ||
| ; CHECK: retq |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| ; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s | ||
|
|
||
| declare i8* @llvm.frameallocate(i32) | ||
| declare i8* @llvm.recoverframeallocation(i8*, i8*) | ||
|
|
||
| define internal void @f() { | ||
| call i8* @llvm.frameallocate(i32 4) | ||
| call i8* @llvm.frameallocate(i32 4) | ||
| ret void | ||
| } | ||
| ; CHECK: multiple calls to llvm.frameallocate in one function | ||
|
|
||
| define internal void @f_a(i32 %n) { | ||
| call i8* @llvm.frameallocate(i32 %n) | ||
| ret void | ||
| } | ||
| ; CHECK: llvm.frameallocate argument must be constant integer size | ||
|
|
||
| define internal void @g() { | ||
| entry: | ||
| br label %not_entry | ||
| not_entry: | ||
| call i8* @llvm.frameallocate(i32 4) | ||
| ret void | ||
| } | ||
| ; CHECK: llvm.frameallocate used outside of entry block | ||
|
|
||
| define internal void @h() { | ||
| call i8* @llvm.recoverframeallocation(i8* null, i8* null) | ||
| ret void | ||
| } | ||
| ; CHECK: llvm.recoverframeallocation first argument must be function defined in this module | ||
|
|
||
| @global = constant i8 0 | ||
|
|
||
| declare void @declaration() | ||
|
|
||
| define internal void @i() { | ||
| call i8* @llvm.recoverframeallocation(i8* @global, i8* null) | ||
| ret void | ||
| } | ||
| ; CHECK: llvm.recoverframeallocation first argument must be function defined in this module | ||
|
|
||
| define internal void @j() { | ||
| call i8* @llvm.recoverframeallocation(i8* bitcast(void()* @declaration to i8*), i8* null) | ||
| ret void | ||
| } | ||
| ; CHECK: llvm.recoverframeallocation first argument must be function defined in this module |