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