1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc %s -o - | FileCheck %s
3 target triple = "thumbv7-apple-ios"
5 declare i32 @llvm.eh.sjlj.setjmp(ptr)
6 declare void @llvm.eh.sjlj.longjmp(ptr)
7 declare ptr @llvm.frameaddress(i32)
8 declare ptr @llvm.stacksave()
9 @g = external global i32
11 define void @double_foobar() {
12 ; CHECK-LABEL: double_foobar:
13 ; CHECK: @ %bb.0: @ %entry
14 ; CHECK-NEXT: push.w {r4, r5, r6, r7, r8, r10, r11, lr}
15 ; CHECK-NEXT: add r7, sp, #24
16 ; CHECK-NEXT: sub sp, #24
17 ; CHECK-NEXT: movs r1, #0
18 ; CHECK-NEXT: add r0, sp, #4
19 ; CHECK-NEXT: str r7, [sp, #4]
20 ; CHECK-NEXT: str.w sp, [sp, #12]
21 ; CHECK-NEXT: mov r1, pc @ eh_setjmp begin
22 ; CHECK-NEXT: adds r1, r1, #7
23 ; CHECK-NEXT: str r1, [r0, #4]
24 ; CHECK-NEXT: movs r0, #0
25 ; CHECK-NEXT: b LSJLJEH0
26 ; CHECK-NEXT: movs r0, #1 @ eh_setjmp end
27 ; CHECK-NEXT: LSJLJEH0:
28 ; CHECK-NEXT: cbz r0, LBB0_3
29 ; CHECK-NEXT: @ %bb.1: @ %if.then
30 ; CHECK-NEXT: movw r0, :lower16:(L_g$non_lazy_ptr-(LPC0_0+4))
31 ; CHECK-NEXT: movt r0, :upper16:(L_g$non_lazy_ptr-(LPC0_0+4))
33 ; CHECK-NEXT: add r0, pc
34 ; CHECK-NEXT: ldr r1, [r0]
35 ; CHECK-NEXT: movs r0, #1
36 ; CHECK-NEXT: str r1, [sp] @ 4-byte Spill
37 ; CHECK-NEXT: str r0, [r1]
38 ; CHECK-NEXT: add r0, sp, #4
39 ; CHECK-NEXT: movs r1, #0
40 ; CHECK-NEXT: str r7, [sp, #4]
41 ; CHECK-NEXT: str.w sp, [sp, #12]
42 ; CHECK-NEXT: mov r1, pc @ eh_setjmp begin
43 ; CHECK-NEXT: adds r1, r1, #7
44 ; CHECK-NEXT: str r1, [r0, #4]
45 ; CHECK-NEXT: movs r0, #0
46 ; CHECK-NEXT: b LSJLJEH1
47 ; CHECK-NEXT: movs r0, #1 @ eh_setjmp end
48 ; CHECK-NEXT: LSJLJEH1:
49 ; CHECK-NEXT: cmp r0, #0
50 ; CHECK-NEXT: itttt ne
51 ; CHECK-NEXT: movne r0, #3
52 ; CHECK-NEXT: ldrne r1, [sp] @ 4-byte Reload
53 ; CHECK-NEXT: strne r0, [r1]
54 ; CHECK-NEXT: addne sp, #24
56 ; CHECK-NEXT: popne.w {r4, r5, r6, r7, r8, r10, r11, pc}
57 ; CHECK-NEXT: LBB0_2: @ %if2.else
58 ; CHECK-NEXT: ldr r1, [sp] @ 4-byte Reload
59 ; CHECK-NEXT: movs r0, #2
60 ; CHECK-NEXT: str r0, [r1]
61 ; CHECK-NEXT: add r1, sp, #4
62 ; CHECK-NEXT: movs r0, #0
63 ; CHECK-NEXT: ldr r0, [r1, #8]
64 ; CHECK-NEXT: mov sp, r0
65 ; CHECK-NEXT: ldr r0, [r1, #4]
66 ; CHECK-NEXT: ldr r7, [r1]
68 ; CHECK-NEXT: LBB0_3: @ %if.else
69 ; CHECK-NEXT: movw r0, :lower16:(L_g$non_lazy_ptr-(LPC0_1+4))
70 ; CHECK-NEXT: movs r1, #0
71 ; CHECK-NEXT: movt r0, :upper16:(L_g$non_lazy_ptr-(LPC0_1+4))
73 ; CHECK-NEXT: add r0, pc
74 ; CHECK-NEXT: ldr r0, [r0]
75 ; CHECK-NEXT: str r1, [r0]
76 ; CHECK-NEXT: add r0, sp, #4
77 ; CHECK-NEXT: ldr r1, [r0, #8]
78 ; CHECK-NEXT: mov sp, r1
79 ; CHECK-NEXT: ldr r1, [r0, #4]
80 ; CHECK-NEXT: ldr r7, [r0]
83 %buf = alloca [5 x ptr], align 4
85 %fa = tail call ptr @llvm.frameaddress(i32 0)
86 store ptr %fa, ptr %buf, align 4
87 %ss = tail call ptr @llvm.stacksave()
88 %ssgep = getelementptr [5 x ptr], ptr %buf, i32 0, i32 2
89 store ptr %ss, ptr %ssgep, align 4
91 %setjmpres = call i32 @llvm.eh.sjlj.setjmp(ptr %buf)
92 %tobool = icmp ne i32 %setjmpres, 0
93 br i1 %tobool, label %if.then, label %if.else
96 store volatile i32 1, ptr @g, align 4
100 store volatile i32 0, ptr @g, align 4
101 call void @llvm.eh.sjlj.longjmp(ptr %buf)
105 %fa2 = tail call ptr @llvm.frameaddress(i32 0)
106 store ptr %fa2, ptr %buf, align 4
107 %ss2 = tail call ptr @llvm.stacksave()
108 store ptr %ss2, ptr %ssgep, align 4
110 %setjmpres2 = call i32 @llvm.eh.sjlj.setjmp(ptr %buf)
111 %tobool2 = icmp ne i32 %setjmpres2, 0
112 br i1 %tobool2, label %if2.then, label %if2.else
115 store volatile i32 3, ptr @g, align 4
119 store volatile i32 2, ptr @g, align 4
120 call void @llvm.eh.sjlj.longjmp(ptr %buf)