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

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

Fixed: https://github.com/llvm/llvm-project/issues/181527
This commit is contained in:
hanbeom 2026-03-26 21:04:57 +09:00 committed by GitHub
parent 77710f1420
commit bb7db7c15e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 39 additions and 10 deletions

View file

@ -197,16 +197,15 @@ void WebAssemblyAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
if (!Sym->getType()) {
SmallVector<MVT, 1> VTs;
Type *GlobalVT = GV->getValueType();
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);
}
// Function-specific subtargets are not needed here: WebAssembly
// coalesces features before isel, so use the TargetMachine's
// module-wide subtarget to compute legal value types.
auto &WasmTM = static_cast<const WebAssemblyTargetMachine &>(TM);
const WebAssemblySubtarget *ST = WasmTM.getSubtargetImpl();
const WebAssemblyTargetLowering &TLI = *ST->getTargetLowering();
computeLegalValueVTs(TLI, GV->getParent()->getContext(),
GV->getDataLayout(), GlobalVT, VTs);
WebAssembly::wasmSymbolSetType(Sym, GlobalVT, VTs);
}

View file

@ -0,0 +1,30 @@
; 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: .globaltype wasm_var, i32
; CHECK: .globl wasm_var
; CHECK-LABEL: wasm_var:
@wasm_var = addrspace(1) global i32 42
; CHECK: .globaltype wasm_var_float, f32
; CHECK: .globl wasm_var_float
; CHECK-LABEL: wasm_var_float:
@wasm_var_float = addrspace(1) global float 0x40091EB860000000
; CHECK: .globaltype wasm_var_i64, i64
; CHECK: .globl wasm_var_i64
; CHECK-LABEL: wasm_var_i64:
@wasm_var_i64 = addrspace(1) global i64 1234567890
; CHECK: .globaltype wasm_var_f64, f64
; CHECK: .globl wasm_var_f64
; CHECK-LABEL: wasm_var_f64:
@wasm_var_f64 = local_unnamed_addr addrspace(1) global double -0.0
; CHECK: .globaltype wasm_external, i32
; CHECK-NOT: .global wasm_external
; CHECK-NOT: wasm_external:
@wasm_external = external addrspace(1) global i32