[llvm] Partial support for common linkage for WebAssembly (PR #151478)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 31 02:28:02 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-webassembly
Author: None (serge-sans-paille)
<details>
<summary>Changes</summary>
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
---
Full diff: https://github.com/llvm/llvm-project/pull/151478.diff
2 Files Affected:
- (modified) llvm/lib/MC/MCWasmStreamer.cpp (+24-1)
- (added) llvm/test/MC/WebAssembly/common.ll (+69)
``````````diff
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: ...
``````````
</details>
https://github.com/llvm/llvm-project/pull/151478
More information about the llvm-commits
mailing list