aheejin created this revision. aheejin added a reviewer: sbc100. Herald added subscribers: wingo, ecnelises, sunfish, jgravelle-google, dschuff. aheejin requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Functions specified in `-emscripten-cxx-exceptions-allowed`, which is set by Emscripten's `EXCEPTION_CATCHING_ALLOWED` setting, can be inlined in LLVM middle ends before we reach WebAssemblyLowerEmscriptenEHSjLj pass in the wasm backend and thus don't get transformed for exception catching. This fixes the issue by adding `--force-attribute=FUNC_NAME:noinline` for each function name in `-emscripten-cxx-exceptions-allowed`, which adds `noinline` attribute to the specified function and thus excludes the function from inlining candidates in optimization passes. Fixes the remaining half of https://github.com/emscripten-core/emscripten/issues/10721. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D99259 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 @@ -79,6 +79,21 @@ // RUN: | FileCheck -check-prefix=PTHREAD_NO_SIGN_EXT %s // PTHREAD_NO_SIGN_EXT: invalid argument '-pthread' not allowed with '-mno-sign-ext' +// '-mllvm -emscripten-cxx-exceptions-allowed=foo,bar' sets +// '-mllvm --force-attribute=foo:noinline -mllvm --force-attribute=bar:noinline' +// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown \ +// RUN: --sysroot=/foo %s -mllvm -enable-emscripten-cxx-exceptions \ +// RUN: -mllvm -emscripten-cxx-exceptions-allowed=foo,bar 2>&1 \ +// RUN: | FileCheck -check-prefix=EMSCRIPTEN_EH_ALLOWED_NOINLINE %s +// EMSCRIPTEN_EH_ALLOWED_NOINLINE: clang{{.*}}" "-cc1" {{.*}} "-mllvm" "--force-attribute=foo:noinline" "-mllvm" "--force-attribute=bar:noinline" + +// '-mllvm -emscripten-cxx-exceptions-allowed' only allowed with +// '-mllvm -enable-emscripten-cxx-exceptions' +// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown \ +// RUN: --sysroot=/foo %s -mllvm -emscripten-cxx-exceptions-allowed 2>&1 \ +// 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 // RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown \ // RUN: --sysroot=/foo %s -fwasm-exceptions 2>&1 \ Index: clang/lib/Driver/ToolChains/WebAssembly.cpp =================================================================== --- clang/lib/Driver/ToolChains/WebAssembly.cpp +++ clang/lib/Driver/ToolChains/WebAssembly.cpp @@ -294,6 +294,33 @@ CC1Args.push_back("-target-feature"); CC1Args.push_back("+exception-handling"); } + + for (const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) { + StringRef Opt = A->getValue(0); + if (Opt.startswith("-emscripten-cxx-exceptions-allowed")) { + // '-mllvm -emscripten-cxx-exceptions-allowed' is only allowed with + // '-mllvm -enable-emscripten-cxx-exceptions' + bool EmExceptionArgExists = false; + for (const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) + if (StringRef(A->getValue(0)) == "-enable-emscripten-cxx-exceptions") + EmExceptionArgExists = true; + if (!EmExceptionArgExists) + getDriver().Diag(diag::err_drv_argument_only_allowed_with) + << "-mllvm -emscripten-cxx-exceptions-allowed" + << "-mllvm -enable-emscripten-cxx-exceptions"; + + // Prevent functions specified in -emscripten-cxx-exceptions-allowed list + // from being inlined before reaching the wasm backend. + StringRef FuncNamesStr = Opt.split('=').second; + SmallVector<StringRef, 4> FuncNames; + FuncNamesStr.split(FuncNames, ','); + for (auto Name : FuncNames) { + CC1Args.push_back("-mllvm"); + CC1Args.push_back(DriverArgs.MakeArgString("--force-attribute=" + Name + + ":noinline")); + } + } + } } ToolChain::RuntimeLibType WebAssembly::GetDefaultRuntimeLibType() const {
Index: clang/test/Driver/wasm-toolchain.c =================================================================== --- clang/test/Driver/wasm-toolchain.c +++ clang/test/Driver/wasm-toolchain.c @@ -79,6 +79,21 @@ // RUN: | FileCheck -check-prefix=PTHREAD_NO_SIGN_EXT %s // PTHREAD_NO_SIGN_EXT: invalid argument '-pthread' not allowed with '-mno-sign-ext' +// '-mllvm -emscripten-cxx-exceptions-allowed=foo,bar' sets +// '-mllvm --force-attribute=foo:noinline -mllvm --force-attribute=bar:noinline' +// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown \ +// RUN: --sysroot=/foo %s -mllvm -enable-emscripten-cxx-exceptions \ +// RUN: -mllvm -emscripten-cxx-exceptions-allowed=foo,bar 2>&1 \ +// RUN: | FileCheck -check-prefix=EMSCRIPTEN_EH_ALLOWED_NOINLINE %s +// EMSCRIPTEN_EH_ALLOWED_NOINLINE: clang{{.*}}" "-cc1" {{.*}} "-mllvm" "--force-attribute=foo:noinline" "-mllvm" "--force-attribute=bar:noinline" + +// '-mllvm -emscripten-cxx-exceptions-allowed' only allowed with +// '-mllvm -enable-emscripten-cxx-exceptions' +// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown \ +// RUN: --sysroot=/foo %s -mllvm -emscripten-cxx-exceptions-allowed 2>&1 \ +// 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 // RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown \ // RUN: --sysroot=/foo %s -fwasm-exceptions 2>&1 \ Index: clang/lib/Driver/ToolChains/WebAssembly.cpp =================================================================== --- clang/lib/Driver/ToolChains/WebAssembly.cpp +++ clang/lib/Driver/ToolChains/WebAssembly.cpp @@ -294,6 +294,33 @@ CC1Args.push_back("-target-feature"); CC1Args.push_back("+exception-handling"); } + + for (const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) { + StringRef Opt = A->getValue(0); + if (Opt.startswith("-emscripten-cxx-exceptions-allowed")) { + // '-mllvm -emscripten-cxx-exceptions-allowed' is only allowed with + // '-mllvm -enable-emscripten-cxx-exceptions' + bool EmExceptionArgExists = false; + for (const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) + if (StringRef(A->getValue(0)) == "-enable-emscripten-cxx-exceptions") + EmExceptionArgExists = true; + if (!EmExceptionArgExists) + getDriver().Diag(diag::err_drv_argument_only_allowed_with) + << "-mllvm -emscripten-cxx-exceptions-allowed" + << "-mllvm -enable-emscripten-cxx-exceptions"; + + // Prevent functions specified in -emscripten-cxx-exceptions-allowed list + // from being inlined before reaching the wasm backend. + StringRef FuncNamesStr = Opt.split('=').second; + SmallVector<StringRef, 4> FuncNames; + FuncNamesStr.split(FuncNames, ','); + for (auto Name : FuncNames) { + CC1Args.push_back("-mllvm"); + CC1Args.push_back(DriverArgs.MakeArgString("--force-attribute=" + Name + + ":noinline")); + } + } + } } ToolChain::RuntimeLibType WebAssembly::GetDefaultRuntimeLibType() const {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits