diff options
7 files changed, 58 insertions, 10 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp index c3990d1..ba81537 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp @@ -482,6 +482,14 @@ static Value *getAddrSizeInt(Module *M, uint64_t C) { return IRB.getIntN(M->getDataLayout().getPointerSizeInBits(), C); } +// Returns true if the function has "target-features"="+exception-handling" +// attribute. +static bool hasEHTargetFeatureAttr(const Function &F) { + Attribute FeaturesAttr = F.getFnAttribute("target-features"); + return FeaturesAttr.isValid() && + FeaturesAttr.getValueAsString().contains("+exception-handling"); +} + // Returns __cxa_find_matching_catch_N function, where N = NumClauses + 2. // This is because a landingpad instruction contains two more arguments, a // personality function and a cleanup bit, and __cxa_find_matching_catch_N @@ -1004,6 +1012,7 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runOnModule(Module &M) { // Function registration and data pre-gathering for setjmp/longjmp handling if (DoSjLj) { assert(EnableEmSjLj || EnableWasmSjLj); + if (EnableEmSjLj) { // Register emscripten_longjmp function FunctionType *FTy = FunctionType::get( @@ -1019,6 +1028,22 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runOnModule(Module &M) { WasmLongjmpF->addFnAttr(Attribute::NoReturn); } + if (EnableWasmSjLj) { + for (auto *SjLjF : {SetjmpF, LongjmpF}) { + if (SjLjF) { + for (User *U : SjLjF->users()) { + if (auto *CI = dyn_cast<CallInst>(U)) { + auto &F = *CI->getFunction(); + if (!hasEHTargetFeatureAttr(F)) + report_fatal_error("Function " + F.getName() + + " is using setjmp/longjmp but does not have " + "+exception-handling target feature"); + } + } + } + } + } + if (SetjmpF) { Type *Int8PtrTy = IRB.getPtrTy(); Type *Int32PtrTy = IRB.getPtrTy(); diff --git a/llvm/test/CodeGen/WebAssembly/lower-em-sjlj-alloca.ll b/llvm/test/CodeGen/WebAssembly/lower-em-sjlj-alloca.ll index 3264fe9..2c50275 100644 --- a/llvm/test/CodeGen/WebAssembly/lower-em-sjlj-alloca.ll +++ b/llvm/test/CodeGen/WebAssembly/lower-em-sjlj-alloca.ll @@ -1,12 +1,12 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 -; RUN: opt -S -wasm-lower-em-ehsjlj -wasm-enable-sjlj -mtriple=wasm32-unknown-emscripten < %s | FileCheck %s +; RUN: opt -S -wasm-lower-em-ehsjlj -wasm-enable-sjlj -mattr=+exception-handling -mtriple=wasm32-unknown-emscripten < %s | FileCheck %s @buf = external global i8 declare i32 @setjmp(ptr) returns_twice declare void @dummy() define void @test_static() { -; CHECK-LABEL: define void @test_static() personality ptr @__gxx_wasm_personality_v0 { +; CHECK-LABEL: define void @test_static() {{.*}} personality ptr @__gxx_wasm_personality_v0 { ; CHECK-NEXT: [[ENTRY:.*]]: ; CHECK-NEXT: [[X:%.*]] = alloca i32, align 4 ; CHECK-NEXT: [[FUNCTIONINVOCATIONID:%.*]] = alloca i32, align 4 @@ -69,7 +69,7 @@ else: define void @test_dynamic(i32 %size) { ; CHECK-LABEL: define void @test_dynamic( -; CHECK-SAME: i32 [[SIZE:%.*]]) personality ptr @__gxx_wasm_personality_v0 { +; CHECK-SAME: i32 [[SIZE:%.*]]) {{.*}} personality ptr @__gxx_wasm_personality_v0 { ; CHECK-NEXT: [[ENTRY:.*]]: ; CHECK-NEXT: [[FUNCTIONINVOCATIONID:%.*]] = alloca i32, align 4 ; CHECK-NEXT: br label %[[SETJMP_DISPATCH:.*]] diff --git a/llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj-phi.ll b/llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj-phi.ll index 97f6d79..5e8ebcf 100644 --- a/llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj-phi.ll +++ b/llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj-phi.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -wasm-lower-em-ehsjlj -wasm-enable-eh -wasm-enable-sjlj -S | FileCheck %s +; RUN: opt < %s -wasm-lower-em-ehsjlj -wasm-enable-eh -wasm-enable-sjlj -mattr=+exception-handling -S | FileCheck %s target triple = "wasm32-unknown-emscripten" diff --git a/llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj.ll b/llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj.ll index 9de6652..d5ae37d7 100644 --- a/llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj.ll +++ b/llvm/test/CodeGen/WebAssembly/lower-wasm-ehsjlj.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -wasm-lower-em-ehsjlj -wasm-enable-eh -wasm-enable-sjlj -S | FileCheck %s +; RUN: opt < %s -wasm-lower-em-ehsjlj -wasm-enable-eh -wasm-enable-sjlj -mattr=+exception-handling -S | FileCheck %s ; RUN: llc < %s -wasm-enable-eh -wasm-enable-sjlj -exception-model=wasm -mattr=+exception-handling -verify-machineinstrs target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" @@ -109,7 +109,7 @@ catch: ; preds = %catch.start catchret from %2 to label %catchret.dest ; CHECK: catch: ; preds = %catch.start ; CHECK-NEXT: %exn = load ptr, ptr %exn.slot, align 4 -; CHECK-NEXT: %5 = call ptr @__cxa_begin_catch(ptr %exn) #3 [ "funclet"(token %2) ] +; CHECK-NEXT: %5 = call ptr @__cxa_begin_catch(ptr %exn) {{.*}} [ "funclet"(token %2) ] ; CHECK-NEXT: invoke void @__cxa_end_catch() [ "funclet"(token %2) ] ; CHECK-NEXT: to label %.noexc unwind label %catch.dispatch.longjmp diff --git a/llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj-no-eh-feature.ll b/llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj-no-eh-feature.ll new file mode 100644 index 0000000..c929560 --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj-no-eh-feature.ll @@ -0,0 +1,23 @@ +; RUN: not --crash opt < %s -wasm-lower-em-ehsjlj -wasm-enable-sjlj -S 2>&1 | FileCheck %s + +target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" +target triple = "wasm32-unknown-unknown" + +%struct.__jmp_buf_tag = type { [6 x i32], i32, [32 x i32] } + +; CHECK: LLVM ERROR: Function setjmp_longjmp is using setjmp/longjmp but does not have +exception-handling target feature +define void @setjmp_longjmp() { +entry: + %buf = alloca [1 x %struct.__jmp_buf_tag], align 16 + %call = call i32 @setjmp(ptr %buf) #0 + call void @longjmp(ptr %buf, i32 1) #1 + unreachable +} + +; Function Attrs: returns_twice +declare i32 @setjmp(ptr) #0 +; Function Attrs: noreturn +declare void @longjmp(ptr, i32) #1 + +attributes #0 = { returns_twice } +attributes #1 = { noreturn } diff --git a/llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj.ll b/llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj.ll index e1cb859..a4819b2 100644 --- a/llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj.ll +++ b/llvm/test/CodeGen/WebAssembly/lower-wasm-sjlj.ll @@ -1,6 +1,6 @@ -; RUN: opt < %s -wasm-lower-em-ehsjlj -wasm-enable-sjlj -S | FileCheck %s -DPTR=i32 -; RUN: opt < %s -wasm-lower-em-ehsjlj -wasm-enable-sjlj -S --mattr=+atomics,+bulk-memory | FileCheck %s -DPTR=i32 -; RUN: opt < %s -wasm-lower-em-ehsjlj -wasm-enable-sjlj --mtriple=wasm64-unknown-unknown -data-layout="e-m:e-p:64:64-i64:64-n32:64-S128" -S | FileCheck %s -DPTR=i64 +; RUN: opt < %s -wasm-lower-em-ehsjlj -wasm-enable-sjlj -mattr=+exception-handling -S | FileCheck %s -DPTR=i32 +; RUN: opt < %s -wasm-lower-em-ehsjlj -wasm-enable-sjlj -S --mattr=+atomics,+bulk-memory,+exception-handling | FileCheck %s -DPTR=i32 +; RUN: opt < %s -wasm-lower-em-ehsjlj -wasm-enable-sjlj -mattr=+exception-handling --mtriple=wasm64-unknown-unknown -data-layout="e-m:e-p:64:64-i64:64-n32:64-S128" -S | FileCheck %s -DPTR=i64 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-unknown" diff --git a/llvm/test/CodeGen/WebAssembly/wasm-eh-sjlj-setjmp-within-catch.ll b/llvm/test/CodeGen/WebAssembly/wasm-eh-sjlj-setjmp-within-catch.ll index f0d622a..ed9b629 100644 --- a/llvm/test/CodeGen/WebAssembly/wasm-eh-sjlj-setjmp-within-catch.ll +++ b/llvm/test/CodeGen/WebAssembly/wasm-eh-sjlj-setjmp-within-catch.ll @@ -1,4 +1,4 @@ -; RUN: not --crash opt < %s -wasm-lower-em-ehsjlj -wasm-enable-eh -wasm-enable-sjlj -S 2>&1 | FileCheck %s +; RUN: not --crash opt < %s -wasm-lower-em-ehsjlj -wasm-enable-eh -wasm-enable-sjlj -mattr=+exception-handling -S 2>&1 | FileCheck %s target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-unknown" |
