1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc %s -o - | FileCheck %s 3target triple = "thumbv7-apple-ios" 4 5declare i32 @llvm.eh.sjlj.setjmp(ptr) 6declare void @llvm.eh.sjlj.longjmp(ptr) 7declare ptr @llvm.frameaddress(i32) 8declare ptr @llvm.stacksave() 9@g = external global i32 10 11define 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)) 32; CHECK-NEXT: LPC0_0: 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 55; CHECK-NEXT: it ne 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] 67; CHECK-NEXT: bx r0 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)) 72; CHECK-NEXT: LPC0_1: 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] 81; CHECK-NEXT: bx r1 82entry: 83 %buf = alloca [5 x ptr], align 4 84 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 90 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 94 95if.then: 96 store volatile i32 1, ptr @g, align 4 97 br label %if.end 98 99if.else: 100 store volatile i32 0, ptr @g, align 4 101 call void @llvm.eh.sjlj.longjmp(ptr %buf) 102 unreachable 103 104if.end: 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 109 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 113 114if2.then: 115 store volatile i32 3, ptr @g, align 4 116 br label %if2.end 117 118if2.else: 119 store volatile i32 2, ptr @g, align 4 120 call void @llvm.eh.sjlj.longjmp(ptr %buf) 121 unreachable 122 123if2.end: 124 ret void 125} 126