Skip to content

Conversation

sbc100
Copy link
Collaborator

@sbc100 sbc100 commented Sep 16, 2025

Rather then defining these tags in each object file that requires them
we can can declare them as undefined and require that they defined
externally in, for example, compiler-rt or libcxxabi.

I also added these tag definitions to compiler-rt.

@sbc100
Copy link
Collaborator Author

sbc100 commented Sep 16, 2025

Depends on #159141

@llvmbot
Copy link
Member

llvmbot commented Sep 16, 2025

@llvm/pr-subscribers-lld
@llvm/pr-subscribers-backend-webassembly

@llvm/pr-subscribers-lld-wasm

Author: Sam Clegg (sbc100)

Changes

Rather then defining these tags in each object file that requires them
we can can declare them as undefined and require that they defined
externally in, for example, compiler-rt.


Patch is 42.60 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/159143.diff

12 Files Affected:

  • (added) lld/test/wasm/Inputs/tags.s (+7)
  • (modified) lld/test/wasm/tag-section.ll (+9-7)
  • (modified) lld/wasm/Relocations.cpp (+5-3)
  • (modified) llvm/lib/CodeGen/AsmPrinter/WasmException.cpp (-23)
  • (modified) llvm/lib/CodeGen/AsmPrinter/WasmException.h (+1-1)
  • (modified) llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp (-7)
  • (modified) llvm/test/CodeGen/WebAssembly/exception-legacy.ll (+2-1)
  • (modified) llvm/test/CodeGen/WebAssembly/exception.ll (+2-1)
  • (removed) llvm/test/MC/WebAssembly/tag-section-decoding.ll (-342)
  • (added) llvm/test/MC/WebAssembly/tag-section-decoding.s (+409)
  • (removed) llvm/test/MC/WebAssembly/tag-section.ll (-56)
  • (added) llvm/test/MC/WebAssembly/tag-section.s (+63)
diff --git a/lld/test/wasm/Inputs/tags.s b/lld/test/wasm/Inputs/tags.s
new file mode 100644
index 0000000000000..e59b31b25626d
--- /dev/null
+++ b/lld/test/wasm/Inputs/tags.s
@@ -0,0 +1,7 @@
+.globl __cpp_exception
+.tagtype  __cpp_exception i32
+__cpp_exception:
+
+.globl __c_longjmp
+.tagtype  __c_longjmp i32
+__c_longjmp:
diff --git a/lld/test/wasm/tag-section.ll b/lld/test/wasm/tag-section.ll
index 20823c72c6511..05bfc9120eb10 100644
--- a/lld/test/wasm/tag-section.ll
+++ b/lld/test/wasm/tag-section.ll
@@ -1,18 +1,20 @@
-; Static code
+; RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t_tags.o %p/Inputs/tags.s
+
+; Static code, with tags defined in tags.s
 ; RUN: llc -filetype=obj -wasm-enable-eh -exception-model=wasm -mattr=+exception-handling %p/Inputs/tag-section1.ll -o %t1.o
 ; RUN: llc -filetype=obj -wasm-enable-eh -exception-model=wasm -mattr=+exception-handling %p/Inputs/tag-section2.ll -o %t2.o
 ; RUN: llc -filetype=obj -wasm-enable-eh -exception-model=wasm -mattr=+exception-handling %s -o %t.o
-; RUN: wasm-ld -o %t.wasm %t.o %t1.o %t2.o
-; RUN: wasm-ld --export-all -o %t-export-all.wasm %t.o %t1.o %t2.o
+; RUN: wasm-ld -o %t.wasm %t.o %t1.o %t2.o %t_tags.o
+; RUN: wasm-ld --export-all -o %t-export-all.wasm %t.o %t1.o %t2.o %t_tags.o
 ; RUN: obj2yaml %t.wasm | FileCheck %s --check-prefix=NOPIC
 ; RUN: obj2yaml %t-export-all.wasm | FileCheck %s --check-prefix=NOPIC-EXPORT-ALL
 
-; PIC code
+; PIC code with tags imported
 ; RUN: llc -filetype=obj -wasm-enable-eh -exception-model=wasm -mattr=+exception-handling -relocation-model=pic %p/Inputs/tag-section1.ll -o %t1.o
 ; RUN: llc -filetype=obj -wasm-enable-eh -exception-model=wasm -mattr=+exception-handling -relocation-model=pic %p/Inputs/tag-section2.ll -o %t2.o
 ; RUN: llc -filetype=obj -wasm-enable-eh -exception-model=wasm -mattr=+exception-handling -relocation-model=pic %s -o %t.o
-; RUN: wasm-ld --import-undefined --experimental-pic --unresolved-symbols=import-dynamic -pie -o %t.wasm %t.o %t1.o %t2.o
-; RUN: obj2yaml %t.wasm | FileCheck %s --check-prefix=PIC
+; RUN: wasm-ld --import-undefined --experimental-pic --unresolved-symbols=import-dynamic -pie -o %t_pic.wasm %t.o %t1.o %t2.o
+; RUN: obj2yaml %t_pic.wasm | FileCheck %s --check-prefix=PIC
 
 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
 target triple = "wasm32-unknown-emscripten"
@@ -49,7 +51,7 @@ define void @_start() {
 ; NOPIC-EXPORT-ALL:         Kind:            TAG
 ; NOPIC-EXPORT-ALL:         Index:           0
 
-; In PIC mode, tags are undefined and imported from JS.
+; In IMPORT mode, we leave the tags as undefined and they should be imported
 ; PIC:        Sections:
 ; PIC:         - Type:            TYPE
 ; PIC-NEXT:      Signatures:
diff --git a/lld/wasm/Relocations.cpp b/lld/wasm/Relocations.cpp
index 52888ad25034e..7d06fb977c619 100644
--- a/lld/wasm/Relocations.cpp
+++ b/lld/wasm/Relocations.cpp
@@ -156,9 +156,11 @@ void scanRelocations(InputChunk *chunk) {
       case R_WASM_MEMORY_ADDR_LEB64:
         // Certain relocation types can't be used when building PIC output,
         // since they would require absolute symbol addresses at link time.
-        error(toString(file) + ": relocation " + relocTypeToString(reloc.Type) +
-              " cannot be used against symbol `" + toString(*sym) +
-              "`; recompile with -fPIC");
+        if (!sym->isWeak()) {
+          error(toString(file) + ": relocation " + relocTypeToString(reloc.Type) +
+                " cannot be used against symbol `" + toString(*sym) +
+                "`; recompile with -fPIC");
+        }
         break;
       case R_WASM_TABLE_INDEX_I32:
       case R_WASM_TABLE_INDEX_I64:
diff --git a/llvm/lib/CodeGen/AsmPrinter/WasmException.cpp b/llvm/lib/CodeGen/AsmPrinter/WasmException.cpp
index bf65e525dde14..0309c65c7fb9d 100644
--- a/llvm/lib/CodeGen/AsmPrinter/WasmException.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/WasmException.cpp
@@ -19,29 +19,6 @@
 #include "llvm/MC/MCStreamer.h"
 using namespace llvm;
 
-void WasmException::endModule() {
-  // These are symbols used to throw/catch C++ exceptions and C longjmps. These
-  // symbols have to be emitted somewhere once in the module. Check if each of
-  // the symbols has already been created, i.e., we have at least one 'throw' or
-  // 'catch' instruction with the symbol in the module, and emit the symbol only
-  // if so.
-  //
-  // But in dynamic linking, it is in general not possible to come up with a
-  // module instantiating order in which tag-defining modules are loaded before
-  // the importing modules. So we make them undefined symbols here, define tags
-  // in the JS side, and feed them to each importing module.
-  if (!Asm->isPositionIndependent()) {
-    for (const char *SymName : {"__cpp_exception", "__c_longjmp"}) {
-      SmallString<60> NameStr;
-      Mangler::getNameWithPrefix(NameStr, SymName, Asm->getDataLayout());
-      if (Asm->OutContext.lookupSymbol(NameStr)) {
-        MCSymbol *ExceptionSym = Asm->GetExternalSymbolSymbol(SymName);
-        Asm->OutStreamer->emitLabel(ExceptionSym);
-      }
-    }
-  }
-}
-
 void WasmException::endFunction(const MachineFunction *MF) {
   bool ShouldEmitExceptionTable = false;
   for (const LandingPadInfo &Info : MF->getLandingPads()) {
diff --git a/llvm/lib/CodeGen/AsmPrinter/WasmException.h b/llvm/lib/CodeGen/AsmPrinter/WasmException.h
index 86cc37dfde079..9b545dfc98857 100644
--- a/llvm/lib/CodeGen/AsmPrinter/WasmException.h
+++ b/llvm/lib/CodeGen/AsmPrinter/WasmException.h
@@ -26,7 +26,7 @@ class LLVM_LIBRARY_VISIBILITY WasmException : public EHStreamer {
 public:
   WasmException(AsmPrinter *A) : EHStreamer(A) {}
 
-  void endModule() override;
+  void endModule() override {}
   void beginFunction(const MachineFunction *MF) override {}
   void endFunction(const MachineFunction *MF) override;
 
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
index db832bc91ddb5..6bb064a53eabd 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
@@ -249,13 +249,6 @@ MCSymbol *WebAssemblyAsmPrinter::getOrCreateWasmSymbol(StringRef Name) {
   SmallVector<wasm::ValType, 4> Params;
   if (Name == "__cpp_exception" || Name == "__c_longjmp") {
     WasmSym->setType(wasm::WASM_SYMBOL_TYPE_TAG);
-    // In static linking we define tag symbols in WasmException::endModule().
-    // But we may have multiple objects to be linked together, each of which
-    // defines the tag symbols. To resolve them, we declare them as weak. In
-    // dynamic linking we make tag symbols undefined in the backend, define it
-    // in JS, and feed them to each importing module.
-    if (!isPositionIndependent())
-      WasmSym->setWeak(true);
     WasmSym->setExternal(true);
 
     // Currently both C++ exceptions and C longjmps have a single pointer type
diff --git a/llvm/test/CodeGen/WebAssembly/exception-legacy.ll b/llvm/test/CodeGen/WebAssembly/exception-legacy.ll
index 149e443903a88..fe554c6fb607d 100644
--- a/llvm/test/CodeGen/WebAssembly/exception-legacy.ll
+++ b/llvm/test/CodeGen/WebAssembly/exception-legacy.ll
@@ -573,4 +573,5 @@ attributes #0 = { nounwind }
 attributes #1 = { noreturn }
 attributes #2 = { noreturn nounwind }
 
-; CHECK: __cpp_exception:
+;; The exception tag should not be defined locaally
+; CHECK-NOT: __cpp_exception:
diff --git a/llvm/test/CodeGen/WebAssembly/exception.ll b/llvm/test/CodeGen/WebAssembly/exception.ll
index fc42f050a687e..2e85ef1688619 100644
--- a/llvm/test/CodeGen/WebAssembly/exception.ll
+++ b/llvm/test/CodeGen/WebAssembly/exception.ll
@@ -670,4 +670,5 @@ attributes #0 = { nounwind }
 attributes #1 = { noreturn }
 attributes #2 = { noreturn nounwind }
 
-; CHECK: __cpp_exception:
+;; The exception tag should not be defined locaally
+; CHECK-NOT: __cpp_exception:
diff --git a/llvm/test/MC/WebAssembly/tag-section-decoding.ll b/llvm/test/MC/WebAssembly/tag-section-decoding.ll
deleted file mode 100644
index 4e3b7688e4806..0000000000000
--- a/llvm/test/MC/WebAssembly/tag-section-decoding.ll
+++ /dev/null
@@ -1,342 +0,0 @@
-; RUN: llc -filetype=obj -wasm-enable-eh -exception-model=wasm -mattr=+exception-handling %s -o - | obj2yaml | FileCheck %s
-
-; This is a regression test for a decoding bug that happens when a tag's
-; sigindex is greater than 63, so we put 63 dummy functions with different
-; signatures before the function that contains the 'throw' instruction to make
-; the tag's sigindex 64.
-
-target triple = "wasm32-unknown-unknown"
-
-declare void @llvm.wasm.throw(i32, ptr)
-
-define i32 @dummy0() {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy1(i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy2(i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy3(i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy4(i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy5(i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy6(i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy7(i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy8(i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy9(i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy10(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy11(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy12(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy13(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy14(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy15(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy16(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy17(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy18(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy19(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy20(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy21(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy22(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy23(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy24(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy25(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy26(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy27(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy28(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy29(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy30(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy31(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy32(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy33(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy34(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy35(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy36(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy37(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy38(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy39(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy40(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy41(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy42(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy43(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy44(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy45(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy46(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy47(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy48(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy49(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy50(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy51(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy52(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy53(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy54(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy55(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy56(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy57(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy58(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy59(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) {
-entry:
-  ret i32 0
-}
-
-define i32 @dummy60(i32, i32, i32, i32, i32, i32, i32, i3...
[truncated]

@sbc100
Copy link
Collaborator Author

sbc100 commented Sep 16, 2025

@aheejin @dschuff, I wonder what you think of this change.

The emscripten side change is here: emscripten-core/emscripten#25284

Technically I suppose is an ABI break since it will require any new object to be linked against a compiler-rt / libc that contains these tags, but it seems like a very low level internal detail that should be easy for toolchains to update to.

Copy link

github-actions bot commented Sep 16, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Member

@aheejin aheejin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM % comment

sbc100 added a commit to emscripten-core/emscripten that referenced this pull request Sep 17, 2025
These tags have also historically be weakly defined in each object file
by llvm (at least for non-PIC object files) but I hope to remove those
definitions going forward and instead rely on the toolchain/compiler-rt
to define them.

This will remove one of the distinctions between PIC and non-PIC
generated code.

This change can land here on the emscripten side before the
corresponding llvm changes since the strong definition I'm adding here
will always take precedence over any weak definitions in object files.

See llvm/llvm-project#159143
@sbc100 sbc100 changed the title [WebAssembly] Require tags for Wasm EH and Wasm SJLJ to be defined by compiler-rt [WebAssembly] Require tags for Wasm EH and Wasm SJLJ to be defined externally Sep 17, 2025
@sbc100 sbc100 force-pushed the external_tags branch 3 times, most recently from ae501eb to c422aec Compare September 17, 2025 22:21
@sbc100 sbc100 requested a review from petrhosek September 17, 2025 22:28
@sbc100
Copy link
Collaborator Author

sbc100 commented Sep 17, 2025

Adding @petrhosek for the compiler-rt additions. I could land this change without that part but it seems friendlier to downstream toolchains such as wasi-sdk to include these symbols in compiler-rt out-of-the-box.

Copy link
Member

@dschuff dschuff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we discussed this will mean that older object files will have forward compatibility with newer LLVM. It also means that new LLVM will need newer compiler-rt and libc++abi. I think that's fine since they should be distributed together.
BTW is this ABI documented in tool-conventions? Do we need to update that too?

//
//===----------------------------------------------------------------------===//

#ifdef __wasm_exception_handling__
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Weren't we going to put __cpp_exception into libc++abi instead of compiler-rt?

Copy link
Collaborator Author

@sbc100 sbc100 Sep 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think compiler-rt is fine for both of these symbols, they are both very low level symbols generated at codegen time.

Also, I'm not sure symbols like this that are arch-specific will be welcome in libc++abi (I imagine it has strict rules about naming and such, and we don't think we want rename these symbols at this point).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also think these symbols are lower level than even libcxxabi which contains publicly documents names and names that users themselves can reference if needed.

These tags are even lower level than C and their names cannot be referenced directly from C.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it just seemed to me that since it's C++-specific it could be in the C++ library. But I don't have a strong feeling about it; maybe @petrhosek has thoughts.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I should revert that part of this PR? Both emscripten and wasi-sdk can take care of defining these symbols in their runtime support code.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's fine if you don't want to wait to land this. We can always add it again later.

@sbc100
Copy link
Collaborator Author

sbc100 commented Sep 17, 2025

As we discussed this will mean that older object files will have forward compatibility with newer LLVM. It also means that new LLVM will need newer compiler-rt and libc++abi. I think that's fine since they should be distributed together. BTW is this ABI documented in tool-conventions? Do we need to update that too?

I had a realization while working on this: Older toolchains will "just work" with object file compiled with the new LLVM since their prebuilt libc++/libc/compiler-rt libraries will contain object files the weakly defined versions of these symbols. So this change should not break any existing toolchains.

Its only when a toolchain itself it rebuilt with the latest LLVM that the toolchain will have to be sure that it included the explicit versions of these symbols.

@sbc100
Copy link
Collaborator Author

sbc100 commented Sep 17, 2025

BTW is this ABI documented in tool-conventions? Do we need to update that too?

I don't think this ABI is documented anywhere yet. The ABI docs we have in tool-conventions pre-date Wasm EH I think. We should probably update them and include this.

… compiler-rt

Rather then defining these tags in each object file that requires them
we can can declare them as undefined and require that they defined
externally in, for example, compiler-rt.
@sbc100
Copy link
Collaborator Author

sbc100 commented Sep 18, 2025

OK, I reverted the compiler-rt changes for now. We can land them separately.

@sbc100 sbc100 merged commit cac54a8 into llvm:main Sep 19, 2025
9 checks passed
@sbc100 sbc100 deleted the external_tags branch September 19, 2025 17:11
SeongjaeP pushed a commit to SeongjaeP/llvm-project that referenced this pull request Sep 23, 2025
…ternally (llvm#159143)

Rather then defining these tags in each object file that requires them
we can can declare them as undefined and require that they defined
externally in, for example, compiler-rt or libcxxabi.
YixingZhang007 pushed a commit to YixingZhang007/llvm-project that referenced this pull request Sep 27, 2025
…ternally (llvm#159143)

Rather then defining these tags in each object file that requires them
we can can declare them as undefined and require that they defined
externally in, for example, compiler-rt or libcxxabi.
sbc100 added a commit to sbc100/llvm-project that referenced this pull request Oct 1, 2025
The `__c_longjmp` and `__cpp_exceptions` tags are used internally by
llvm to implement setjmp/longjmp and C++ exception handling
respectively.

These symbols were previously defined weakly in each object file but
were recently converted to external references in llvm#159143.  They now
need to be defined somewhere in the runtime libraries.  I think
compiler-rt is likely the most sensible place for them.
sbc100 added a commit that referenced this pull request Oct 1, 2025
The `__c_longjmp` and `__cpp_exceptions` tags are used internally by
llvm to implement setjmp/longjmp and C++ exception handling
respectively.

These symbols were previously defined weakly in each object file but
were recently converted to external references in #159143. They now need
to be defined somewhere in the runtime libraries. I think compiler-rt is
likely the most sensible place for them.
mahesh-attarde pushed a commit to mahesh-attarde/llvm-project that referenced this pull request Oct 3, 2025
…60959)

The `__c_longjmp` and `__cpp_exceptions` tags are used internally by
llvm to implement setjmp/longjmp and C++ exception handling
respectively.

These symbols were previously defined weakly in each object file but
were recently converted to external references in llvm#159143. They now need
to be defined somewhere in the runtime libraries. I think compiler-rt is
likely the most sensible place for them.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants