[clang] [clang][WebAssembly] Fix Wasm Vararg pointer width (PR #173580)

Folkert de Vries via cfe-commits cfe-commits at lists.llvm.org
Tue Dec 30 14:16:23 PST 2025


folkertdev wrote:

I believe this change is incomplete, consider

```rust
#![feature(c_variadic)]

#[unsafe(no_mangle)]
unsafe extern "C" fn foo(x: ...) -> u32 {
    let mut x = core::hint::black_box(x);
    let _ = unsafe { x.arg::<u32>() };
    unsafe { x.arg::<u32>() }
}

#[unsafe(no_mangle)]
unsafe extern "C" fn bar() -> u32 {
    foo(123u32, 456u32)
}
```

This currently produces

```asm
.type	bar, at function
bar:
	.functype	bar () -> (i32)
	.local  	i64, i32
	global.get __stack_pointer
	i64.const 16
	i64.sub 
	local.tee 0
	global.set __stack_pointer
	local.get 0
	i64.const 1958505087099
	i64.store 0
	local.get 0
	call foo
	local.set 1
	local.get 0
	i64.const 16
	i64.add 
	global.set __stack_pointer
	local.get 1
	end_function
```

where `1958505087099` is `123 | 456 << 32`. In other words, the call itself passes the arguments with a slot size of 4 as well. 

I believe that the slot size is mostly relevant for aligning the values in the variable arguments list. That might be less important for wasm, although the alignment of 64-bit integers is 8 on the vast majority of host targets that might run a wasm  interpreter.

https://github.com/llvm/llvm-project/pull/173580


More information about the cfe-commits mailing list