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_7
185 ; CHECK-NEXT: LBB3_1: ## %entry
186 ; CHECK-NEXT: pushq %rax
187 ; CHECK-NEXT: .cfi_def_cfa_offset 16
188 ; CHECK-NEXT: movq %rdi, %rax
189 ; CHECK-NEXT: orq %rsi, %rax
190 ; CHECK-NEXT: sete %al
191 ; CHECK-NEXT: testq %rdi, %rdi
192 ; CHECK-NEXT: je LBB3_5
193 ; CHECK-NEXT: ## %bb.2: ## %entry
194 ; CHECK-NEXT: testq %rsi, %rsi
195 ; CHECK-NEXT: je LBB3_5
196 ; CHECK-NEXT: ## %bb.3: ## %if.end4.i
197 ; CHECK-NEXT: movq 8(%rdi), %rdx
198 ; CHECK-NEXT: cmpq 8(%rsi), %rdx
199 ; CHECK-NEXT: jne LBB3_6
200 ; CHECK-NEXT: ## %bb.4: ## %land.rhs.i.i
201 ; CHECK-NEXT: movq (%rsi), %rsi
202 ; CHECK-NEXT: movq (%rdi), %rdi
203 ; CHECK-NEXT: callq _memcmp
204 ; CHECK-NEXT: testl %eax, %eax
205 ; CHECK-NEXT: sete %al
206 ; CHECK-NEXT: LBB3_5: ## %__go_ptr_strings_equal.exit
207 ; CHECK-NEXT: ## kill: def $al killed $al killed $eax
208 ; CHECK-NEXT: popq %rcx
210 ; CHECK-NEXT: LBB3_6:
211 ; CHECK-NEXT: xorl %eax, %eax
212 ; CHECK-NEXT: ## kill: def $al killed $al killed $eax
213 ; CHECK-NEXT: popq %rcx
215 ; CHECK-NEXT: LBB3_7:
216 ; CHECK-NEXT: movl $8, %r10d
217 ; CHECK-NEXT: movl $0, %r11d
218 ; CHECK-NEXT: callq ___morestack
220 ; CHECK-NEXT: jmp LBB3_1
222 ; NOCOMPACTUNWIND-LABEL: segmentedStack:
223 ; NOCOMPACTUNWIND: # %bb.0:
224 ; NOCOMPACTUNWIND-NEXT: cmpq %fs:112, %rsp
225 ; NOCOMPACTUNWIND-NEXT: jbe .LBB3_7
226 ; NOCOMPACTUNWIND-NEXT: .LBB3_1: # %entry
227 ; NOCOMPACTUNWIND-NEXT: pushq %rax
228 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16
229 ; NOCOMPACTUNWIND-NEXT: movq %rdi, %rax
230 ; NOCOMPACTUNWIND-NEXT: orq %rsi, %rax
231 ; NOCOMPACTUNWIND-NEXT: sete %al
232 ; NOCOMPACTUNWIND-NEXT: testq %rdi, %rdi
233 ; NOCOMPACTUNWIND-NEXT: je .LBB3_5
234 ; NOCOMPACTUNWIND-NEXT: # %bb.2: # %entry
235 ; NOCOMPACTUNWIND-NEXT: testq %rsi, %rsi
236 ; NOCOMPACTUNWIND-NEXT: je .LBB3_5
237 ; NOCOMPACTUNWIND-NEXT: # %bb.3: # %if.end4.i
238 ; NOCOMPACTUNWIND-NEXT: movq 8(%rdi), %rdx
239 ; NOCOMPACTUNWIND-NEXT: cmpq 8(%rsi), %rdx
240 ; NOCOMPACTUNWIND-NEXT: jne .LBB3_6
241 ; NOCOMPACTUNWIND-NEXT: # %bb.4: # %land.rhs.i.i
242 ; NOCOMPACTUNWIND-NEXT: movq (%rsi), %rsi
243 ; NOCOMPACTUNWIND-NEXT: movq (%rdi), %rdi
244 ; NOCOMPACTUNWIND-NEXT: callq memcmp@PLT
245 ; NOCOMPACTUNWIND-NEXT: testl %eax, %eax
246 ; NOCOMPACTUNWIND-NEXT: sete %al
247 ; NOCOMPACTUNWIND-NEXT: .LBB3_5: # %__go_ptr_strings_equal.exit
248 ; NOCOMPACTUNWIND-NEXT: # kill: def $al killed $al killed $eax
249 ; NOCOMPACTUNWIND-NEXT: popq %rcx
250 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 8
251 ; NOCOMPACTUNWIND-NEXT: retq
252 ; NOCOMPACTUNWIND-NEXT: .LBB3_6:
253 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16
254 ; NOCOMPACTUNWIND-NEXT: xorl %eax, %eax
255 ; NOCOMPACTUNWIND-NEXT: # kill: def $al killed $al killed $eax
256 ; NOCOMPACTUNWIND-NEXT: popq %rcx
257 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 8
258 ; NOCOMPACTUNWIND-NEXT: retq
259 ; NOCOMPACTUNWIND-NEXT: .LBB3_7:
260 ; NOCOMPACTUNWIND-NEXT: movl $8, %r10d
261 ; NOCOMPACTUNWIND-NEXT: movl $0, %r11d
262 ; NOCOMPACTUNWIND-NEXT: callq __morestack
263 ; NOCOMPACTUNWIND-NEXT: retq
264 ; NOCOMPACTUNWIND-NEXT: jmp .LBB3_1
266 %cmp.i = icmp eq ptr %vk1, null
267 %cmp1.i = icmp eq ptr %vk2, null
268 %brmerge.i = or i1 %cmp.i, %cmp1.i
269 %cmp1.mux.i = and i1 %cmp.i, %cmp1.i
270 br i1 %brmerge.i, label %__go_ptr_strings_equal.exit, label %if.end4.i
272 if.end4.i: ; preds = %entry
273 %tmp = getelementptr inbounds i8, ptr %vk1, i64 8
274 %tmp2 = load i64, ptr %tmp, align 8
275 %tmp3 = getelementptr inbounds i8, ptr %vk2, i64 8
276 %tmp5 = load i64, ptr %tmp3, align 8
277 %cmp.i.i = icmp eq i64 %tmp2, %tmp5
278 br i1 %cmp.i.i, label %land.rhs.i.i, label %__go_ptr_strings_equal.exit
280 land.rhs.i.i: ; preds = %if.end4.i
281 %tmp7 = load ptr, ptr %vk2, align 8
282 %tmp9 = load ptr, ptr %vk1, align 8
283 %call.i.i = tail call i32 @memcmp(ptr %tmp9, ptr %tmp7, i64 %tmp2) #5
284 %cmp4.i.i = icmp eq i32 %call.i.i, 0
285 br label %__go_ptr_strings_equal.exit
287 __go_ptr_strings_equal.exit: ; preds = %land.rhs.i.i, %if.end4.i, %entry
288 %retval.0.i = phi i1 [ %cmp1.mux.i, %entry ], [ false, %if.end4.i ], [ %cmp4.i.i, %land.rhs.i.i ]
292 ; Function Attrs: nounwind readonly
293 declare i32 @memcmp(ptr nocapture, ptr nocapture, i64) #5
295 attributes #5 = { nounwind readonly ssp uwtable "split-stack" }
297 ; Check that correctly take into account the jumps to landing pad.
298 ; We used to consider function that may throw like regular
300 ; Therefore, in this example, we were happily inserting the epilogue
301 ; right after the call to throw_exception. Because of that we would not
302 ; execute the epilogue when an execption occur and bad things will
305 define void @with_nounwind(i1 %cond) nounwind personality ptr @my_personality {
306 ; CHECK-LABEL: with_nounwind:
307 ; CHECK: ## %bb.0: ## %entry
308 ; CHECK-NEXT: pushq %rax
309 ; CHECK-NEXT: .cfi_def_cfa_offset 16
310 ; CHECK-NEXT: testb $1, %dil
311 ; CHECK-NEXT: jne LBB4_1
312 ; CHECK-NEXT: ## %bb.4: ## %return
313 ; CHECK-NEXT: popq %rax
315 ; CHECK-NEXT: LBB4_1: ## %throw
317 ; CHECK-NEXT: callq _throw_exception
319 ; CHECK-NEXT: ## %bb.2: ## %unreachable
321 ; CHECK-NEXT: LBB4_3: ## %landing
323 ; CHECK-NEXT: popq %rax
325 ; CHECK-NEXT: Lfunc_end0:
327 ; NOCOMPACTUNWIND-LABEL: with_nounwind:
328 ; NOCOMPACTUNWIND: # %bb.0: # %entry
329 ; NOCOMPACTUNWIND-NEXT: pushq %rax
330 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16
331 ; NOCOMPACTUNWIND-NEXT: testb $1, %dil
332 ; NOCOMPACTUNWIND-NEXT: jne .LBB4_1
333 ; NOCOMPACTUNWIND-NEXT: # %bb.4: # %return
334 ; NOCOMPACTUNWIND-NEXT: popq %rax
335 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 8
336 ; NOCOMPACTUNWIND-NEXT: retq
337 ; NOCOMPACTUNWIND-NEXT: .LBB4_1: # %throw
338 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16
339 ; NOCOMPACTUNWIND-NEXT: .Ltmp0:
340 ; NOCOMPACTUNWIND-NEXT: callq throw_exception@PLT
341 ; NOCOMPACTUNWIND-NEXT: .Ltmp1:
342 ; NOCOMPACTUNWIND-NEXT: # %bb.2: # %unreachable
343 ; NOCOMPACTUNWIND-NEXT: .LBB4_3: # %landing
344 ; NOCOMPACTUNWIND-NEXT: .Ltmp2:
345 ; NOCOMPACTUNWIND-NEXT: popq %rax
346 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 8
347 ; NOCOMPACTUNWIND-NEXT: retq
349 br i1 %cond, label %throw, label %return
352 invoke void @throw_exception()
353 to label %unreachable unwind label %landing
359 %pad = landingpad { ptr, i32 }
367 ; Check landing pad again.
368 ; This time checks that we can shrink-wrap when the epilogue does not
369 ; span accross several blocks.
370 define void @with_nounwind_same_succ(i1 %cond) nounwind personality ptr @my_personality2 {
371 ; CHECK-LABEL: with_nounwind_same_succ:
372 ; CHECK: ## %bb.0: ## %entry
373 ; CHECK-NEXT: testb $1, %dil
374 ; CHECK-NEXT: je LBB5_4
375 ; CHECK-NEXT: ## %bb.1: ## %throw
376 ; CHECK-NEXT: pushq %rax
377 ; CHECK-NEXT: .cfi_def_cfa_offset 16
379 ; CHECK-NEXT: callq _throw_exception
381 ; CHECK-NEXT: LBB5_3: ## %fallthrough
382 ; CHECK-NEXT: ## InlineAsm Start
384 ; CHECK-NEXT: ## InlineAsm End
385 ; CHECK-NEXT: popq %rax
386 ; CHECK-NEXT: LBB5_4: ## %return
388 ; CHECK-NEXT: LBB5_2: ## %landing
390 ; CHECK-NEXT: jmp LBB5_3
391 ; CHECK-NEXT: Lfunc_end1:
393 ; NOCOMPACTUNWIND-LABEL: with_nounwind_same_succ:
394 ; NOCOMPACTUNWIND: # %bb.0: # %entry
395 ; NOCOMPACTUNWIND-NEXT: testb $1, %dil
396 ; NOCOMPACTUNWIND-NEXT: je .LBB5_4
397 ; NOCOMPACTUNWIND-NEXT: # %bb.1: # %throw
398 ; NOCOMPACTUNWIND-NEXT: pushq %rax
399 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16
400 ; NOCOMPACTUNWIND-NEXT: .Ltmp3:
401 ; NOCOMPACTUNWIND-NEXT: callq throw_exception@PLT
402 ; NOCOMPACTUNWIND-NEXT: .Ltmp4:
403 ; NOCOMPACTUNWIND-NEXT: .LBB5_3: # %fallthrough
404 ; NOCOMPACTUNWIND-NEXT: #APP
405 ; NOCOMPACTUNWIND-NEXT: nop
406 ; NOCOMPACTUNWIND-NEXT: #NO_APP
407 ; NOCOMPACTUNWIND-NEXT: popq %rax
408 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 8
409 ; NOCOMPACTUNWIND-NEXT: .LBB5_4: # %return
410 ; NOCOMPACTUNWIND-NEXT: retq
411 ; NOCOMPACTUNWIND-NEXT: .LBB5_2: # %landing
412 ; NOCOMPACTUNWIND-NEXT: .cfi_def_cfa_offset 16
413 ; NOCOMPACTUNWIND-NEXT: .Ltmp5:
414 ; NOCOMPACTUNWIND-NEXT: jmp .LBB5_3
416 br i1 %cond, label %throw, label %return
419 invoke void @throw_exception()
420 to label %fallthrough unwind label %landing
422 %pad = landingpad { ptr, i32 }
424 br label %fallthrough
427 tail call void asm "nop", ""()
434 declare void @throw_exception()
435 declare i32 @my_personality(...)
436 declare i32 @my_personality2(...)