[llvm] Partial support for common linkage for WebAssembly (PR #151478)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 31 02:27:28 PDT 2025


https://github.com/serge-sans-paille created https://github.com/llvm/llvm-project/pull/151478

Emulate common linkage through weak linkage, the only difference between the two being mostly similar according to langref, with the notable exception that common linkage implies zero initializer.

This is needed for fortran-to-web-assembly projects used in the python community, esp.

https://github.com/emscripten-forge/recipes/tree/main/recipes/recipes_emscripten/libflang

>From ce491c59bb251e100fb875b2fb952ea809395511 Mon Sep 17 00:00:00 2001
From: serge-sans-paille <sguelton at mozilla.com>
Date: Wed, 9 Apr 2025 07:43:08 +0200
Subject: [PATCH] Partial support for common linkage for WebAssembly

Emulate common linkage through weak linkage, the only difference between
the two being mostly similar according to langref, with the notable
exception that common linkage implies zero initializer.

This is needed for fortran-to-web-assembly projects used in the python
community, esp.

https://github.com/emscripten-forge/recipes/tree/main/recipes/recipes_emscripten/libflang
---
 llvm/lib/MC/MCWasmStreamer.cpp     | 25 ++++++++++-
 llvm/test/MC/WebAssembly/common.ll | 69 ++++++++++++++++++++++++++++++
 2 files changed, 93 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/MC/WebAssembly/common.ll

diff --git a/llvm/lib/MC/MCWasmStreamer.cpp b/llvm/lib/MC/MCWasmStreamer.cpp
index e3ef1117b4125..c5249db753ec6 100644
--- a/llvm/lib/MC/MCWasmStreamer.cpp
+++ b/llvm/lib/MC/MCWasmStreamer.cpp
@@ -14,6 +14,7 @@
 #include "llvm/MC/MCAsmBackend.h"
 #include "llvm/MC/MCAssembler.h"
 #include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCFixup.h"
 #include "llvm/MC/MCObjectStreamer.h"
@@ -131,7 +132,29 @@ bool MCWasmStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
 
 void MCWasmStreamer::emitCommonSymbol(MCSymbol *S, uint64_t Size,
                                       Align ByteAlignment) {
-  llvm_unreachable("Common symbols are not yet implemented for Wasm");
+  auto *Symbol = cast<MCSymbolWasm>(S);
+
+  pushSection();
+
+  // Common symbols are very close to weak symbols, so manually build a weak
+  // symbol.
+  MCSectionWasm *SW = getContext().getWasmSection(".bss.common." + S->getName(),
+                                                  SectionKind::getData());
+  SW->setAlignment(ByteAlignment);
+  getAssembler().registerSection(*SW);
+
+  switchSection(SW);
+
+  MCDataFragment *DF = getOrCreateDataFragment();
+  DF->setContents(std::vector<char>(Size, '\0'));
+  Symbol->setFragment(DF);
+
+  Symbol->setSize(MCConstantExpr::create(Size, getContext(), false, 8));
+  Symbol->setWeak(true);
+  Symbol->setExternal(true);
+  getAssembler().registerSymbol(*Symbol);
+
+  popSection();
 }
 
 void MCWasmStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
diff --git a/llvm/test/MC/WebAssembly/common.ll b/llvm/test/MC/WebAssembly/common.ll
new file mode 100644
index 0000000000000..50e7298684ccb
--- /dev/null
+++ b/llvm/test/MC/WebAssembly/common.ll
@@ -0,0 +1,69 @@
+; RUN; llc -mcpu=mvp -filetype=obj %s -o - | obj2yaml | FileCheck %s
+; RUN; llc -mcpu=mvp -filetype=asm %s -asm-verbose=false -o -  | FileCheck --check-prefix=ASM %s
+; RUN: llc -mcpu=mvp -filetype=asm %s -o - | llvm-mc -triple=wasm32 -filetype=obj  -o - | obj2yaml | FileCheck %s
+
+target triple = "wasm32-unknown-unknown"
+;target triple = "x86_64-redhat-linux-gnu"
+ at b = common dso_local global [10 x i32] zeroinitializer, align 4
+ at c = common dso_local global [20 x i32] zeroinitializer, align 32
+
+; CHECK-ASM: .file	"common.ll"
+; CHECK-ASM: .type	b, at object
+; CHECK-ASM: .comm	b,40,2
+; CHECK-ASM: .type	c, at object
+; CHECK-ASM: .comm	c,80,5
+
+
+; CHECK:      --- !WASM
+; CHECK-NEXT: FileHeader:
+; CHECK-NEXT:   Version:         0x1
+; CHECK-NEXT: Sections:
+; CHECK-NEXT:   - Type:            IMPORT
+; CHECK-NEXT:     Imports:
+; CHECK-NEXT:       - Module:          env
+; CHECK-NEXT:         Field:           __linear_memory
+; CHECK-NEXT:         Kind:            MEMORY
+; CHECK-NEXT:         Memory:
+; CHECK-NEXT:           Minimum:         0x1
+; CHECK-NEXT:   - Type:            DATACOUNT
+; CHECK-NEXT:     Count:           2
+; CHECK-NEXT:   - Type:            DATA
+; CHECK-NEXT:     Segments:
+; CHECK-NEXT:       - SectionOffset:   6
+; CHECK-NEXT:         InitFlags:       0
+; CHECK-NEXT:         Offset:
+; CHECK-NEXT:           Opcode:          I32_CONST
+; CHECK-NEXT:           Value:           0
+; CHECK-NEXT:         Content:         '00000000000000000000000000000000000000000000000000000000000000000000000000000000'
+; CHECK-NEXT:       - SectionOffset:   52
+; CHECK-NEXT:         InitFlags:       0
+; CHECK-NEXT:         Offset:
+; CHECK-NEXT:           Opcode:          I32_CONST
+; CHECK-NEXT:           Value:           64
+; CHECK-NEXT:         Content:         '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
+; CHECK-NEXT:   - Type:            CUSTOM
+; CHECK-NEXT:     Name:            linking
+; CHECK-NEXT:     Version:         2
+; CHECK-NEXT:     SymbolTable:
+; CHECK-NEXT:       - Index:           0
+; CHECK-NEXT:         Kind:            DATA
+; CHECK-NEXT:         Name:            b
+; CHECK-NEXT:         Flags:           [ BINDING_WEAK ]
+; CHECK-NEXT:         Segment:         0
+; CHECK-NEXT:         Size:            40
+; CHECK-NEXT:       - Index:           1
+; CHECK-NEXT:         Kind:            DATA
+; CHECK-NEXT:         Name:            c
+; CHECK-NEXT:         Flags:           [ BINDING_WEAK ]
+; CHECK-NEXT:         Segment:         1
+; CHECK-NEXT:         Size:            80
+; CHECK-NEXT:     SegmentInfo:
+; CHECK-NEXT:       - Index:           0
+; CHECK-NEXT:         Name:            .bss.common.b
+; CHECK-NEXT:         Alignment:       2
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT:       - Index:           1
+; CHECK-NEXT:         Name:            .bss.common.c
+; CHECK-NEXT:         Alignment:       5
+; CHECK-NEXT:         Flags:           [  ]
+; CHECK-NEXT: ...



More information about the llvm-commits mailing list