[llvm] [WebAssembly] Emit i64 GOT import globals on wasm64 (PR #226326)
Patrick Rachford via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 24 16:05:57 PDT 2026
https://github.com/rachfop created https://github.com/llvm/llvm-project/pull/226326
WasmObjectWriter hardcodes the synthetic GOT import globals
(GOT.mem/GOT.func) to i32, but on wasm64 they hold 64-bit addresses,
so the object is type-invalid against the i64 global.get that consumes
them. wasm-ld already emits i64 GOT imports on wasm64, so this aligns
the object writer with the linker: the import type is gated on
is64Bit(), and the reloc-pic64 expectations are updated. The wasm32
checks are unchanged.
>From 05ef85a298b674c121b9f45a5497fc2b8dbd7d2d Mon Sep 17 00:00:00 2001
From: rachfop <prachford at icloud.com>
Date: Thu, 24 Sep 2026 18:01:06 -0500
Subject: [PATCH] [WebAssembly] Emit i64 GOT import globals on wasm64
WasmObjectWriter::prepareImports hardcodes the synthetic GOT import
globals (GOT.mem/GOT.func) to i32. On wasm64 those globals hold 64-bit
addresses: the code consuming them expects an i64 from global.get, so
the emitted object is type-invalid, and wasm-ld has to work around the
mismatch when relocating against the import.
wasm-ld already synthesizes its GOT imports as i64 on wasm64
(lld/wasm/SyntheticSections.cpp), so the writer is the outlier. Gate
the import type on is64Bit(), the same check the writer's linear-memory
import already uses for WASM_LIMITS_FLAG_IS_64.
Update the reloc-pic64 expectations; wasm32 output is unchanged and
reloc-pic.s passes as-is.
---
llvm/lib/MC/WasmObjectWriter.cpp | 4 +++-
llvm/test/MC/WebAssembly/reloc-pic64.s | 4 ++--
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp
index aa3edd82ff30a6..3bf5b4616c55c3 100644
--- a/llvm/lib/MC/WasmObjectWriter.cpp
+++ b/llvm/lib/MC/WasmObjectWriter.cpp
@@ -1430,7 +1430,9 @@ void WasmObjectWriter::prepareImports(
Import.Module = "GOT.mem";
Import.Field = WS.getName();
Import.Kind = wasm::WASM_EXTERNAL_GLOBAL;
- Import.Global = {wasm::WASM_TYPE_I32, true};
+ Import.Global = {static_cast<uint8_t>(is64Bit() ? wasm::WASM_TYPE_I64
+ : wasm::WASM_TYPE_I32),
+ true};
Imports.push_back(Import);
assert(!GOTIndices.contains(&WS));
GOTIndices[&WS] = NumGlobalImports++;
diff --git a/llvm/test/MC/WebAssembly/reloc-pic64.s b/llvm/test/MC/WebAssembly/reloc-pic64.s
index 743bba33749bd4..d46c11131a7d1f 100644
--- a/llvm/test/MC/WebAssembly/reloc-pic64.s
+++ b/llvm/test/MC/WebAssembly/reloc-pic64.s
@@ -98,12 +98,12 @@ hidden_func:
# CHECK-NEXT: - Module: GOT.mem
# CHECK-NEXT: Field: default_data
# CHECK-NEXT: Kind: GLOBAL
-# CHECK-NEXT: GlobalType: I32
+# CHECK-NEXT: GlobalType: I64
# CHECK-NEXT: GlobalMutable: true
# CHECK-NEXT: - Module: GOT.func
# CHECK-NEXT: Field: default_func
# CHECK-NEXT: Kind: GLOBAL
-# CHECK-NEXT: GlobalType: I32
+# CHECK-NEXT: GlobalType: I64
# CHECK-NEXT: GlobalMutable: true
# CHECK-NEXT: - Type: FUNCTION
# CHECK-NEXT: FunctionTypes: [ 0, 0, 1, 1, 0 ]
More information about the llvm-commits
mailing list