1; RUN: llc < %s -mtriple=i386-apple-darwin | FileCheck %s
2
3; There should be no stack manipulations between the inline asm and ret.
4; CHECK: test1
5; CHECK: InlineAsm End
6; CHECK-NEXT: ret
7define x86_fp80 @test1() {
8        %tmp85 = call x86_fp80 asm sideeffect "fld0", "={st(0)}"()
9        ret x86_fp80 %tmp85
10}
11
12; CHECK: test2
13; CHECK: InlineAsm End
14; CHECK-NEXT: ret
15define double @test2() {
16        %tmp85 = call double asm sideeffect "fld0", "={st(0)}"()
17        ret double %tmp85
18}
19
20; Setting up argument in st(0) should be a single fld.
21; CHECK: test3
22; CHECK: fld
23; CHECK-NEXT: InlineAsm Start
24; Asm consumes stack, nothing should be popped.
25; CHECK: InlineAsm End
26; CHECK-NOT: fstp
27; CHECK: ret
28define void @test3(x86_fp80 %X) {
29        call void asm sideeffect "frob ", "{st(0)},~{dirflag},~{fpsr},~{flags}"( x86_fp80 %X)
30        ret void
31}
32
33; CHECK: test4
34; CHECK: fld
35; CHECK-NEXT: InlineAsm Start
36; CHECK: InlineAsm End
37; CHECK-NOT: fstp
38; CHECK: ret
39define void @test4(double %X) {
40        call void asm sideeffect "frob ", "{st(0)},~{dirflag},~{fpsr},~{flags}"( double %X)
41        ret void
42}
43
44; Same as test3/4, but using value from fadd.
45; The fadd can be done in xmm or x87 regs - we don't test that.
46; CHECK: test5
47; CHECK: InlineAsm End
48; CHECK-NOT: fstp
49; CHECK: ret
50define void @test5(double %X) {
51        %Y = fadd double %X, 123.0
52        call void asm sideeffect "frob ", "{st(0)},~{dirflag},~{fpsr},~{flags}"( double %Y)
53        ret void
54}
55
56; CHECK: test6
57define void @test6(double %A, double %B, double %C,
58                   double %D, double %E) nounwind  {
59entry:
60; Uses the same value twice, should have one fstp after the asm.
61; CHECK: foo
62; CHECK: InlineAsm End
63; CHECK-NEXT: fstp
64; CHECK-NOT: fstp
65	tail call void asm sideeffect "foo $0 $1", "f,f,~{dirflag},~{fpsr},~{flags}"( double %A, double %A ) nounwind
66; Uses two different values, should be in st(0)/st(1) and both be popped.
67; CHECK: bar
68; CHECK: InlineAsm End
69; CHECK-NEXT: fstp
70; CHECK-NEXT: fstp
71	tail call void asm sideeffect "bar $0 $1", "f,f,~{dirflag},~{fpsr},~{flags}"( double %B, double %C ) nounwind
72; Uses two different values, one of which isn't killed in this asm, it
73; should not be popped after the asm.
74; CHECK: baz
75; CHECK: InlineAsm End
76; CHECK-NEXT: fstp
77; CHECK-NOT: fstp
78	tail call void asm sideeffect "baz $0 $1", "f,f,~{dirflag},~{fpsr},~{flags}"( double %D, double %E ) nounwind
79; This is the last use of %D, so it should be popped after.
80; CHECK: baz
81; CHECK: InlineAsm End
82; CHECK-NEXT: fstp
83; CHECK-NOT: fstp
84; CHECK: ret
85	tail call void asm sideeffect "baz $0", "f,~{dirflag},~{fpsr},~{flags}"( double %D ) nounwind
86	ret void
87}
88
89