1; RUN: llc %s -o - | FileCheck %s
2target triple = "thumbv7-apple-ios"
3
4declare i32 @llvm.eh.sjlj.setjmp(i8*)
5declare void @llvm.eh.sjlj.longjmp(i8*)
6declare i8* @llvm.frameaddress(i32)
7declare i8* @llvm.stacksave()
8@g = external global i32
9
10; CHECK-LABEL: double_foobar
11;
12; setjmp sequence:
13; CHECK: mov [[PCREG:r[0-9]+]], pc
14; CHECK-NEXT: adds [[PCREG]], [[PCREG]], #7
15; CHECK-NEXT: str [[PCREG]], {{\[}}[[BUFREG:r[0-9]+]], #4]
16; CHECK-NEXT: movs r0, #0
17; CHECK-NEXT: b [[LABEL:L[a-zA-Z0-9]+]]
18; CHECK-NEXT: movs r0, #1
19; CHECK-NEXT: [[LABEL]]:
20;
21; setjmp sequence 2:
22; CHECK: mov [[PCREG:r[0-9]+]], pc
23; CHECK-NEXT: adds [[PCREG]], [[PCREG]], #7
24; CHECK-NEXT: str [[PCREG]], {{\[}}[[BUFREG:r[0-9]+]], #4]
25; CHECK-NEXT: movs r0, #0
26; CHECK-NEXT: b [[LABEL:L[a-zA-Z0-9]+]]
27; CHECK-NEXT: movs r0, #1
28; CHECK-NEXT: [[LABEL]]:
29
30; longjmp sequence:
31; CHECK: ldr [[TEMPREG:r[0-9]+]], [{{\s*}}[[BUFREG:r[0-9]+]], #8]
32; CHECK-NEXT: mov sp, [[TEMPREG]]
33; CHECK-NEXT: ldr [[DESTREG:r[0-9]+]], {{\[}}[[BUFREG]], #4]
34; CHECK-NEXT: ldr r7, {{\[}}[[BUFREG]]{{\]}}
35; CHECK-NEXT: bx [[DESTREG]]
36;
37; longjmp sequence2:
38; CHECK: ldr [[TEMPREG:r[0-9]+]], [{{\s*}}[[BUFREG:r[0-9]+]], #8]
39; CHECK-NEXT: mov sp, [[TEMPREG]]
40; CHECK-NEXT: ldr [[DESTREG:r[0-9]+]], {{\[}}[[BUFREG]], #4]
41; CHECK-NEXT: ldr r7, {{\[}}[[BUFREG]]{{\]}}
42; CHECK-NEXT: bx [[DESTREG]]
43define void @double_foobar() {
44entry:
45  %buf = alloca [5 x i8*], align 4
46  %bufptr = bitcast [5 x i8*]* %buf to i8*
47  %arraydecay = getelementptr inbounds [5 x i8*], [5 x i8*]* %buf, i32 0, i32 0
48
49  %fa = tail call i8* @llvm.frameaddress(i32 0)
50  store i8* %fa, i8** %arraydecay, align 4
51  %ss = tail call i8* @llvm.stacksave()
52  %ssgep = getelementptr [5 x i8*], [5 x i8*]* %buf, i32 0, i32 2
53  store i8* %ss, i8** %ssgep, align 4
54
55  %setjmpres = call i32 @llvm.eh.sjlj.setjmp(i8* %bufptr)
56  %tobool = icmp ne i32 %setjmpres, 0
57  br i1 %tobool, label %if.then, label %if.else
58
59if.then:
60  store volatile i32 1, i32* @g, align 4
61  br label %if.end
62
63if.else:
64  store volatile i32 0, i32* @g, align 4
65  call void @llvm.eh.sjlj.longjmp(i8* %bufptr)
66  unreachable
67
68if.end:
69  %fa2 = tail call i8* @llvm.frameaddress(i32 0)
70  store i8* %fa2, i8** %arraydecay, align 4
71  %ss2 = tail call i8* @llvm.stacksave()
72  store i8* %ss2, i8** %ssgep, align 4
73
74  %setjmpres2 = call i32 @llvm.eh.sjlj.setjmp(i8* %bufptr)
75  %tobool2 = icmp ne i32 %setjmpres2, 0
76  br i1 %tobool2, label %if2.then, label %if2.else
77
78if2.then:
79  store volatile i32 3, i32* @g, align 4
80  br label %if2.end
81
82if2.else:
83  store volatile i32 2, i32* @g, align 4
84  call void @llvm.eh.sjlj.longjmp(i8* %bufptr)
85  unreachable
86
87if2.end:
88  ret void
89}
90