|  | ; RUN: llc -march=x86 < %s | FileCheck %s | 
|  | ; RUN: llc -march=x86 -O0 < %s | FileCheck %s | 
|  | ; RUN: llc -march=x86 -disable-tail-calls < %s | FileCheck %s | 
|  |  | 
|  | declare void @t1_callee(i8*) | 
|  | define void @t1(i32* %a) { | 
|  | ; CHECK-LABEL: t1: | 
|  | ; CHECK: jmp {{_?}}t1_callee | 
|  | %b = bitcast i32* %a to i8* | 
|  | musttail call void @t1_callee(i8* %b) | 
|  | ret void | 
|  | } | 
|  |  | 
|  | declare i8* @t2_callee() | 
|  | define i32* @t2() { | 
|  | ; CHECK-LABEL: t2: | 
|  | ; CHECK: jmp {{_?}}t2_callee | 
|  | %v = musttail call i8* @t2_callee() | 
|  | %w = bitcast i8* %v to i32* | 
|  | ret i32* %w | 
|  | } | 
|  |  | 
|  | ; Complex frame layout: stack realignment with dynamic alloca. | 
|  | define void @t3(i32 %n) alignstack(32) nounwind { | 
|  | entry: | 
|  | ; CHECK: t3: | 
|  | ; CHECK: pushl %ebp | 
|  | ; CHECK: pushl %esi | 
|  | ; CHECK: andl $-32, %esp | 
|  | ; CHECK: movl %esp, %esi | 
|  | ; CHECK: popl %esi | 
|  | ; CHECK: popl %ebp | 
|  | ; CHECK-NEXT: jmp {{_?}}t3_callee | 
|  | %a = alloca i8, i32 %n | 
|  | call void @capture(i8* %a) | 
|  | musttail call void @t3_callee(i32 %n) nounwind | 
|  | ret void | 
|  | } | 
|  |  | 
|  | declare void @capture(i8*) | 
|  | declare void @t3_callee(i32) | 
|  |  | 
|  | ; Test that we actually copy in and out stack arguments that aren't forwarded | 
|  | ; without modification. | 
|  | define i32 @t4({}* %fn, i32 %n, i32 %r) { | 
|  | ; CHECK-LABEL: t4: | 
|  | ; CHECK: incl %[[r:.*]] | 
|  | ; CHECK: decl %[[n:.*]] | 
|  | ; CHECK: movl %[[r]], {{[0-9]+}}(%esp) | 
|  | ; CHECK: movl %[[n]], {{[0-9]+}}(%esp) | 
|  | ; CHECK: jmpl *%{{.*}} | 
|  |  | 
|  | entry: | 
|  | %r1 = add i32 %r, 1 | 
|  | %n1 = sub i32 %n, 1 | 
|  | %fn_cast = bitcast {}* %fn to i32 ({}*, i32, i32)* | 
|  | %r2 = musttail call i32 %fn_cast({}* %fn, i32 %n1, i32 %r1) | 
|  | ret i32 %r2 | 
|  | } | 
|  |  | 
|  | ; Combine the complex stack frame with the parameter modification. | 
|  | define i32 @t5({}* %fn, i32 %n, i32 %r) alignstack(32) { | 
|  | ; CHECK-LABEL: t5: | 
|  | ; CHECK: pushl %ebp | 
|  | ; CHECK: movl %esp, %ebp | 
|  | ; CHECK: pushl %esi | 
|  | ; 	Align the stack. | 
|  | ; CHECK: andl $-32, %esp | 
|  | ; CHECK: movl %esp, %esi | 
|  | ; 	Modify the args. | 
|  | ; CHECK: incl %[[r:.*]] | 
|  | ; CHECK: decl %[[n:.*]] | 
|  | ; 	Store them through ebp, since that's the only stable arg pointer. | 
|  | ; CHECK: movl %[[r]], {{[0-9]+}}(%ebp) | 
|  | ; CHECK: movl %[[n]], {{[0-9]+}}(%ebp) | 
|  | ; 	Epilogue. | 
|  | ; CHECK: leal {{[-0-9]+}}(%ebp), %esp | 
|  | ; CHECK: popl %esi | 
|  | ; CHECK: popl %ebp | 
|  | ; CHECK: jmpl *%{{.*}} | 
|  |  | 
|  | entry: | 
|  | %a = alloca i8, i32 %n | 
|  | call void @capture(i8* %a) | 
|  | %r1 = add i32 %r, 1 | 
|  | %n1 = sub i32 %n, 1 | 
|  | %fn_cast = bitcast {}* %fn to i32 ({}*, i32, i32)* | 
|  | %r2 = musttail call i32 %fn_cast({}* %fn, i32 %n1, i32 %r1) | 
|  | ret i32 %r2 | 
|  | } |