1 ; RUN: llc < %s -mtriple=i386-linux | FileCheck %s -check-prefix=X86-32
2 ; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s -check-prefix=X86-64
5 declare void @use_val(i32)
7 declare void @longjmp()
8 declare void @personality()
11 ; Test that llc avoids reusing spill slots in functions that call
12 ; setjmp(), whether they use "call" or "invoke" for calling setjmp()
15 define void @setjmp_caller() {
16 ; X86-32-LABEL: setjmp_caller:
17 ; X86-64-LABEL: setjmp_caller:
18 ; This code keeps enough variables live across the setjmp() call that
19 ; they don't all fit in registers and the compiler will allocate a
21 %a1 = call i32 @get_val()
22 %a2 = call i32 @get_val()
23 %a3 = call i32 @get_val()
24 %a4 = call i32 @get_val()
25 %a5 = call i32 @get_val()
26 %a6 = call i32 @get_val()
27 %a7 = call i32 @get_val()
28 %a8 = call i32 @get_val()
29 ; X86-32: movl %eax, [[SPILL_SLOT:[0-9]+]](%esp)
30 ; X86-32: calll get_val
31 ; X86-64: movl %eax, [[SPILL_SLOT:[0-9]+]](%rsp)
32 ; X86-64: callq get_val
34 %setjmp_result = call i1 @setjmp() returns_twice
35 br i1 %setjmp_result, label %second, label %first
36 ; X86-32: calll setjmp
37 ; X86-64: callq setjmp
39 ; Again, keep enough variables live that they need spill slots. Since
40 ; this function calls a returns_twice function (setjmp()), the
41 ; compiler should not reuse the spill slots. longjmp() can return to
42 ; where the first spill slots were still live.
44 %b1 = call i32 @get_val()
45 %b2 = call i32 @get_val()
46 %b3 = call i32 @get_val()
47 %b4 = call i32 @get_val()
48 %b5 = call i32 @get_val()
49 %b6 = call i32 @get_val()
50 %b7 = call i32 @get_val()
51 %b8 = call i32 @get_val()
52 call void @use_val(i32 %b1)
53 call void @use_val(i32 %b2)
54 call void @use_val(i32 %b3)
55 call void @use_val(i32 %b4)
56 call void @use_val(i32 %b5)
57 call void @use_val(i32 %b6)
58 call void @use_val(i32 %b7)
59 call void @use_val(i32 %b8)
62 ; X86-32-NOT: movl {{.*}}, [[SPILL_SLOT]](%esp)
63 ; X86-64-NOT: movl {{.*}}, [[SPILL_SLOT]](%rsp)
66 call void @use_val(i32 %a1)
67 call void @use_val(i32 %a2)
68 call void @use_val(i32 %a3)
69 call void @use_val(i32 %a4)
70 call void @use_val(i32 %a5)
71 call void @use_val(i32 %a6)
72 call void @use_val(i32 %a7)
73 call void @use_val(i32 %a8)
78 ; This is the same as above, but using "invoke" rather than "call" to
81 define void @setjmp_invoker() personality ptr @personality {
82 ; X86-32-LABEL: setjmp_invoker:
83 ; X86-64-LABEL: setjmp_invoker:
84 %a1 = call i32 @get_val()
85 %a2 = call i32 @get_val()
86 %a3 = call i32 @get_val()
87 %a4 = call i32 @get_val()
88 %a5 = call i32 @get_val()
89 %a6 = call i32 @get_val()
90 %a7 = call i32 @get_val()
91 %a8 = call i32 @get_val()
92 ; X86-32: movl %eax, [[SPILL_SLOT:[0-9]+]](%esp)
93 ; X86-32: calll get_val
94 ; X86-64: movl %eax, [[SPILL_SLOT:[0-9]+]](%rsp)
95 ; X86-64: callq get_val
97 %setjmp_result = invoke i1 @setjmp() returns_twice
98 to label %cont unwind label %lpad
99 ; X86-32: calll setjmp
100 ; X86-64: callq setjmp
103 br i1 %setjmp_result, label %second, label %first
106 %lp = landingpad { ptr, i32 } cleanup
110 %b1 = call i32 @get_val()
111 %b2 = call i32 @get_val()
112 %b3 = call i32 @get_val()
113 %b4 = call i32 @get_val()
114 %b5 = call i32 @get_val()
115 %b6 = call i32 @get_val()
116 %b7 = call i32 @get_val()
117 %b8 = call i32 @get_val()
118 call void @use_val(i32 %b1)
119 call void @use_val(i32 %b2)
120 call void @use_val(i32 %b3)
121 call void @use_val(i32 %b4)
122 call void @use_val(i32 %b5)
123 call void @use_val(i32 %b6)
124 call void @use_val(i32 %b7)
125 call void @use_val(i32 %b8)
128 ; X86-32-NOT: movl {{.*}}, [[SPILL_SLOT]](%esp)
129 ; X86-64-NOT: movl {{.*}}, [[SPILL_SLOT]](%rsp)
132 call void @use_val(i32 %a1)
133 call void @use_val(i32 %a2)
134 call void @use_val(i32 %a3)
135 call void @use_val(i32 %a4)
136 call void @use_val(i32 %a5)
137 call void @use_val(i32 %a6)
138 call void @use_val(i32 %a7)
139 call void @use_val(i32 %a8)