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