add test to show suboptimal load merging behavior
[oota-llvm.git] / test / CodeGen / X86 / setjmp-spills.ll
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
3
4 declare i32 @get_val()
5 declare void @use_val(i32)
6 declare i1 @setjmp()
7 declare void @longjmp()
8 declare void @personality()
9
10
11 ; Test that llc avoids reusing spill slots in functions that call
12 ; setjmp(), whether they use "call" or "invoke" for calling setjmp()
13 ; (PR18244).
14
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
20 ; spill slot.
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
33
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
38
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.
43 first:
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)
60   call void @longjmp()
61   unreachable
62 ; X86-32-NOT: movl {{.*}}, [[SPILL_SLOT]](%esp)
63 ; X86-64-NOT: movl {{.*}}, [[SPILL_SLOT]](%rsp)
64
65 second:
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)
74   ret void
75 }
76
77
78 ; This is the same as above, but using "invoke" rather than "call" to
79 ; call setjmp().
80
81 define void @setjmp_invoker() personality void ()* @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
96
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
101
102 cont:
103   br i1 %setjmp_result, label %second, label %first
104
105 lpad:
106   %lp = landingpad { i8*, i32 } cleanup
107   unreachable
108
109 first:
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)
126   call void @longjmp()
127   unreachable
128 ; X86-32-NOT: movl {{.*}}, [[SPILL_SLOT]](%esp)
129 ; X86-64-NOT: movl {{.*}}, [[SPILL_SLOT]](%rsp)
130
131 second:
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)
140   ret void
141 }