[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