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

Reply via email to