; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc %s -o - | FileCheck %s
target triple = "thumbv7-apple-ios"
declare i32 @llvm.eh.sjlj.setjmp(ptr)
declare void @llvm.eh.sjlj.longjmp(ptr)
declare ptr @llvm.frameaddress(i32)
declare ptr @llvm.stacksave()
@g = external global i32
define void @double_foobar() {
; CHECK-LABEL: double_foobar:
; CHECK: @ %bb.0: @ %entry
; CHECK-NEXT: push.w {r4, r5, r6, r7, r8, r10, r11, lr}
; CHECK-NEXT: add r7, sp, #24
; CHECK-NEXT: sub sp, #24
; CHECK-NEXT: movs r1, #0
; CHECK-NEXT: add r0, sp, #4
; CHECK-NEXT: str r7, [sp, #4]
; CHECK-NEXT: str.w sp, [sp, #12]
; CHECK-NEXT: mov r1, pc @ eh_setjmp begin
; CHECK-NEXT: adds r1, r1, #7
; CHECK-NEXT: str r1, [r0, #4]
; CHECK-NEXT: movs r0, #0
; CHECK-NEXT: b LSJLJEH0
; CHECK-NEXT: movs r0, #1 @ eh_setjmp end
; CHECK-NEXT: LSJLJEH0:
; CHECK-NEXT: cbz r0, LBB0_3
; CHECK-NEXT: @ %bb.1: @ %if.then
; CHECK-NEXT: movw r0, :lower16:(L_g$non_lazy_ptr-(LPC0_0+4))
; CHECK-NEXT: movt r0, :upper16:(L_g$non_lazy_ptr-(LPC0_0+4))
; CHECK-NEXT: LPC0_0:
; CHECK-NEXT: add r0, pc
; CHECK-NEXT: ldr r1, [r0]
; CHECK-NEXT: movs r0, #1
; CHECK-NEXT: str r1, [sp] @ 4-byte Spill
; CHECK-NEXT: str r0, [r1]
; CHECK-NEXT: add r0, sp, #4
; CHECK-NEXT: movs r1, #0
; CHECK-NEXT: str r7, [sp, #4]
; CHECK-NEXT: str.w sp, [sp, #12]
; CHECK-NEXT: mov r1, pc @ eh_setjmp begin
; CHECK-NEXT: adds r1, r1, #7
; CHECK-NEXT: str r1, [r0, #4]
; CHECK-NEXT: movs r0, #0
; CHECK-NEXT: b LSJLJEH1
; CHECK-NEXT: movs r0, #1 @ eh_setjmp end
; CHECK-NEXT: LSJLJEH1:
; CHECK-NEXT: cmp r0, #0
; CHECK-NEXT: itttt ne
; CHECK-NEXT: movne r0, #3
; CHECK-NEXT: ldrne r1, [sp] @ 4-byte Reload
; CHECK-NEXT: strne r0, [r1]
; CHECK-NEXT: addne sp, #24
; CHECK-NEXT: it ne
; CHECK-NEXT: popne.w {r4, r5, r6, r7, r8, r10, r11, pc}
; CHECK-NEXT: LBB0_2: @ %if2.else
; CHECK-NEXT: ldr r1, [sp] @ 4-byte Reload
; CHECK-NEXT: movs r0, #2
; CHECK-NEXT: str r0, [r1]
; CHECK-NEXT: add r1, sp, #4
; CHECK-NEXT: movs r0, #0
; CHECK-NEXT: ldr r0, [r1, #8]
; CHECK-NEXT: mov sp, r0
; CHECK-NEXT: ldr r0, [r1, #4]
; CHECK-NEXT: ldr r7, [r1]
; CHECK-NEXT: bx r0
; CHECK-NEXT: LBB0_3: @ %if.else
; CHECK-NEXT: movw r0, :lower16:(L_g$non_lazy_ptr-(LPC0_1+4))
; CHECK-NEXT: movs r1, #0
; CHECK-NEXT: movt r0, :upper16:(L_g$non_lazy_ptr-(LPC0_1+4))
; CHECK-NEXT: LPC0_1:
; CHECK-NEXT: add r0, pc
; CHECK-NEXT: ldr r0, [r0]
; CHECK-NEXT: str r1, [r0]
; CHECK-NEXT: add r0, sp, #4
; CHECK-NEXT: ldr r1, [r0, #8]
; CHECK-NEXT: mov sp, r1
; CHECK-NEXT: ldr r1, [r0, #4]
; CHECK-NEXT: ldr r7, [r0]
; CHECK-NEXT: bx r1
entry:
%buf = alloca [5 x ptr], align 4
%fa = tail call ptr @llvm.frameaddress(i32 0)
store ptr %fa, ptr %buf, align 4
%ss = tail call ptr @llvm.stacksave()
%ssgep = getelementptr [5 x ptr], ptr %buf, i32 0, i32 2
store ptr %ss, ptr %ssgep, align 4
%setjmpres = call i32 @llvm.eh.sjlj.setjmp(ptr %buf)
%tobool = icmp ne i32 %setjmpres, 0
br i1 %tobool, label %if.then, label %if.else
if.then:
store volatile i32 1, ptr @g, align 4
br label %if.end
if.else:
store volatile i32 0, ptr @g, align 4
call void @llvm.eh.sjlj.longjmp(ptr %buf)
unreachable
if.end:
%fa2 = tail call ptr @llvm.frameaddress(i32 0)
store ptr %fa2, ptr %buf, align 4
%ss2 = tail call ptr @llvm.stacksave()
store ptr %ss2, ptr %ssgep, align 4
%setjmpres2 = call i32 @llvm.eh.sjlj.setjmp(ptr %buf)
%tobool2 = icmp ne i32 %setjmpres2, 0
br i1 %tobool2, label %if2.then, label %if2.else
if2.then:
store volatile i32 3, ptr @g, align 4
br label %if2.end
if2.else:
store volatile i32 2, ptr @g, align 4
call void @llvm.eh.sjlj.longjmp(ptr %buf)
unreachable
if2.end:
ret void
}