xref: /llvm-project/llvm/test/CodeGen/X86/x86-shrink-wrap-unwind.ll (revision a4951eca40c070e020aa5d2689c08177fbeb780d)
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
4;
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.
8
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
13;
14; No shrink-wrapping should occur here, until the CFI information are fixed.
15
16define i32 @framelessUnwind(i32 %a, i32 %b) #0 {
17; CHECK-LABEL: framelessUnwind:
18; CHECK:       ## %bb.0:
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
31; CHECK-NEXT:    retq
32;
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
52
53true:
54  store i32 %a, ptr %tmp, align 4
55  %tmp4 = call i32 @doSomething(i32 0, ptr %tmp)
56  br label %false
57
58false:
59  %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
60  ret i32 %tmp.0
61}
62
63declare i32 @doSomething(i32, ptr)
64
65attributes #0 = { "frame-pointer"="none" }
66
67; Shrink-wrapping should occur here. We have a frame pointer.
68define i32 @frameUnwind(i32 %a, i32 %b) #1 {
69; CHECK-LABEL: frameUnwind:
70; CHECK:       ## %bb.0:
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
88; CHECK-NEXT:    retq
89;
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
115
116true:
117  store i32 %a, ptr %tmp, align 4
118  %tmp4 = call i32 @doSomething(i32 0, ptr %tmp)
119  br label %false
120
121false:
122  %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
123  ret i32 %tmp.0
124}
125
126attributes #1 = { "frame-pointer"="all" }
127
128; Shrink-wrapping should occur here. We do not have to unwind.
129define i32 @framelessnoUnwind(i32 %a, i32 %b) #2 {
130; CHECK-LABEL: framelessnoUnwind:
131; CHECK:       ## %bb.0:
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
143; CHECK-NEXT:    retq
144;
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
162
163true:
164  store i32 %a, ptr %tmp, align 4
165  %tmp4 = call i32 @doSomething(i32 0, ptr %tmp)
166  br label %false
167
168false:
169  %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
170  ret i32 %tmp.0
171}
172
173attributes #2 = { "frame-pointer"="none" nounwind }
174
175
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.
180define zeroext i1 @segmentedStack(ptr readonly %vk1, ptr readonly %vk2, i64 %key_size) #5 {
181; CHECK-LABEL: segmentedStack:
182; CHECK:       ## %bb.0:
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
211; CHECK-NEXT:    retq
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
216; CHECK-NEXT:    retq
217; CHECK-NEXT:  LBB3_6:
218; CHECK-NEXT:    movl $8, %r10d
219; CHECK-NEXT:    movl $0, %r11d
220; CHECK-NEXT:    callq ___morestack
221; CHECK-NEXT:    retq
222; CHECK-NEXT:    jmp LBB3_1
223;
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
269entry:
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
275
276if.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
283
284land.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
290
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 ]
293  ret i1 %retval.0.i
294}
295
296; Function Attrs: nounwind readonly
297declare i32 @memcmp(ptr nocapture, ptr nocapture, i64) #5
298
299attributes #5 = { nounwind readonly ssp uwtable "split-stack" }
300
301; Check that correctly take into account the jumps to landing pad.
302; We used to consider function that may throw like regular
303; function calls.
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
307; happen.
308; PR36513
309define 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
318; CHECK-NEXT:    retq
319; CHECK-NEXT:  LBB4_1: ## %throw
320; CHECK-NEXT:  Ltmp0:
321; CHECK-NEXT:    callq _throw_exception
322; CHECK-NEXT:  Ltmp1:
323; CHECK-NEXT:  ## %bb.2: ## %unreachable
324; CHECK-NEXT:    ud2
325; CHECK-NEXT:  LBB4_3: ## %landing
326; CHECK-NEXT:  Ltmp2:
327; CHECK-NEXT:    popq %rax
328; CHECK-NEXT:    retq
329; CHECK-NEXT:  Lfunc_end0:
330;
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
352entry:
353  br i1 %cond, label %throw, label %return
354
355throw:
356  invoke void @throw_exception()
357          to label %unreachable unwind label %landing
358
359unreachable:
360  unreachable
361
362landing:
363  %pad = landingpad { ptr, i32 }
364          catch ptr null
365  ret void
366
367return:
368  ret void
369}
370
371; Check landing pad again.
372; This time checks that we can shrink-wrap when the epilogue does not
373; span accross several blocks.
374define 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
382; CHECK-NEXT:  Ltmp3:
383; CHECK-NEXT:    callq _throw_exception
384; CHECK-NEXT:  Ltmp4:
385; CHECK-NEXT:  LBB5_3: ## %fallthrough
386; CHECK-NEXT:    ## InlineAsm Start
387; CHECK-NEXT:    nop
388; CHECK-NEXT:    ## InlineAsm End
389; CHECK-NEXT:    popq %rax
390; CHECK-NEXT:  LBB5_4: ## %return
391; CHECK-NEXT:    retq
392; CHECK-NEXT:  LBB5_2: ## %landing
393; CHECK-NEXT:  Ltmp5:
394; CHECK-NEXT:    jmp LBB5_3
395; CHECK-NEXT:  Lfunc_end1:
396;
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
419entry:
420  br i1 %cond, label %throw, label %return
421
422throw:
423  invoke void @throw_exception()
424          to label %fallthrough unwind label %landing
425landing:
426  %pad = landingpad { ptr, i32 }
427          catch ptr null
428  br label %fallthrough
429
430fallthrough:
431  tail call void asm "nop", ""()
432  br label %return
433
434return:
435  ret void
436}
437
438declare void @throw_exception()
439declare i32 @my_personality(...)
440declare i32 @my_personality2(...)
441