1*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck %s --check-prefix=X64 2*9880d681SAndroid Build Coastguard Worker; RUN: llc -mtriple=i686-windows-msvc < %s | FileCheck %s --check-prefix=X86 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Workerdeclare i8* @llvm.frameaddress(i32) 5*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.localescape(...) 6*9880d681SAndroid Build Coastguard Workerdeclare i8* @llvm.localaddress() 7*9880d681SAndroid Build Coastguard Workerdeclare i8* @llvm.localrecover(i8*, i8*, i32) 8*9880d681SAndroid Build Coastguard Workerdeclare i32 @printf(i8*, ...) 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Worker@str = internal constant [10 x i8] c"asdf: %d\0A\00" 11*9880d681SAndroid Build Coastguard Worker 12*9880d681SAndroid Build Coastguard Workerdefine void @print_framealloc_from_fp(i8* %fp) { 13*9880d681SAndroid Build Coastguard Worker %a.i8 = call i8* @llvm.localrecover(i8* bitcast (void(i32)* @alloc_func to i8*), i8* %fp, i32 0) 14*9880d681SAndroid Build Coastguard Worker %a = bitcast i8* %a.i8 to i32* 15*9880d681SAndroid Build Coastguard Worker %a.val = load i32, i32* %a 16*9880d681SAndroid Build Coastguard Worker call i32 (i8*, ...) @printf(i8* getelementptr ([10 x i8], [10 x i8]* @str, i32 0, i32 0), i32 %a.val) 17*9880d681SAndroid Build Coastguard Worker %b.i8 = call i8* @llvm.localrecover(i8* bitcast (void(i32)* @alloc_func to i8*), i8* %fp, i32 1) 18*9880d681SAndroid Build Coastguard Worker %b = bitcast i8* %b.i8 to i32* 19*9880d681SAndroid Build Coastguard Worker %b.val = load i32, i32* %b 20*9880d681SAndroid Build Coastguard Worker call i32 (i8*, ...) @printf(i8* getelementptr ([10 x i8], [10 x i8]* @str, i32 0, i32 0), i32 %b.val) 21*9880d681SAndroid Build Coastguard Worker store i32 42, i32* %b 22*9880d681SAndroid Build Coastguard Worker %b2 = getelementptr i32, i32* %b, i32 1 23*9880d681SAndroid Build Coastguard Worker %b2.val = load i32, i32* %b2 24*9880d681SAndroid Build Coastguard Worker call i32 (i8*, ...) @printf(i8* getelementptr ([10 x i8], [10 x i8]* @str, i32 0, i32 0), i32 %b2.val) 25*9880d681SAndroid Build Coastguard Worker ret void 26*9880d681SAndroid Build Coastguard Worker} 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard Worker; X64-LABEL: print_framealloc_from_fp: 29*9880d681SAndroid Build Coastguard Worker; X64: movq %rcx, %[[parent_fp:[a-z]+]] 30*9880d681SAndroid Build Coastguard Worker; X64: movl .Lalloc_func$frame_escape_0(%[[parent_fp]]), %edx 31*9880d681SAndroid Build Coastguard Worker; X64: leaq {{.*}}(%rip), %[[str:[a-z]+]] 32*9880d681SAndroid Build Coastguard Worker; X64: movq %[[str]], %rcx 33*9880d681SAndroid Build Coastguard Worker; X64: callq printf 34*9880d681SAndroid Build Coastguard Worker; X64: movl .Lalloc_func$frame_escape_1(%[[parent_fp]]), %edx 35*9880d681SAndroid Build Coastguard Worker; X64: movq %[[str]], %rcx 36*9880d681SAndroid Build Coastguard Worker; X64: callq printf 37*9880d681SAndroid Build Coastguard Worker; X64: movl $42, .Lalloc_func$frame_escape_1(%[[parent_fp]]) 38*9880d681SAndroid Build Coastguard Worker; X64: retq 39*9880d681SAndroid Build Coastguard Worker 40*9880d681SAndroid Build Coastguard Worker; X86-LABEL: print_framealloc_from_fp: 41*9880d681SAndroid Build Coastguard Worker; X86: pushl %esi 42*9880d681SAndroid Build Coastguard Worker; X86: movl 8(%esp), %esi 43*9880d681SAndroid Build Coastguard Worker; X86: pushl Lalloc_func$frame_escape_0(%esi) 44*9880d681SAndroid Build Coastguard Worker; X86: pushl $_str 45*9880d681SAndroid Build Coastguard Worker; X86: calll _printf 46*9880d681SAndroid Build Coastguard Worker; X86: addl $8, %esp 47*9880d681SAndroid Build Coastguard Worker; X86: pushl Lalloc_func$frame_escape_1(%esi) 48*9880d681SAndroid Build Coastguard Worker; X86: pushl $_str 49*9880d681SAndroid Build Coastguard Worker; X86: calll _printf 50*9880d681SAndroid Build Coastguard Worker; X86: addl $8, %esp 51*9880d681SAndroid Build Coastguard Worker; X86: movl $42, Lalloc_func$frame_escape_1(%esi) 52*9880d681SAndroid Build Coastguard Worker; X86: movl $4, %eax 53*9880d681SAndroid Build Coastguard Worker; X86: pushl Lalloc_func$frame_escape_1(%esi,%eax) 54*9880d681SAndroid Build Coastguard Worker; X86: pushl $_str 55*9880d681SAndroid Build Coastguard Worker; X86: calll _printf 56*9880d681SAndroid Build Coastguard Worker; X86: addl $8, %esp 57*9880d681SAndroid Build Coastguard Worker; X86: popl %esi 58*9880d681SAndroid Build Coastguard Worker; X86: retl 59*9880d681SAndroid Build Coastguard Worker 60*9880d681SAndroid Build Coastguard Workerdefine void @alloc_func(i32 %n) { 61*9880d681SAndroid Build Coastguard Worker %a = alloca i32 62*9880d681SAndroid Build Coastguard Worker %b = alloca i32, i32 2 63*9880d681SAndroid Build Coastguard Worker call void (...) @llvm.localescape(i32* %a, i32* %b) 64*9880d681SAndroid Build Coastguard Worker store i32 42, i32* %a 65*9880d681SAndroid Build Coastguard Worker store i32 13, i32* %b 66*9880d681SAndroid Build Coastguard Worker 67*9880d681SAndroid Build Coastguard Worker ; Force usage of EBP with a dynamic alloca. 68*9880d681SAndroid Build Coastguard Worker alloca i8, i32 %n 69*9880d681SAndroid Build Coastguard Worker 70*9880d681SAndroid Build Coastguard Worker %lp = call i8* @llvm.localaddress() 71*9880d681SAndroid Build Coastguard Worker call void @print_framealloc_from_fp(i8* %lp) 72*9880d681SAndroid Build Coastguard Worker ret void 73*9880d681SAndroid Build Coastguard Worker} 74*9880d681SAndroid Build Coastguard Worker 75*9880d681SAndroid Build Coastguard Worker; X64-LABEL: alloc_func: 76*9880d681SAndroid Build Coastguard Worker; X64: pushq %rbp 77*9880d681SAndroid Build Coastguard Worker; X64: subq $16, %rsp 78*9880d681SAndroid Build Coastguard Worker; X64: .seh_stackalloc 16 79*9880d681SAndroid Build Coastguard Worker; X64: leaq 16(%rsp), %rbp 80*9880d681SAndroid Build Coastguard Worker; X64: .seh_setframe 5, 16 81*9880d681SAndroid Build Coastguard Worker; X64: .Lalloc_func$frame_escape_0 = -4 82*9880d681SAndroid Build Coastguard Worker; X64: .Lalloc_func$frame_escape_1 = -12 83*9880d681SAndroid Build Coastguard Worker; X64: movl $42, -4(%rbp) 84*9880d681SAndroid Build Coastguard Worker; X64: movl $13, -12(%rbp) 85*9880d681SAndroid Build Coastguard Worker; X64: movq %rbp, %rcx 86*9880d681SAndroid Build Coastguard Worker; X64: callq print_framealloc_from_fp 87*9880d681SAndroid Build Coastguard Worker; X64: retq 88*9880d681SAndroid Build Coastguard Worker 89*9880d681SAndroid Build Coastguard Worker; X86-LABEL: alloc_func: 90*9880d681SAndroid Build Coastguard Worker; X86: pushl %ebp 91*9880d681SAndroid Build Coastguard Worker; X86: movl %esp, %ebp 92*9880d681SAndroid Build Coastguard Worker; X86: subl $12, %esp 93*9880d681SAndroid Build Coastguard Worker; X86: Lalloc_func$frame_escape_0 = -4 94*9880d681SAndroid Build Coastguard Worker; X86: Lalloc_func$frame_escape_1 = -12 95*9880d681SAndroid Build Coastguard Worker; X86: movl $42, -4(%ebp) 96*9880d681SAndroid Build Coastguard Worker; X86: movl $13, -12(%ebp) 97*9880d681SAndroid Build Coastguard Worker; X86: pushl %ebp 98*9880d681SAndroid Build Coastguard Worker; X86: calll _print_framealloc_from_fp 99*9880d681SAndroid Build Coastguard Worker; X86: movl %ebp, %esp 100*9880d681SAndroid Build Coastguard Worker; X86: popl %ebp 101*9880d681SAndroid Build Coastguard Worker; X86: retl 102*9880d681SAndroid Build Coastguard Worker 103*9880d681SAndroid Build Coastguard Worker; Helper to make this a complete program so it can be compiled and tested. 104*9880d681SAndroid Build Coastguard Workerdefine i32 @main() { 105*9880d681SAndroid Build Coastguard Worker call void @alloc_func(i32 3) 106*9880d681SAndroid Build Coastguard Worker ret i32 0 107*9880d681SAndroid Build Coastguard Worker} 108*9880d681SAndroid Build Coastguard Worker 109*9880d681SAndroid Build Coastguard Workerdefine void @alloc_func_no_frameaddr() { 110*9880d681SAndroid Build Coastguard Worker %a = alloca i32 111*9880d681SAndroid Build Coastguard Worker %b = alloca i32 112*9880d681SAndroid Build Coastguard Worker call void (...) @llvm.localescape(i32* %a, i32* %b) 113*9880d681SAndroid Build Coastguard Worker store i32 42, i32* %a 114*9880d681SAndroid Build Coastguard Worker store i32 13, i32* %b 115*9880d681SAndroid Build Coastguard Worker call void @print_framealloc_from_fp(i8* null) 116*9880d681SAndroid Build Coastguard Worker ret void 117*9880d681SAndroid Build Coastguard Worker} 118*9880d681SAndroid Build Coastguard Worker 119*9880d681SAndroid Build Coastguard Worker; X64-LABEL: alloc_func_no_frameaddr: 120*9880d681SAndroid Build Coastguard Worker; X64: subq $40, %rsp 121*9880d681SAndroid Build Coastguard Worker; X64: .seh_stackalloc 40 122*9880d681SAndroid Build Coastguard Worker; X64: .seh_endprologue 123*9880d681SAndroid Build Coastguard Worker; X64: .Lalloc_func_no_frameaddr$frame_escape_0 = 36 124*9880d681SAndroid Build Coastguard Worker; X64: .Lalloc_func_no_frameaddr$frame_escape_1 = 32 125*9880d681SAndroid Build Coastguard Worker; X64: movl $42, 36(%rsp) 126*9880d681SAndroid Build Coastguard Worker; X64: movl $13, 32(%rsp) 127*9880d681SAndroid Build Coastguard Worker; X64: xorl %ecx, %ecx 128*9880d681SAndroid Build Coastguard Worker; X64: callq print_framealloc_from_fp 129*9880d681SAndroid Build Coastguard Worker; X64: addq $40, %rsp 130*9880d681SAndroid Build Coastguard Worker; X64: retq 131*9880d681SAndroid Build Coastguard Worker 132*9880d681SAndroid Build Coastguard Worker; X86-LABEL: alloc_func_no_frameaddr: 133*9880d681SAndroid Build Coastguard Worker; X86: subl $8, %esp 134*9880d681SAndroid Build Coastguard Worker; X86: Lalloc_func_no_frameaddr$frame_escape_0 = 4 135*9880d681SAndroid Build Coastguard Worker; X86: Lalloc_func_no_frameaddr$frame_escape_1 = 0 136*9880d681SAndroid Build Coastguard Worker; X86: movl $42, 4(%esp) 137*9880d681SAndroid Build Coastguard Worker; X86: movl $13, (%esp) 138*9880d681SAndroid Build Coastguard Worker; X86: pushl $0 139*9880d681SAndroid Build Coastguard Worker; X86: calll _print_framealloc_from_fp 140*9880d681SAndroid Build Coastguard Worker; X86: addl $12, %esp 141*9880d681SAndroid Build Coastguard Worker; X86: retl 142