1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
2 ; RUN: llc -mtriple=x86_64-apple-darwin10.6 < %s | FileCheck %s
3 ; RUN: llc -mtriple=x86_64-linux < %s | FileCheck %s --check-prefix=NOCOMPACTUNWIND
5 ; Note: This test cannot be merged with the shrink-wrapping tests
6 ; because the booleans set on the command line take precedence on
7 ; the target logic that disable shrink-wrapping.
9 ; The current compact unwind scheme does not work when the prologue is not at
10 ; the start (the instructions before the prologue cannot be described).
11 ; Currently we choose to not perform shrink-wrapping for functions without FP
12 ; not marked as nounwind. PR25614
14 ; No shrink-wrapping should occur here, until the CFI information are fixed.
16 define i32 @framelessUnwind(i32 %a, i32 %b) #0 {
17 ; CHECK-LABEL: framelessUnwind:
19 ; CHECK-NEXT: pushq %rax
20 ; CHECK-NEXT: .cfi_def_cfa_offset 16
21 ; CHECK-NEXT: movl %edi, %eax
22 ; CHECK-NEXT: cmpl %esi, %edi
23 ; CHECK-NEXT: jge LBB0_2
24 ; CHECK-NEXT: ## %bb.1: ## %true
25 ; CHECK-NEXT: movl %eax, {{[0-9]+}}(%rsp)
26 ; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rsi
27 ; CHECK-NEXT: xorl %edi, %edi
28 ; CHECK-NEXT: callq _doSomething
29 ; CHECK-NEXT: LBB0_2: ## %false
30 ; CHECK-NEXT: popq %rcx
33 ; NOCOMPACTUNWIND-LABEL: framelessUnwind:
34 ; NOCOMPACTUNWIND: # %bb.0:
35 ; NOCOMPACTUNWIND-NEXT: movl %edi, %eax
36 ; NOCOMPACTUNWIND-NEXT: cmpl %esi, %edi
37 ; NOCOMPACTUNWIND-NEXT: jge .LBB0_2
38 ; NOCOMPACTUNWIND-NEXT: # %bb.1: # %true
39 ; NOCOMPACTUNWIND-NEXT: pushq %rax
40 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16
41 ; NOCOMPACTUNWIND-NEXT: movl %eax, {{[0-9]+}}(%rsp)
42 ; NOCOMPACTUNWIND-NEXT: leaq {{[0-9]+}}(%rsp), %rsi
43 ; NOCOMPACTUNWIND-NEXT: xorl %edi, %edi
44 ; NOCOMPACTUNWIND-NEXT: callq doSomething@PLT
45 ; NOCOMPACTUNWIND-NEXT: addq $8, %rsp
46 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 8
47 ; NOCOMPACTUNWIND-NEXT: .LBB0_2: # %false
48 ; NOCOMPACTUNWIND-NEXT: retq
49 %tmp = alloca i32, align 4
50 %tmp2 = icmp slt i32 %a, %b
51 br i1 %tmp2, label %true, label %false
54 store i32 %a, ptr %tmp, align 4
55 %tmp4 = call i32 @doSomething(i32 0, ptr %tmp)
59 %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
63 declare i32 @doSomething(i32, ptr)
65 attributes #0 = { "frame-pointer"="none" }
67 ; Shrink-wrapping should occur here. We have a frame pointer.
68 define i32 @frameUnwind(i32 %a, i32 %b) #1 {
69 ; CHECK-LABEL: frameUnwind:
71 ; CHECK-NEXT: movl %edi, %eax
72 ; CHECK-NEXT: cmpl %esi, %edi
73 ; CHECK-NEXT: jge LBB1_2
74 ; CHECK-NEXT: ## %bb.1: ## %true
75 ; CHECK-NEXT: pushq %rbp
76 ; CHECK-NEXT: .cfi_def_cfa_offset 16
77 ; CHECK-NEXT: .cfi_offset %rbp, -16
78 ; CHECK-NEXT: movq %rsp, %rbp
79 ; CHECK-NEXT: .cfi_def_cfa_register %rbp
80 ; CHECK-NEXT: subq $16, %rsp
81 ; CHECK-NEXT: movl %eax, -4(%rbp)
82 ; CHECK-NEXT: leaq -4(%rbp), %rsi
83 ; CHECK-NEXT: xorl %edi, %edi
84 ; CHECK-NEXT: callq _doSomething
85 ; CHECK-NEXT: addq $16, %rsp
86 ; CHECK-NEXT: popq %rbp
87 ; CHECK-NEXT: LBB1_2: ## %false
90 ; NOCOMPACTUNWIND-LABEL: frameUnwind:
91 ; NOCOMPACTUNWIND: # %bb.0:
92 ; NOCOMPACTUNWIND-NEXT: movl %edi, %eax
93 ; NOCOMPACTUNWIND-NEXT: cmpl %esi, %edi
94 ; NOCOMPACTUNWIND-NEXT: jge .LBB1_2
95 ; NOCOMPACTUNWIND-NEXT: # %bb.1: # %true
96 ; NOCOMPACTUNWIND-NEXT: pushq %rbp
97 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16
98 ; NOCOMPACTUNWIND-NEXT: .cfi_offset %rbp, -16
99 ; NOCOMPACTUNWIND-NEXT: movq %rsp, %rbp
100 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_register %rbp
101 ; NOCOMPACTUNWIND-NEXT: subq $16, %rsp
102 ; NOCOMPACTUNWIND-NEXT: movl %eax, -4(%rbp)
103 ; NOCOMPACTUNWIND-NEXT: leaq -4(%rbp), %rsi
104 ; NOCOMPACTUNWIND-NEXT: xorl %edi, %edi
105 ; NOCOMPACTUNWIND-NEXT: callq doSomething@PLT
106 ; NOCOMPACTUNWIND-NEXT: addq $16, %rsp
107 ; NOCOMPACTUNWIND-NEXT: popq %rbp
108 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa %rsp, 8
109 ; NOCOMPACTUNWIND-NEXT: .cfi_restore %rbp
110 ; NOCOMPACTUNWIND-NEXT: .LBB1_2: # %false
111 ; NOCOMPACTUNWIND-NEXT: retq
112 %tmp = alloca i32, align 4
113 %tmp2 = icmp slt i32 %a, %b
114 br i1 %tmp2, label %true, label %false
117 store i32 %a, ptr %tmp, align 4
118 %tmp4 = call i32 @doSomething(i32 0, ptr %tmp)
122 %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
126 attributes #1 = { "frame-pointer"="all" }
128 ; Shrink-wrapping should occur here. We do not have to unwind.
129 define i32 @framelessnoUnwind(i32 %a, i32 %b) #2 {
130 ; CHECK-LABEL: framelessnoUnwind:
132 ; CHECK-NEXT: movl %edi, %eax
133 ; CHECK-NEXT: cmpl %esi, %edi
134 ; CHECK-NEXT: jge LBB2_2
135 ; CHECK-NEXT: ## %bb.1: ## %true
136 ; CHECK-NEXT: pushq %rax
137 ; CHECK-NEXT: movl %eax, {{[0-9]+}}(%rsp)
138 ; CHECK-NEXT: leaq {{[0-9]+}}(%rsp), %rsi
139 ; CHECK-NEXT: xorl %edi, %edi
140 ; CHECK-NEXT: callq _doSomething
141 ; CHECK-NEXT: addq $8, %rsp
142 ; CHECK-NEXT: LBB2_2: ## %false
145 ; NOCOMPACTUNWIND-LABEL: framelessnoUnwind:
146 ; NOCOMPACTUNWIND: # %bb.0:
147 ; NOCOMPACTUNWIND-NEXT: movl %edi, %eax
148 ; NOCOMPACTUNWIND-NEXT: cmpl %esi, %edi
149 ; NOCOMPACTUNWIND-NEXT: jge .LBB2_2
150 ; NOCOMPACTUNWIND-NEXT: # %bb.1: # %true
151 ; NOCOMPACTUNWIND-NEXT: pushq %rax
152 ; NOCOMPACTUNWIND-NEXT: movl %eax, {{[0-9]+}}(%rsp)
153 ; NOCOMPACTUNWIND-NEXT: leaq {{[0-9]+}}(%rsp), %rsi
154 ; NOCOMPACTUNWIND-NEXT: xorl %edi, %edi
155 ; NOCOMPACTUNWIND-NEXT: callq doSomething@PLT
156 ; NOCOMPACTUNWIND-NEXT: addq $8, %rsp
157 ; NOCOMPACTUNWIND-NEXT: .LBB2_2: # %false
158 ; NOCOMPACTUNWIND-NEXT: retq
159 %tmp = alloca i32, align 4
160 %tmp2 = icmp slt i32 %a, %b
161 br i1 %tmp2, label %true, label %false
164 store i32 %a, ptr %tmp, align 4
165 %tmp4 = call i32 @doSomething(i32 0, ptr %tmp)
169 %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
173 attributes #2 = { "frame-pointer"="none" nounwind }
176 ; Check that we generate correct code for segmented stack.
177 ; We used to emit the code at the entry point of the function
178 ; instead of just before the prologue.
179 ; For now, shrink-wrapping is disabled on segmented stack functions: PR26107.
180 define zeroext i1 @segmentedStack(ptr readonly %vk1, ptr readonly %vk2, i64 %key_size) #5 {
181 ; CHECK-LABEL: segmentedStack:
183 ; CHECK-NEXT: cmpq %gs:816, %rsp
184 ; CHECK-NEXT: jbe LBB3_6
185 ; CHECK-NEXT: LBB3_1: ## %entry
186 ; CHECK-NEXT: pushq %rax
187 ; CHECK-NEXT: .cfi_def_cfa_offset 16
188 ; CHECK-NEXT: testq %rdi, %rdi
189 ; CHECK-NEXT: sete %al
190 ; CHECK-NEXT: testq %rsi, %rsi
191 ; CHECK-NEXT: sete %cl
192 ; CHECK-NEXT: orb %al, %cl
193 ; CHECK-NEXT: movq %rdi, %rax
194 ; CHECK-NEXT: orq %rsi, %rax
195 ; CHECK-NEXT: sete %al
196 ; CHECK-NEXT: testb %cl, %cl
197 ; CHECK-NEXT: jne LBB3_4
198 ; CHECK-NEXT: ## %bb.2: ## %if.end4.i
199 ; CHECK-NEXT: movq 8(%rdi), %rdx
200 ; CHECK-NEXT: cmpq 8(%rsi), %rdx
201 ; CHECK-NEXT: jne LBB3_5
202 ; CHECK-NEXT: ## %bb.3: ## %land.rhs.i.i
203 ; CHECK-NEXT: movq (%rsi), %rsi
204 ; CHECK-NEXT: movq (%rdi), %rdi
205 ; CHECK-NEXT: callq _memcmp
206 ; CHECK-NEXT: testl %eax, %eax
207 ; CHECK-NEXT: sete %al
208 ; CHECK-NEXT: LBB3_4: ## %__go_ptr_strings_equal.exit
209 ; CHECK-NEXT: ## kill: def $al killed $al killed $eax
210 ; CHECK-NEXT: popq %rcx
212 ; CHECK-NEXT: LBB3_5:
213 ; CHECK-NEXT: xorl %eax, %eax
214 ; CHECK-NEXT: ## kill: def $al killed $al killed $eax
215 ; CHECK-NEXT: popq %rcx
217 ; CHECK-NEXT: LBB3_6:
218 ; CHECK-NEXT: movl $8, %r10d
219 ; CHECK-NEXT: movl $0, %r11d
220 ; CHECK-NEXT: callq ___morestack
222 ; CHECK-NEXT: jmp LBB3_1
224 ; NOCOMPACTUNWIND-LABEL: segmentedStack:
225 ; NOCOMPACTUNWIND: # %bb.0:
226 ; NOCOMPACTUNWIND-NEXT: cmpq %fs:112, %rsp
227 ; NOCOMPACTUNWIND-NEXT: jbe .LBB3_6
228 ; NOCOMPACTUNWIND-NEXT: .LBB3_1: # %entry
229 ; NOCOMPACTUNWIND-NEXT: pushq %rax
230 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16
231 ; NOCOMPACTUNWIND-NEXT: testq %rdi, %rdi
232 ; NOCOMPACTUNWIND-NEXT: sete %al
233 ; NOCOMPACTUNWIND-NEXT: testq %rsi, %rsi
234 ; NOCOMPACTUNWIND-NEXT: sete %cl
235 ; NOCOMPACTUNWIND-NEXT: orb %al, %cl
236 ; NOCOMPACTUNWIND-NEXT: movq %rdi, %rax
237 ; NOCOMPACTUNWIND-NEXT: orq %rsi, %rax
238 ; NOCOMPACTUNWIND-NEXT: sete %al
239 ; NOCOMPACTUNWIND-NEXT: testb %cl, %cl
240 ; NOCOMPACTUNWIND-NEXT: jne .LBB3_4
241 ; NOCOMPACTUNWIND-NEXT: # %bb.2: # %if.end4.i
242 ; NOCOMPACTUNWIND-NEXT: movq 8(%rdi), %rdx
243 ; NOCOMPACTUNWIND-NEXT: cmpq 8(%rsi), %rdx
244 ; NOCOMPACTUNWIND-NEXT: jne .LBB3_5
245 ; NOCOMPACTUNWIND-NEXT: # %bb.3: # %land.rhs.i.i
246 ; NOCOMPACTUNWIND-NEXT: movq (%rsi), %rsi
247 ; NOCOMPACTUNWIND-NEXT: movq (%rdi), %rdi
248 ; NOCOMPACTUNWIND-NEXT: callq memcmp@PLT
249 ; NOCOMPACTUNWIND-NEXT: testl %eax, %eax
250 ; NOCOMPACTUNWIND-NEXT: sete %al
251 ; NOCOMPACTUNWIND-NEXT: .LBB3_4: # %__go_ptr_strings_equal.exit
252 ; NOCOMPACTUNWIND-NEXT: # kill: def $al killed $al killed $eax
253 ; NOCOMPACTUNWIND-NEXT: popq %rcx
254 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 8
255 ; NOCOMPACTUNWIND-NEXT: retq
256 ; NOCOMPACTUNWIND-NEXT: .LBB3_5:
257 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16
258 ; NOCOMPACTUNWIND-NEXT: xorl %eax, %eax
259 ; NOCOMPACTUNWIND-NEXT: # kill: def $al killed $al killed $eax
260 ; NOCOMPACTUNWIND-NEXT: popq %rcx
261 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 8
262 ; NOCOMPACTUNWIND-NEXT: retq
263 ; NOCOMPACTUNWIND-NEXT: .LBB3_6:
264 ; NOCOMPACTUNWIND-NEXT: movl $8, %r10d
265 ; NOCOMPACTUNWIND-NEXT: movl $0, %r11d
266 ; NOCOMPACTUNWIND-NEXT: callq __morestack
267 ; NOCOMPACTUNWIND-NEXT: retq
268 ; NOCOMPACTUNWIND-NEXT: jmp .LBB3_1
270 %cmp.i = icmp eq ptr %vk1, null
271 %cmp1.i = icmp eq ptr %vk2, null
272 %brmerge.i = or i1 %cmp.i, %cmp1.i
273 %cmp1.mux.i = and i1 %cmp.i, %cmp1.i
274 br i1 %brmerge.i, label %__go_ptr_strings_equal.exit, label %if.end4.i
276 if.end4.i: ; preds = %entry
277 %tmp = getelementptr inbounds i8, ptr %vk1, i64 8
278 %tmp2 = load i64, ptr %tmp, align 8
279 %tmp3 = getelementptr inbounds i8, ptr %vk2, i64 8
280 %tmp5 = load i64, ptr %tmp3, align 8
281 %cmp.i.i = icmp eq i64 %tmp2, %tmp5
282 br i1 %cmp.i.i, label %land.rhs.i.i, label %__go_ptr_strings_equal.exit
284 land.rhs.i.i: ; preds = %if.end4.i
285 %tmp7 = load ptr, ptr %vk2, align 8
286 %tmp9 = load ptr, ptr %vk1, align 8
287 %call.i.i = tail call i32 @memcmp(ptr %tmp9, ptr %tmp7, i64 %tmp2) #5
288 %cmp4.i.i = icmp eq i32 %call.i.i, 0
289 br label %__go_ptr_strings_equal.exit
291 __go_ptr_strings_equal.exit: ; preds = %land.rhs.i.i, %if.end4.i, %entry
292 %retval.0.i = phi i1 [ %cmp1.mux.i, %entry ], [ false, %if.end4.i ], [ %cmp4.i.i, %land.rhs.i.i ]
296 ; Function Attrs: nounwind readonly
297 declare i32 @memcmp(ptr nocapture, ptr nocapture, i64) #5
299 attributes #5 = { nounwind readonly ssp uwtable "split-stack" }
301 ; Check that correctly take into account the jumps to landing pad.
302 ; We used to consider function that may throw like regular
304 ; Therefore, in this example, we were happily inserting the epilogue
305 ; right after the call to throw_exception. Because of that we would not
306 ; execute the epilogue when an execption occur and bad things will
309 define void @with_nounwind(i1 %cond) nounwind personality ptr @my_personality {
310 ; CHECK-LABEL: with_nounwind:
311 ; CHECK: ## %bb.0: ## %entry
312 ; CHECK-NEXT: pushq %rax
313 ; CHECK-NEXT: .cfi_def_cfa_offset 16
314 ; CHECK-NEXT: testb $1, %dil
315 ; CHECK-NEXT: jne LBB4_1
316 ; CHECK-NEXT: ## %bb.4: ## %return
317 ; CHECK-NEXT: popq %rax
319 ; CHECK-NEXT: LBB4_1: ## %throw
321 ; CHECK-NEXT: callq _throw_exception
323 ; CHECK-NEXT: ## %bb.2: ## %unreachable
325 ; CHECK-NEXT: LBB4_3: ## %landing
327 ; CHECK-NEXT: popq %rax
329 ; CHECK-NEXT: Lfunc_end0:
331 ; NOCOMPACTUNWIND-LABEL: with_nounwind:
332 ; NOCOMPACTUNWIND: # %bb.0: # %entry
333 ; NOCOMPACTUNWIND-NEXT: pushq %rax
334 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16
335 ; NOCOMPACTUNWIND-NEXT: testb $1, %dil
336 ; NOCOMPACTUNWIND-NEXT: jne .LBB4_1
337 ; NOCOMPACTUNWIND-NEXT: # %bb.4: # %return
338 ; NOCOMPACTUNWIND-NEXT: popq %rax
339 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 8
340 ; NOCOMPACTUNWIND-NEXT: retq
341 ; NOCOMPACTUNWIND-NEXT: .LBB4_1: # %throw
342 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16
343 ; NOCOMPACTUNWIND-NEXT: .Ltmp0:
344 ; NOCOMPACTUNWIND-NEXT: callq throw_exception@PLT
345 ; NOCOMPACTUNWIND-NEXT: .Ltmp1:
346 ; NOCOMPACTUNWIND-NEXT: # %bb.2: # %unreachable
347 ; NOCOMPACTUNWIND-NEXT: .LBB4_3: # %landing
348 ; NOCOMPACTUNWIND-NEXT: .Ltmp2:
349 ; NOCOMPACTUNWIND-NEXT: popq %rax
350 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 8
351 ; NOCOMPACTUNWIND-NEXT: retq
353 br i1 %cond, label %throw, label %return
356 invoke void @throw_exception()
357 to label %unreachable unwind label %landing
363 %pad = landingpad { ptr, i32 }
371 ; Check landing pad again.
372 ; This time checks that we can shrink-wrap when the epilogue does not
373 ; span accross several blocks.
374 define void @with_nounwind_same_succ(i1 %cond) nounwind personality ptr @my_personality2 {
375 ; CHECK-LABEL: with_nounwind_same_succ:
376 ; CHECK: ## %bb.0: ## %entry
377 ; CHECK-NEXT: testb $1, %dil
378 ; CHECK-NEXT: je LBB5_4
379 ; CHECK-NEXT: ## %bb.1: ## %throw
380 ; CHECK-NEXT: pushq %rax
381 ; CHECK-NEXT: .cfi_def_cfa_offset 16
383 ; CHECK-NEXT: callq _throw_exception
385 ; CHECK-NEXT: LBB5_3: ## %fallthrough
386 ; CHECK-NEXT: ## InlineAsm Start
388 ; CHECK-NEXT: ## InlineAsm End
389 ; CHECK-NEXT: popq %rax
390 ; CHECK-NEXT: LBB5_4: ## %return
392 ; CHECK-NEXT: LBB5_2: ## %landing
394 ; CHECK-NEXT: jmp LBB5_3
395 ; CHECK-NEXT: Lfunc_end1:
397 ; NOCOMPACTUNWIND-LABEL: with_nounwind_same_succ:
398 ; NOCOMPACTUNWIND: # %bb.0: # %entry
399 ; NOCOMPACTUNWIND-NEXT: testb $1, %dil
400 ; NOCOMPACTUNWIND-NEXT: je .LBB5_4
401 ; NOCOMPACTUNWIND-NEXT: # %bb.1: # %throw
402 ; NOCOMPACTUNWIND-NEXT: pushq %rax
403 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16
404 ; NOCOMPACTUNWIND-NEXT: .Ltmp3:
405 ; NOCOMPACTUNWIND-NEXT: callq throw_exception@PLT
406 ; NOCOMPACTUNWIND-NEXT: .Ltmp4:
407 ; NOCOMPACTUNWIND-NEXT: .LBB5_3: # %fallthrough
408 ; NOCOMPACTUNWIND-NEXT: #APP
409 ; NOCOMPACTUNWIND-NEXT: nop
410 ; NOCOMPACTUNWIND-NEXT: #NO_APP
411 ; NOCOMPACTUNWIND-NEXT: popq %rax
412 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 8
413 ; NOCOMPACTUNWIND-NEXT: .LBB5_4: # %return
414 ; NOCOMPACTUNWIND-NEXT: retq
415 ; NOCOMPACTUNWIND-NEXT: .LBB5_2: # %landing
416 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16
417 ; NOCOMPACTUNWIND-NEXT: .Ltmp5:
418 ; NOCOMPACTUNWIND-NEXT: jmp .LBB5_3
420 br i1 %cond, label %throw, label %return
423 invoke void @throw_exception()
424 to label %fallthrough unwind label %landing
426 %pad = landingpad { ptr, i32 }
428 br label %fallthrough
431 tail call void asm "nop", ""()
438 declare void @throw_exception()
439 declare i32 @my_personality(...)
440 declare i32 @my_personality2(...)