1 ; RUN: opt -mtriple=i686-pc-windows-msvc -S -x86-winehstate < %s | FileCheck %s 2 target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" 3 target triple = "i686-pc-windows-msvc" 4 5 @jb = external global i8 6 7 define i32 @test1() personality i32 (...)* @__CxxFrameHandler3 { 8 entry: 9 ; CHECK-LABEL: define i32 @test1( 10 ; CHECK: %[[eh_reg:.*]] = alloca 11 ; CHECK: %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}} %[[eh_reg]], i32 0, i32 2 12 ; CHECK: store i32 -1, i32* %[[gep]] 13 ; CHECK: %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}} %[[eh_reg]], i32 0, i32 2 14 ; CHECK: store i32 0, i32* %[[gep]] 15 ; CHECK: %[[lsda:.*]] = call i8* @llvm.x86.seh.lsda(i8* bitcast (i32 ()* @test1 to i8*)) 16 ; CHECK: invoke i32 (i8*, i32, ...) @_setjmp3(i8* @jb, i32 3, void (i8*)* @__CxxLongjmpUnwind, i32 0, i8* %[[lsda]]) 17 %inv = invoke i32 (i8*, i32, ...) @_setjmp3(i8* @jb, i32 0) #2 18 to label %invoke.cont unwind label %ehcleanup 19 20 invoke.cont: 21 ; CHECK: %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}} %[[eh_reg]], i32 0, i32 2 22 ; CHECK: store i32 -1, i32* %[[gep]] 23 ; CHECK: %[[lsda:.*]] = call i8* @llvm.x86.seh.lsda(i8* bitcast (i32 ()* @test1 to i8*)) 24 ; CHECK: call i32 (i8*, i32, ...) @_setjmp3(i8* @jb, i32 3, void (i8*)* @__CxxLongjmpUnwind, i32 -1, i8* %[[lsda]]) 25 call i32 (i8*, i32, ...) @_setjmp3(i8* @jb, i32 0) 26 call void @cleanup() 27 ret i32 %inv 28 29 ehcleanup: 30 %cp = cleanuppad within none [] 31 ; CHECK: %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}} %[[eh_reg]], i32 0, i32 2 32 ; CHECK: %[[load:.*]] = load i32, i32* %[[gep]] 33 ; CHECK: %[[lsda:.*]] = call i8* @llvm.x86.seh.lsda(i8* bitcast (i32 ()* @test1 to i8*)) 34 ; CHECK: call i32 (i8*, i32, ...) @_setjmp3(i8* @jb, i32 3, void (i8*)* @__CxxLongjmpUnwind, i32 %[[load]], i8* %[[lsda]]) [ "funclet"(token %cp) ] 35 %cal = call i32 (i8*, i32, ...) @_setjmp3(i8* @jb, i32 0) [ "funclet"(token %cp) ] 36 call void @cleanup() [ "funclet"(token %cp) ] 37 cleanupret from %cp unwind to caller 38 } 39 40 define i32 @test2() personality i32 (...)* @_except_handler3 { 41 entry: 42 ; CHECK-LABEL: define i32 @test2( 43 ; CHECK: %[[eh_reg:.*]] = alloca 44 ; CHECK: %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}} %[[eh_reg]], i32 0, i32 4 45 ; CHECK: store i32 -1, i32* %[[gep]] 46 ; CHECK: %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}} %[[eh_reg]], i32 0, i32 4 47 ; CHECK: store i32 0, i32* %[[gep]] 48 ; CHECK: invoke i32 (i8*, i32, ...) @_setjmp3(i8* @jb, i32 2, void (i8*)* @_seh_longjmp_unwind, i32 0) 49 %inv = invoke i32 (i8*, i32, ...) @_setjmp3(i8* @jb, i32 0) #2 50 to label %invoke.cont unwind label %ehcleanup 51 52 invoke.cont: 53 ; CHECK: %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}} %[[eh_reg]], i32 0, i32 4 54 ; CHECK: store i32 -1, i32* %[[gep]] 55 ; CHECK: call i32 (i8*, i32, ...) @_setjmp3(i8* @jb, i32 2, void (i8*)* @_seh_longjmp_unwind, i32 -1) 56 call i32 (i8*, i32, ...) @_setjmp3(i8* @jb, i32 0) 57 call void @cleanup() 58 ret i32 %inv 59 60 ehcleanup: 61 %cp = cleanuppad within none [] 62 call void @cleanup() [ "funclet"(token %cp) ] 63 cleanupret from %cp unwind to caller 64 } 65 66 ; Function Attrs: returns_twice 67 declare i32 @_setjmp3(i8*, i32, ...) #2 68 69 declare i32 @__CxxFrameHandler3(...) 70 71 declare i32 @_except_handler3(...) 72 73 declare void @cleanup() 74 75 attributes #2 = { returns_twice } 76