aheejin created this revision. aheejin added reviewers: dschuff, tlively. Herald added subscribers: wingo, ecnelises, sunfish, jgravelle-google, sbc100. aheejin requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
This adds support for Wasm SjLj in clang. Also this sets the new `-mllvm -wasm-enable-eh` option for Wasm EH. Note there is a little unfortunate inconsistency there: Wasm EH is enabled by a clang option `-fwasm-exceptions`, which sets `-mllvm -wasm-enable-eh` in the backend options. It also sets `-exception-model=wasm` but this is done in the common code. Wasm SjLj doesn't have a clang-level option like `-fwasm-exceptions`. `-fwasm-exceptions` was added because each exception model has its corresponding `-f***-exceptions`, but I'm not sure if adding a new option like `-fwasm-sjlj` or something is a good idea. So the current plan is Emscripten sets `-mllvm -wasm-enable-sjlj` if Wasm SJLj is enabled in its settings.js, as it does for Emscripten EH/SjLj (it sets `-mllvm -enable-emscripten-cxx-exceptions` for Emscripten EH and `-mllvm -enable-emscripten-sjlj` for Emscripten SjLj). And setting this enables the exception handling feature, and also sets `-exception-model=wasm`, but this time this is not done in the common code so we do it ourselves. It also sets the multivalue feature, because for `longjmp` we throw two values and catch two values: the setjmp buffer and the return value. So `catch` instruction will produce two values. Also note that other exception models have 1-to-1 correspondance with their `-f***-exceptions` flag and their `-exception-model=***` flag, but because we use `-exception-model=wasm` also for Wasm SjLj while `-fwasm-exceptions` still means Wasm EH, there is also a little inconsistency there, but I think it is manageable. Also this adds various error checking and tests. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D108582 Files: clang/lib/Driver/ToolChains/WebAssembly.cpp clang/test/Driver/wasm-toolchain.c
Index: clang/test/Driver/wasm-toolchain.c =================================================================== --- clang/test/Driver/wasm-toolchain.c +++ clang/test/Driver/wasm-toolchain.c @@ -94,11 +94,11 @@ // RUN: | FileCheck -check-prefix=EMSCRIPTEN_EH_ALLOWED_WO_ENABLE %s // EMSCRIPTEN_EH_ALLOWED_WO_ENABLE: invalid argument '-mllvm -emscripten-cxx-exceptions-allowed' only allowed with '-mllvm -enable-emscripten-cxx-exceptions' -// '-fwasm-exceptions' sets +exception-handling +// '-fwasm-exceptions' sets +exception-handling and '-mllvm -wasm-enable-eh' // RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown \ // RUN: --sysroot=/foo %s -fwasm-exceptions 2>&1 \ // RUN: | FileCheck -check-prefix=WASM_EXCEPTIONS %s -// WASM_EXCEPTIONS: clang{{.*}}" "-cc1" {{.*}} "-target-feature" "+exception-handling" +// WASM_EXCEPTIONS: clang{{.*}}" "-cc1" {{.*}} "-target-feature" "+exception-handling" "-mllvm" "-wasm-enable-eh" // '-fwasm-exceptions' not allowed with '-mno-exception-handling' // RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown \ @@ -106,13 +106,48 @@ // RUN: | FileCheck -check-prefix=WASM_EXCEPTIONS_NO_EH %s // WASM_EXCEPTIONS_NO_EH: invalid argument '-fwasm-exceptions' not allowed with '-mno-exception-handling' -// '-fwasm-exceptions' not allowed with -// '-mllvm -enable-emscripten-cxx-exceptions' +// '-fwasm-exceptions' not allowed with '-mllvm -enable-emscripten-cxx-exceptions' // RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown \ -// RUN: --sysroot=/foo %s -fwasm-exceptions -mllvm -enable-emscripten-cxx-exceptions 2>&1 \ +// RUN: --sysroot=/foo %s -fwasm-exceptions \ +// RUN: -mllvm -enable-emscripten-cxx-exceptions 2>&1 \ // RUN: | FileCheck -check-prefix=WASM_EXCEPTIONS_EMSCRIPTEN_EH %s // WASM_EXCEPTIONS_EMSCRIPTEN_EH: invalid argument '-fwasm-exceptions' not allowed with '-mllvm -enable-emscripten-cxx-exceptions' +// '-mllvm -wasm-enable-sjlj' sets +exception-handling, +multivalue and +// '-exception-model=wasm' +// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown \ +// RUN: --sysroot=/foo %s -mllvm -wasm-enable-sjlj 2>&1 \ +// RUN: | FileCheck -check-prefix=WASM_SJLJ %s +// WASM_SJLJ: clang{{.*}}" "-cc1" {{.*}} "-target-feature" "+exception-handling" "-target-feature" "+multivalue" "-exception-model=wasm" + +// '-mllvm -wasm-enable-sjlj' not allowed with '-mno-exception-handling' +// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown \ +// RUN: --sysroot=/foo %s -mllvm -wasm-enable-sjlj -mno-exception-handling \ +// RUN: 2>&1 \ +// RUN: | FileCheck -check-prefix=WASM_SJLJ_NO_EH %s +// WASM_SJLJ_NO_EH: invalid argument '-mllvm -wasm-enable-sjlj' not allowed with '-mno-exception-handling' + +// '-mllvm -wasm-enable-sjlj' not allowed with '-mno-multivalue' +// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown \ +// RUN: --sysroot=/foo %s -mllvm -wasm-enable-sjlj -mno-multivalue 2>&1 \ +// RUN: | FileCheck -check-prefix=WASM_SJLJ_NO_MULTIVALUE %s +// WASM_SJLJ_NO_MULTIVALUE: invalid argument '-mllvm -wasm-enable-sjlj' not allowed with '-mno-multivalue' + +// '-mllvm -wasm-enable-sjlj' not allowed with +// '-mllvm -enable-emscripten-cxx-exceptions' +// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown \ +// RUN: --sysroot=/foo %s -mllvm -wasm-enable-sjlj \ +// RUN: -mllvm -enable-emscripten-cxx-exceptions 2>&1 \ +// RUN: | FileCheck -check-prefix=WASM_SJLJ_EMSCRIPTEN_EH %s +// WASM_SJLJ_EMSCRIPTEN_EH: invalid argument '-mllvm -wasm-enable-sjlj' not allowed with '-mllvm -enable-emscripten-cxx-exceptions' + +// '-mllvm -wasm-enable-sjlj' not allowed with '-mllvm -enable-emscripten-sjlj' +// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown \ +// RUN: --sysroot=/foo %s -mllvm -wasm-enable-sjlj \ +// RUN: -mllvm -enable-emscripten-sjlj 2>&1 \ +// RUN: | FileCheck -check-prefix=WASM_SJLJ_EMSCRIPTEN_SJLJ %s +// WASM_SJLJ_EMSCRIPTEN_SJLJ: invalid argument '-mllvm -wasm-enable-sjlj' not allowed with '-mllvm -enable-emscripten-sjlj' + // RUN: %clang %s -### -fsanitize=address -target wasm32-unknown-emscripten 2>&1 | FileCheck -check-prefix=CHECK-ASAN-EMSCRIPTEN %s // CHECK-ASAN-EMSCRIPTEN: "-fsanitize=address" // CHECK-ASAN-EMSCRIPTEN: "-fsanitize-address-globals-dead-stripping" Index: clang/lib/Driver/ToolChains/WebAssembly.cpp =================================================================== --- clang/lib/Driver/ToolChains/WebAssembly.cpp +++ clang/lib/Driver/ToolChains/WebAssembly.cpp @@ -293,6 +293,9 @@ // '-fwasm-exceptions' implies exception-handling feature CC1Args.push_back("-target-feature"); CC1Args.push_back("+exception-handling"); + // Backend needs -wasm-enable-eh to enable Wasm EH + CC1Args.push_back("-mllvm"); + CC1Args.push_back("-wasm-enable-eh"); } for (const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) { @@ -300,14 +303,14 @@ if (Opt.startswith("-emscripten-cxx-exceptions-allowed")) { // '-mllvm -emscripten-cxx-exceptions-allowed' should be used with // '-mllvm -enable-emscripten-cxx-exceptions' - bool EmExceptionArgExists = false; + bool EmEHArgExists = false; for (const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) { if (StringRef(A->getValue(0)) == "-enable-emscripten-cxx-exceptions") { - EmExceptionArgExists = true; + EmEHArgExists = true; break; } } - if (!EmExceptionArgExists) + if (!EmEHArgExists) getDriver().Diag(diag::err_drv_argument_only_allowed_with) << "-mllvm -emscripten-cxx-exceptions-allowed" << "-mllvm -enable-emscripten-cxx-exceptions"; @@ -323,6 +326,48 @@ ":noinline")); } } + + if (Opt.startswith("-wasm-enable-sjlj")) { + // '-mllvm -wasm-enable-sjlj' is not compatible with + // '-mno-exception-handling' + if (DriverArgs.hasFlag(options::OPT_mno_exception_handing, + options::OPT_mexception_handing, false)) + getDriver().Diag(diag::err_drv_argument_not_allowed_with) + << "-mllvm -wasm-enable-sjlj" + << "-mno-exception-handling"; + // '-mllvm -wasm-enable-sjlj' is not compatible with '-mno-multivalue' + if (DriverArgs.hasFlag(options::OPT_mno_multivalue, + options::OPT_mexception_handing, false)) + getDriver().Diag(diag::err_drv_argument_not_allowed_with) + << "-mllvm -wasm-enable-sjlj" + << "-mno-multivalue"; + // '-mllvm -wasm-enable-sjlj' is not compatible with + // '-mllvm -enable-emscripten-cxx-exceptions' + // because we don't allow Emscripten EH + Wasm SjLj + for (const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) { + if (StringRef(A->getValue(0)) == "-enable-emscripten-cxx-exceptions") + getDriver().Diag(diag::err_drv_argument_not_allowed_with) + << "-mllvm -wasm-enable-sjlj" + << "-mllvm -enable-emscripten-cxx-exceptions"; + } + // '-mllvm -wasm-enable-sjlj' is not compatible with + // '-mllvm -enable-emscripten-sjlj' + for (const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) { + if (StringRef(A->getValue(0)) == "-enable-emscripten-sjlj") + getDriver().Diag(diag::err_drv_argument_not_allowed_with) + << "-mllvm -wasm-enable-sjlj" + << "-mllvm -enable-emscripten-sjlj"; + } + // '-mllvm -wasm-enable-sjlj' implies exception-handling feature + CC1Args.push_back("-target-feature"); + CC1Args.push_back("+exception-handling"); + // __builtin_wasm_longjmp will be lowered to a 'catch' instruction that + // produces two values + CC1Args.push_back("-target-feature"); + CC1Args.push_back("+multivalue"); + // Backend needs '-exception-model=wasm' to use Wasm EH instructions + CC1Args.push_back("-exception-model=wasm"); + } } }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits