https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/146634
This was enforcing some rules about the combinations of flags at a random point in the IR pass pipeline configuration. This is a module property that should be handled at TargetMachine construction time at the latest. This required adding flags to a few mir and clang tests which never got this far to avoid hitting the errors. Split out from https://github.com/llvm/llvm-project/pull/146343 >From 4854c33649f7c8a6fad517ad77c355a3f7b7045c Mon Sep 17 00:00:00 2001 From: Matt Arsenault <matthew.arsena...@amd.com> Date: Wed, 2 Jul 2025 14:15:09 +0900 Subject: [PATCH] WebAssembly: Move validation of EH flags to TargetMachine construct time This was enforcing some rules about the combinations of flags at a random point in the IR pass pipeline configuration. This is a module property that should be handled at TargetMachine construction time at the latest. This required adding flags to a few mir and clang tests which never got this far to avoid hitting the errors. Split out from https://github.com/llvm/llvm-project/pull/146343 --- ...asm-exception-model-flag-parse-ir-input.ll | 7 +- clang/test/CodeGenCXX/builtins-eh-wasm.cpp | 2 +- clang/test/CodeGenCXX/wasm-eh.cpp | 6 +- .../WebAssembly/WebAssemblyTargetMachine.cpp | 110 +++++++++--------- .../WebAssembly/cfg-stackify-eh-legacy.mir | 2 +- .../CodeGen/WebAssembly/exception-legacy.mir | 2 +- .../CodeGen/WebAssembly/function-info.mir | 2 +- 7 files changed, 63 insertions(+), 68 deletions(-) diff --git a/clang/test/CodeGen/WebAssembly/wasm-exception-model-flag-parse-ir-input.ll b/clang/test/CodeGen/WebAssembly/wasm-exception-model-flag-parse-ir-input.ll index 4a7eeece58717..85bfc7f74daed 100644 --- a/clang/test/CodeGen/WebAssembly/wasm-exception-model-flag-parse-ir-input.ll +++ b/clang/test/CodeGen/WebAssembly/wasm-exception-model-flag-parse-ir-input.ll @@ -2,15 +2,16 @@ ; Check all the options parse ; RUN: %clang_cc1 -triple wasm32 -o - -emit-llvm -exception-model=none %s | FileCheck %s -; RUN: %clang_cc1 -triple wasm32 -o - -emit-llvm -exception-model=wasm %s | FileCheck %s -; RUN: %clang_cc1 -triple wasm32 -o - -emit-llvm -exception-model=dwarf %s | FileCheck %s -; RUN: %clang_cc1 -triple wasm32 -o - -emit-llvm -exception-model=sjlj %s | FileCheck %s +; RUN: %clang_cc1 -triple wasm32 -o - -emit-llvm -exception-model=wasm -mllvm -wasm-enable-eh %s | FileCheck %s ; RUN: not %clang_cc1 -triple wasm32 -o - -emit-llvm -exception-model=invalid %s 2>&1 | FileCheck -check-prefix=ERR %s +; RUN: not %clang_cc1 -triple wasm32 -o - -emit-llvm -exception-model=dwarf %s 2>&1 | FileCheck -check-prefix=ERR-BE %s +; RUN: not %clang_cc1 -triple wasm32 -o - -emit-llvm -exception-model=sjlj %s 2>&1 | FileCheck -check-prefix=ERR-BE %s ; CHECK-LABEL: define void @test( ; ERR: error: invalid value 'invalid' in '-exception-model=invalid' +; ERR-BE: fatal error: error in backend: -exception-model should be either 'none' or 'wasm' define void @test() { ret void } diff --git a/clang/test/CodeGenCXX/builtins-eh-wasm.cpp b/clang/test/CodeGenCXX/builtins-eh-wasm.cpp index b0f763d3e54dc..9a7134c48f208 100644 --- a/clang/test/CodeGenCXX/builtins-eh-wasm.cpp +++ b/clang/test/CodeGenCXX/builtins-eh-wasm.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple wasm32-unknown-unknown -fexceptions -fcxx-exceptions -target-feature +reference-types -target-feature +exception-handling -target-feature +multivalue -exception-model=wasm -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple wasm32-unknown-unknown -fexceptions -fcxx-exceptions -target-feature +reference-types -target-feature +exception-handling -target-feature +multivalue -mllvm -wasm-enable-eh -exception-model=wasm -emit-llvm -o - %s | FileCheck %s // Check if __builtin_wasm_throw and __builtin_wasm_rethrow are correctly // invoked when placed in try-catch. diff --git a/clang/test/CodeGenCXX/wasm-eh.cpp b/clang/test/CodeGenCXX/wasm-eh.cpp index faff764878f5d..f243f37ecb435 100644 --- a/clang/test/CodeGenCXX/wasm-eh.cpp +++ b/clang/test/CodeGenCXX/wasm-eh.cpp @@ -393,9 +393,9 @@ void noexcept_throw() noexcept { // CHECK-NEXT: call void @_ZSt9terminatev() -// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -exception-model=wasm -target-feature +exception-handling -emit-llvm -o - -std=c++11 2>&1 | FileCheck %s --check-prefix=WARNING-DEFAULT -// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -exception-model=wasm -target-feature +exception-handling -Wwasm-exception-spec -emit-llvm -o - -std=c++11 2>&1 | FileCheck %s --check-prefix=WARNING-ON -// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -exception-model=wasm -target-feature +exception-handling -Wno-wasm-exception-spec -emit-llvm -o - -std=c++11 2>&1 | FileCheck %s --check-prefix=WARNING-OFF +// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -mllvm -wasm-enable-eh -exception-model=wasm -target-feature +exception-handling -emit-llvm -o - -std=c++11 2>&1 | FileCheck %s --check-prefix=WARNING-DEFAULT +// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -mllvm -wasm-enable-eh -exception-model=wasm -target-feature +exception-handling -Wwasm-exception-spec -emit-llvm -o - -std=c++11 2>&1 | FileCheck %s --check-prefix=WARNING-ON +// RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -fms-extensions -fexceptions -fcxx-exceptions -mllvm -wasm-enable-eh -exception-model=wasm -target-feature +exception-handling -Wno-wasm-exception-spec -emit-llvm -o - -std=c++11 2>&1 | FileCheck %s --check-prefix=WARNING-OFF // RUN: %clang_cc1 %s -triple wasm32-unknown-unknown -fexceptions -fcxx-exceptions -emit-llvm -o - -std=c++11 2>&1 | FileCheck %s --check-prefix=EM-EH-WARNING // Wasm EH ignores dynamic exception specifications with types at the moment. diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp index 378af22f4907c..3e964be202956 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp @@ -111,6 +111,57 @@ static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM, return *RM; } +using WebAssembly::WasmEnableEH; +using WebAssembly::WasmEnableEmEH; +using WebAssembly::WasmEnableEmSjLj; +using WebAssembly::WasmEnableSjLj; + +static void basicCheckForEHAndSjLj(TargetMachine *TM) { + + // You can't enable two modes of EH at the same time + if (WasmEnableEmEH && WasmEnableEH) + report_fatal_error( + "-enable-emscripten-cxx-exceptions not allowed with -wasm-enable-eh"); + // You can't enable two modes of SjLj at the same time + if (WasmEnableEmSjLj && WasmEnableSjLj) + report_fatal_error( + "-enable-emscripten-sjlj not allowed with -wasm-enable-sjlj"); + // You can't mix Emscripten EH with Wasm SjLj. + if (WasmEnableEmEH && WasmEnableSjLj) + report_fatal_error( + "-enable-emscripten-cxx-exceptions not allowed with -wasm-enable-sjlj"); + + if (TM->Options.ExceptionModel == ExceptionHandling::None) { + // FIXME: These flags should be removed in favor of directly using the + // generically configured ExceptionsType + if (WebAssembly::WasmEnableEH || WebAssembly::WasmEnableSjLj) + TM->Options.ExceptionModel = ExceptionHandling::Wasm; + } + + // Basic Correctness checking related to -exception-model + if (TM->Options.ExceptionModel != ExceptionHandling::None && + TM->Options.ExceptionModel != ExceptionHandling::Wasm) + report_fatal_error("-exception-model should be either 'none' or 'wasm'"); + if (WasmEnableEmEH && TM->Options.ExceptionModel == ExceptionHandling::Wasm) + report_fatal_error("-exception-model=wasm not allowed with " + "-enable-emscripten-cxx-exceptions"); + if (WasmEnableEH && TM->Options.ExceptionModel != ExceptionHandling::Wasm) + report_fatal_error( + "-wasm-enable-eh only allowed with -exception-model=wasm"); + if (WasmEnableSjLj && TM->Options.ExceptionModel != ExceptionHandling::Wasm) + report_fatal_error( + "-wasm-enable-sjlj only allowed with -exception-model=wasm"); + if ((!WasmEnableEH && !WasmEnableSjLj) && + TM->Options.ExceptionModel == ExceptionHandling::Wasm) + report_fatal_error( + "-exception-model=wasm only allowed with at least one of " + "-wasm-enable-eh or -wasm-enable-sjlj"); + + // Currently it is allowed to mix Wasm EH with Emscripten SjLj as an interim + // measure, but some code will error out at compile time in this combination. + // See WebAssemblyLowerEmscriptenEHSjLj pass for details. +} + /// Create an WebAssembly architecture model. /// WebAssemblyTargetMachine::WebAssemblyTargetMachine( @@ -149,7 +200,7 @@ WebAssemblyTargetMachine::WebAssemblyTargetMachine( this->Options.UniqueSectionNames = true; initAsmInfo(); - + basicCheckForEHAndSjLj(this); // Note that we don't use setRequiresStructuredCFG(true). It disables // optimizations than we're ok with, and want, such as critical edge // splitting and tail merging. @@ -400,61 +451,6 @@ FunctionPass *WebAssemblyPassConfig::createTargetRegisterAllocator(bool) { return nullptr; // No reg alloc } -using WebAssembly::WasmEnableEH; -using WebAssembly::WasmEnableEmEH; -using WebAssembly::WasmEnableEmSjLj; -using WebAssembly::WasmEnableSjLj; - -static void basicCheckForEHAndSjLj(TargetMachine *TM) { - - // You can't enable two modes of EH at the same time - if (WasmEnableEmEH && WasmEnableEH) - report_fatal_error( - "-enable-emscripten-cxx-exceptions not allowed with -wasm-enable-eh"); - // You can't enable two modes of SjLj at the same time - if (WasmEnableEmSjLj && WasmEnableSjLj) - report_fatal_error( - "-enable-emscripten-sjlj not allowed with -wasm-enable-sjlj"); - // You can't mix Emscripten EH with Wasm SjLj. - if (WasmEnableEmEH && WasmEnableSjLj) - report_fatal_error( - "-enable-emscripten-cxx-exceptions not allowed with -wasm-enable-sjlj"); - - // Here we make sure TargetOptions.ExceptionModel is the same as - // MCAsmInfo.ExceptionsType. Normally these have to be the same, because clang - // stores the exception model info in LangOptions, which is later transferred - // to TargetOptions and MCAsmInfo. But when clang compiles bitcode directly, - // clang's LangOptions is not used and thus the exception model info is not - // correctly transferred to TargetOptions and MCAsmInfo, so we make sure we - // have the correct exception model in WebAssemblyMCAsmInfo constructor. But - // in this case TargetOptions is still not updated, so we make sure they are - // the same. - TM->Options.ExceptionModel = TM->getMCAsmInfo()->getExceptionHandlingType(); - - // Basic Correctness checking related to -exception-model - if (TM->Options.ExceptionModel != ExceptionHandling::None && - TM->Options.ExceptionModel != ExceptionHandling::Wasm) - report_fatal_error("-exception-model should be either 'none' or 'wasm'"); - if (WasmEnableEmEH && TM->Options.ExceptionModel == ExceptionHandling::Wasm) - report_fatal_error("-exception-model=wasm not allowed with " - "-enable-emscripten-cxx-exceptions"); - if (WasmEnableEH && TM->Options.ExceptionModel != ExceptionHandling::Wasm) - report_fatal_error( - "-wasm-enable-eh only allowed with -exception-model=wasm"); - if (WasmEnableSjLj && TM->Options.ExceptionModel != ExceptionHandling::Wasm) - report_fatal_error( - "-wasm-enable-sjlj only allowed with -exception-model=wasm"); - if ((!WasmEnableEH && !WasmEnableSjLj) && - TM->Options.ExceptionModel == ExceptionHandling::Wasm) - report_fatal_error( - "-exception-model=wasm only allowed with at least one of " - "-wasm-enable-eh or -wasm-enable-sjlj"); - - // Currently it is allowed to mix Wasm EH with Emscripten SjLj as an interim - // measure, but some code will error out at compile time in this combination. - // See WebAssemblyLowerEmscriptenEHSjLj pass for details. -} - //===----------------------------------------------------------------------===// // The following functions are called from lib/CodeGen/Passes.cpp to modify // the CodeGen pass sequence. @@ -475,8 +471,6 @@ void WebAssemblyPassConfig::addIRPasses() { if (getOptLevel() != CodeGenOptLevel::None) addPass(createWebAssemblyOptimizeReturned()); - basicCheckForEHAndSjLj(TM); - // If exception handling is not enabled and setjmp/longjmp handling is // enabled, we lower invokes into calls and delete unreachable landingpad // blocks. Lowering invokes when there is no EH support is done in diff --git a/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh-legacy.mir b/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh-legacy.mir index 5a4dc11cd328b..d5fbf41d39031 100644 --- a/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh-legacy.mir +++ b/llvm/test/CodeGen/WebAssembly/cfg-stackify-eh-legacy.mir @@ -1,4 +1,4 @@ -# RUN: llc -mtriple=wasm32-unknown-unknown -wasm-use-legacy-eh -exception-model=wasm -mattr=+exception-handling -run-pass wasm-cfg-stackify %s -o - | FileCheck %s +# RUN: llc -mtriple=wasm32-unknown-unknown -wasm-use-legacy-eh -wasm-enable-eh -exception-model=wasm -mattr=+exception-handling -run-pass wasm-cfg-stackify %s -o - | FileCheck %s --- | target triple = "wasm32-unknown-unknown" diff --git a/llvm/test/CodeGen/WebAssembly/exception-legacy.mir b/llvm/test/CodeGen/WebAssembly/exception-legacy.mir index 9273ceeadd0e7..95929af4f4cea 100644 --- a/llvm/test/CodeGen/WebAssembly/exception-legacy.mir +++ b/llvm/test/CodeGen/WebAssembly/exception-legacy.mir @@ -1,4 +1,4 @@ -# RUN: llc -mtriple=wasm32-unknown-unknown -wasm-use-legacy-eh -exception-model=wasm -mattr=+exception-handling -run-pass wasm-late-eh-prepare -run-pass wasm-cfg-stackify %s -o - | FileCheck %s +# RUN: llc -mtriple=wasm32-unknown-unknown -wasm-use-legacy-eh -wasm-enable-eh -exception-model=wasm -mattr=+exception-handling -run-pass wasm-late-eh-prepare -run-pass wasm-cfg-stackify %s -o - | FileCheck %s --- | target triple = "wasm32-unknown-unknown" diff --git a/llvm/test/CodeGen/WebAssembly/function-info.mir b/llvm/test/CodeGen/WebAssembly/function-info.mir index d241d59b67a39..ae7c15efe872f 100644 --- a/llvm/test/CodeGen/WebAssembly/function-info.mir +++ b/llvm/test/CodeGen/WebAssembly/function-info.mir @@ -1,4 +1,4 @@ -# RUN: llc -mtriple=wasm32-unknown-unknown -exception-model=wasm -mattr=+exception-handling,+multivalue,+simd128 -run-pass wasm-cfg-sort -run-pass wasm-cfg-stackify %s -o - | FileCheck %s +# RUN: llc -mtriple=wasm32-unknown-unknown -exception-model=wasm -wasm-enable-sjlj -mattr=+exception-handling,+multivalue,+simd128 -run-pass wasm-cfg-sort -run-pass wasm-cfg-stackify %s -o - | FileCheck %s --- | target triple = "wasm32-unknown-unknown" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits