1*9880d681SAndroid Build Coastguard Worker; RUN: llc %s -o - | FileCheck %s 2*9880d681SAndroid Build Coastguard Workertarget triple = "armv7-apple-ios" 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Workerdeclare i32 @llvm.eh.sjlj.setjmp(i8*) 5*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.eh.sjlj.longjmp(i8*) 6*9880d681SAndroid Build Coastguard Worker@g = external global i32 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Workerdeclare void @may_throw() 9*9880d681SAndroid Build Coastguard Workerdeclare i32 @__gxx_personality_sj0(...) 10*9880d681SAndroid Build Coastguard Workerdeclare i8* @__cxa_begin_catch(i8*) 11*9880d681SAndroid Build Coastguard Workerdeclare void @__cxa_end_catch() 12*9880d681SAndroid Build Coastguard Workerdeclare i32 @llvm.eh.typeid.for(i8*) 13*9880d681SAndroid Build Coastguard Workerdeclare i8* @llvm.frameaddress(i32) 14*9880d681SAndroid Build Coastguard Workerdeclare i8* @llvm.stacksave() 15*9880d681SAndroid Build Coastguard Worker@_ZTIPKc = external constant i8* 16*9880d681SAndroid Build Coastguard Worker 17*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foobar 18*9880d681SAndroid Build Coastguard Worker; 19*9880d681SAndroid Build Coastguard Worker; setjmp sequence: 20*9880d681SAndroid Build Coastguard Worker; CHECK: add [[PCREG:r[0-9]+]], pc, #8 21*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[PCREG]], {{\[}}[[BUFREG:r[0-9]+]], #4] 22*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov r0, #0 23*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add pc, pc, #0 24*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov r0, #1 25*9880d681SAndroid Build Coastguard Worker; 26*9880d681SAndroid Build Coastguard Worker; longjmp sequence: 27*9880d681SAndroid Build Coastguard Worker; CHECK: ldr sp, [{{\s*}}[[BUFREG:r[0-9]+]], #8] 28*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldr [[DESTREG:r[0-9]+]], {{\[}}[[BUFREG]], #4] 29*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldr r7, {{\[}}[[BUFREG]]{{\]}} 30*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bx [[DESTREG]] 31*9880d681SAndroid Build Coastguard Workerdefine void @foobar() { 32*9880d681SAndroid Build Coastguard Workerentry: 33*9880d681SAndroid Build Coastguard Worker %buf = alloca [5 x i8*], align 4 34*9880d681SAndroid Build Coastguard Worker %arraydecay = getelementptr inbounds [5 x i8*], [5 x i8*]* %buf, i32 0, i32 0 35*9880d681SAndroid Build Coastguard Worker %bufptr = bitcast i8** %arraydecay to i8* 36*9880d681SAndroid Build Coastguard Worker ; Note: This is simplified, in reality you have to store the framepointer + 37*9880d681SAndroid Build Coastguard Worker ; stackpointer in the buffer as well for this to be legal! 38*9880d681SAndroid Build Coastguard Worker %setjmpres = call i32 @llvm.eh.sjlj.setjmp(i8* %bufptr) 39*9880d681SAndroid Build Coastguard Worker %tobool = icmp ne i32 %setjmpres, 0 40*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %if.then, label %if.else 41*9880d681SAndroid Build Coastguard Worker 42*9880d681SAndroid Build Coastguard Workerif.then: 43*9880d681SAndroid Build Coastguard Worker store volatile i32 1, i32* @g, align 4 44*9880d681SAndroid Build Coastguard Worker br label %if.end 45*9880d681SAndroid Build Coastguard Worker 46*9880d681SAndroid Build Coastguard Workerif.else: 47*9880d681SAndroid Build Coastguard Worker store volatile i32 0, i32* @g, align 4 48*9880d681SAndroid Build Coastguard Worker call void @llvm.eh.sjlj.longjmp(i8* %bufptr) 49*9880d681SAndroid Build Coastguard Worker unreachable 50*9880d681SAndroid Build Coastguard Worker 51*9880d681SAndroid Build Coastguard Workerif.end: 52*9880d681SAndroid Build Coastguard Worker ret void 53*9880d681SAndroid Build Coastguard Worker} 54*9880d681SAndroid Build Coastguard Worker 55*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: combine_sjlj_eh_and_setjmp_longjmp 56*9880d681SAndroid Build Coastguard Worker; Check that we can mix sjlj exception handling with __builtin_setjmp 57*9880d681SAndroid Build Coastguard Worker; and __builtin_longjmp. 58*9880d681SAndroid Build Coastguard Worker; 59*9880d681SAndroid Build Coastguard Worker; setjmp sequence: 60*9880d681SAndroid Build Coastguard Worker; CHECK: add [[PCREG:r[0-9]+]], pc, #8 61*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[PCREG]], {{\[}}[[BUFREG:r[0-9]+]], #4] 62*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov r0, #0 63*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add pc, pc, #0 64*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov r0, #1 65*9880d681SAndroid Build Coastguard Worker; 66*9880d681SAndroid Build Coastguard Worker; longjmp sequence: 67*9880d681SAndroid Build Coastguard Worker; CHECK: ldr sp, [{{\s*}}[[BUFREG:r[0-9]+]], #8] 68*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldr [[DESTREG:r[0-9]+]], {{\[}}[[BUFREG]], #4] 69*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldr r7, {{\[}}[[BUFREG]]{{\]}} 70*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bx [[DESTREG]] 71*9880d681SAndroid Build Coastguard Workerdefine void @combine_sjlj_eh_and_setjmp_longjmp() personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*) { 72*9880d681SAndroid Build Coastguard Workerentry: 73*9880d681SAndroid Build Coastguard Worker %buf = alloca [5 x i8*], align 4 74*9880d681SAndroid Build Coastguard Worker invoke void @may_throw() to label %try.cont unwind label %lpad 75*9880d681SAndroid Build Coastguard Worker 76*9880d681SAndroid Build Coastguard Workerlpad: 77*9880d681SAndroid Build Coastguard Worker %0 = landingpad { i8*, i32 } catch i8* bitcast (i8** @_ZTIPKc to i8*) 78*9880d681SAndroid Build Coastguard Worker %1 = extractvalue { i8*, i32 } %0, 1 79*9880d681SAndroid Build Coastguard Worker %2 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIPKc to i8*)) #3 80*9880d681SAndroid Build Coastguard Worker %matches = icmp eq i32 %1, %2 81*9880d681SAndroid Build Coastguard Worker br i1 %matches, label %catch, label %eh.resume 82*9880d681SAndroid Build Coastguard Worker 83*9880d681SAndroid Build Coastguard Workercatch: 84*9880d681SAndroid Build Coastguard Worker %3 = extractvalue { i8*, i32 } %0, 0 85*9880d681SAndroid Build Coastguard Worker %4 = tail call i8* @__cxa_begin_catch(i8* %3) #3 86*9880d681SAndroid Build Coastguard Worker store volatile i32 0, i32* @g, align 4 87*9880d681SAndroid Build Coastguard Worker %5 = bitcast [5 x i8*]* %buf to i8* 88*9880d681SAndroid Build Coastguard Worker %arraydecay = getelementptr inbounds [5 x i8*], [5 x i8*]* %buf, i64 0, i64 0 89*9880d681SAndroid Build Coastguard Worker %6 = tail call i8* @llvm.frameaddress(i32 0) 90*9880d681SAndroid Build Coastguard Worker store i8* %6, i8** %arraydecay, align 16 91*9880d681SAndroid Build Coastguard Worker %7 = tail call i8* @llvm.stacksave() 92*9880d681SAndroid Build Coastguard Worker %8 = getelementptr [5 x i8*], [5 x i8*]* %buf, i64 0, i64 2 93*9880d681SAndroid Build Coastguard Worker store i8* %7, i8** %8, align 16 94*9880d681SAndroid Build Coastguard Worker %9 = call i32 @llvm.eh.sjlj.setjmp(i8* %5) 95*9880d681SAndroid Build Coastguard Worker %tobool = icmp eq i32 %9, 0 96*9880d681SAndroid Build Coastguard Worker br i1 %tobool, label %if.else, label %if.then 97*9880d681SAndroid Build Coastguard Worker 98*9880d681SAndroid Build Coastguard Workerif.then: 99*9880d681SAndroid Build Coastguard Worker store volatile i32 2, i32* @g, align 4 100*9880d681SAndroid Build Coastguard Worker call void @__cxa_end_catch() #3 101*9880d681SAndroid Build Coastguard Worker br label %try.cont 102*9880d681SAndroid Build Coastguard Worker 103*9880d681SAndroid Build Coastguard Workerif.else: 104*9880d681SAndroid Build Coastguard Worker store volatile i32 1, i32* @g, align 4 105*9880d681SAndroid Build Coastguard Worker call void @llvm.eh.sjlj.longjmp(i8* %5) 106*9880d681SAndroid Build Coastguard Worker unreachable 107*9880d681SAndroid Build Coastguard Worker 108*9880d681SAndroid Build Coastguard Workereh.resume: 109*9880d681SAndroid Build Coastguard Worker resume { i8*, i32 } %0 110*9880d681SAndroid Build Coastguard Worker 111*9880d681SAndroid Build Coastguard Workertry.cont: 112*9880d681SAndroid Build Coastguard Worker ret void 113*9880d681SAndroid Build Coastguard Worker} 114