1; RUN: llc < %s -enable-emscripten-cxx-exceptions | FileCheck %s --check-prefix=EH 2; RUN: llc < %s -enable-emscripten-sjlj | FileCheck %s --check-prefix=SJLJ 3; RUN: llc < %s | FileCheck %s --check-prefix=NONE 4; RUN: not --crash llc < %s -enable-emscripten-cxx-exceptions -exception-model=wasm 2>&1 | FileCheck %s --check-prefix=WASM-EH-EM-EH 5 6target triple = "wasm32-unknown-unknown" 7 8; EH: .functype invoke_vi (i32, i32) -> () 9; EH: .import_module invoke_vi, env 10; EH: .import_name invoke_vi, invoke_vi 11; EH-NOT: .functype __invoke_void_i32 12; EH-NOT: .import_module __invoke_void_i32 13; EH-NOT: .import_name __invoke_void_i32 14 15; SJLJ: .functype emscripten_longjmp (i32, i32) -> () 16; SJLJ: .import_module emscripten_longjmp, env 17; SJLJ: .import_name emscripten_longjmp, emscripten_longjmp 18; SJLJ-NOT: .functype emscripten_longjmp_jmpbuf 19; SJLJ-NOT: .import_module emscripten_longjmp_jmpbuf 20; SJLJ-NOT: .import_name emscripten_longjmp_jmpbuf 21 22%struct.__jmp_buf_tag = type { [6 x i32], i32, [32 x i32] } 23 24define void @exception() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 25; EH-LABEL: type exception,@function 26; NONE-LABEL: type exception,@function 27entry: 28 invoke void @foo(i32 3) 29 to label %invoke.cont unwind label %lpad 30; EH: call invoke_vi 31; EH-NOT: call __invoke_void_i32 32; NONE: call foo 33 34invoke.cont: 35 invoke void @bar() 36 to label %try.cont unwind label %lpad 37; EH: call invoke_v 38; EH-NOT: call __invoke_void 39; NONE: call bar 40 41lpad: ; preds = %entry 42 %0 = landingpad { i8*, i32 } 43 catch i8* null 44 %1 = extractvalue { i8*, i32 } %0, 0 45 %2 = extractvalue { i8*, i32 } %0, 1 46 %3 = call i8* @__cxa_begin_catch(i8* %1) #2 47 call void @__cxa_end_catch() 48 br label %try.cont 49 50try.cont: ; preds = %entry, %lpad 51 ret void 52} 53 54define void @setjmp_longjmp() { 55; SJLJ-LABEL: type setjmp_longjmp,@function 56; NONE-LABEL: type setjmp_longjmp,@function 57entry: 58 %buf = alloca [1 x %struct.__jmp_buf_tag], align 16 59 %arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0 60 %call = call i32 @setjmp(%struct.__jmp_buf_tag* %arraydecay) #0 61 %arraydecay1 = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0 62 call void @longjmp(%struct.__jmp_buf_tag* %arraydecay1, i32 1) #1 63 unreachable 64; SJLJ: call saveSetjmp 65; SJLJ: i32.const emscripten_longjmp 66; SJLJ-NOT: i32.const emscripten_longjmp_jmpbuf 67; SJLJ: call invoke_vii 68; SJLJ-NOT: call "__invoke_void_%struct.__jmp_buf_tag*_i32" 69; SJLJ: call testSetjmp 70 71; NONE: call setjmp 72; NONE: call longjmp 73} 74 75; Tests whether a user function with 'invoke_' prefix can be used 76declare void @invoke_ignoreme() 77define void @test_invoke_ignoreme() { 78; EH-LABEL: type test_invoke_ignoreme,@function 79; SJLJ-LABEL: type test_invoke_ignoreme,@function 80entry: 81 call void @invoke_ignoreme() 82; EH: call invoke_ignoreme 83; SJLJ: call invoke_ignoreme 84 ret void 85} 86 87declare void @foo(i32) 88declare void @bar() 89declare i32 @__gxx_personality_v0(...) 90declare i8* @__cxa_begin_catch(i8*) 91declare void @__cxa_end_catch() 92; Function Attrs: returns_twice 93declare i32 @setjmp(%struct.__jmp_buf_tag*) #0 94; Function Attrs: noreturn 95declare void @longjmp(%struct.__jmp_buf_tag*, i32) #1 96declare i8* @malloc(i32) 97declare void @free(i8*) 98 99attributes #0 = { returns_twice } 100attributes #1 = { noreturn } 101attributes #2 = { nounwind } 102 103; WASM-EH-EM-EH: LLVM ERROR: -exception-model=wasm not allowed with -enable-emscripten-cxx-exceptions 104