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(i8*)
6 declare void @llvm.eh.sjlj.longjmp(i8*)
7 declare i8* @llvm.frameaddress(i32)
8 declare i8* @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 i8*], align 4
84 %bufptr = bitcast [5 x i8*]* %buf to i8*
85 %arraydecay = getelementptr inbounds [5 x i8*], [5 x i8*]* %buf, i32 0, i32 0
87 %fa = tail call i8* @llvm.frameaddress(i32 0)
88 store i8* %fa, i8** %arraydecay, align 4
89 %ss = tail call i8* @llvm.stacksave()
90 %ssgep = getelementptr [5 x i8*], [5 x i8*]* %buf, i32 0, i32 2
91 store i8* %ss, i8** %ssgep, align 4
93 %setjmpres = call i32 @llvm.eh.sjlj.setjmp(i8* %bufptr)
94 %tobool = icmp ne i32 %setjmpres, 0
95 br i1 %tobool, label %if.then, label %if.else
98 store volatile i32 1, i32* @g, align 4
102 store volatile i32 0, i32* @g, align 4
103 call void @llvm.eh.sjlj.longjmp(i8* %bufptr)
107 %fa2 = tail call i8* @llvm.frameaddress(i32 0)
108 store i8* %fa2, i8** %arraydecay, align 4
109 %ss2 = tail call i8* @llvm.stacksave()
110 store i8* %ss2, i8** %ssgep, align 4
112 %setjmpres2 = call i32 @llvm.eh.sjlj.setjmp(i8* %bufptr)
113 %tobool2 = icmp ne i32 %setjmpres2, 0
114 br i1 %tobool2, label %if2.then, label %if2.else
117 store volatile i32 3, i32* @g, align 4
121 store volatile i32 2, i32* @g, align 4
122 call void @llvm.eh.sjlj.longjmp(i8* %bufptr)