[llvm] [WebAssembly] Fix null Subtarget crash for addrspace(1) globals (PR #181536)

via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 15 04:19:38 PST 2026


https://github.com/ParkHanbum updated https://github.com/llvm/llvm-project/pull/181536

>From 2f1555badaffb78e3d27f886eeaab3b63d2c3175 Mon Sep 17 00:00:00 2001
From: hanbeom <kese111 at gmail.com>
Date: Sun, 15 Feb 2026 17:12:50 +0900
Subject: [PATCH 1/2] [WebAssembly] Fix null Subtarget crash for addrspace(1)
 globals

If Subtarget is null during global emission, it is now retrieved
from TargetMachine to prevent crashes caused by empty VTs in
wasmSymbolSetType.

Fixed: #181527
---
 .../Target/WebAssembly/WebAssemblyAsmPrinter.cpp | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
index 1cacdb04fa74d..a088b67a5eedc 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
@@ -197,16 +197,22 @@ void WebAssemblyAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
   if (!Sym->getType()) {
     SmallVector<MVT, 1> VTs;
     Type *GlobalVT = GV->getValueType();
-    if (Subtarget) {
+    if (!Subtarget) {
       // Subtarget is only set when a function is defined, because
       // each function can declare a different subtarget. For example,
       // on ARM a compilation unit might have a function on ARM and
       // another on Thumb. Therefore only if Subtarget is non-null we
-      // can actually calculate the legal VTs.
-      const WebAssemblyTargetLowering &TLI = *Subtarget->getTargetLowering();
-      computeLegalValueVTs(TLI, GV->getParent()->getContext(),
-                           GV->getDataLayout(), GlobalVT, VTs);
+      // can actually calculate the legal VTs. Therefore, if Subtarget
+      // is null, we retrieve the default subtarget from TargetMachine
+      // to calculate the legal VTs.
+      auto &WasmTM = static_cast<const WebAssemblyTargetMachine &>(TM);
+      Subtarget = WasmTM.getSubtargetImpl();
     }
+
+    const WebAssemblyTargetLowering &TLI = *Subtarget->getTargetLowering();
+    computeLegalValueVTs(TLI, GV->getParent()->getContext(),
+                         GV->getDataLayout(), GlobalVT, VTs);
+
     WebAssembly::wasmSymbolSetType(Sym, GlobalVT, VTs);
   }
 

>From 75bda2ef40422224420e2647f15031a4bd52fa8e Mon Sep 17 00:00:00 2001
From: Hanbum Park <kese111 at gmail.com>
Date: Sun, 15 Feb 2026 21:19:03 +0900
Subject: [PATCH 2/2] add test

---
 .../CodeGen/WebAssembly/global-addrspace.ll   | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)
 create mode 100644 llvm/test/CodeGen/WebAssembly/global-addrspace.ll

diff --git a/llvm/test/CodeGen/WebAssembly/global-addrspace.ll b/llvm/test/CodeGen/WebAssembly/global-addrspace.ll
new file mode 100644
index 0000000000000..c0dd5ff56c8e7
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/global-addrspace.ll
@@ -0,0 +1,20 @@
+; RUN: llc < %s -mtriple=wasm32-unknown-unknown | FileCheck %s
+
+;; This test ensures that globals in addrspace(1) (Wasm-specific variables)
+;; do not cause a crash during emission when Subtarget is not set
+;; (e.g., in modules without functions) and correctly emit their initializers.
+
+; CHECK-LABEL: .globaltype wasm_var, i32
+; CHECK-NEXT: .globl wasm_var
+; CHECK-NEXT: wasm_var:
+ at wasm_var = addrspace(1) global i32 42
+
+; CHECK-LABEL: .globaltype wasm_var_float, f32
+; CHECK-NEXT: .globl wasm_var_float
+; CHECK-NEXT: wasm_var_float:
+ at wasm_var_float = addrspace(1) global float 0x40091EB860000000
+
+; CHECK-LABEL: .globaltype     wasm_var_i64, i64
+; CHECK-NEXT: .globl  wasm_var_i64
+; CHECK-NEXT: wasm_var_i64:
+ at wasm_var_i64 = addrspace(1) global i64 1234567890



More information about the llvm-commits mailing list