zig
zig copied to clipboard
`@max(i64, 0)` generates invalid wasm in debug with `reference_types` enabled
Zig Version
0.14.0-dev.184+bf588f67d
Steps to Reproduce and Observed Behavior
Create bug.zig
const std = @import("std");
export fn foo(
position_x: i64,
) void {
const start_x = @max(position_x, 0);
std.mem.doNotOptimizeAway(start_x);
}
Compile with
- wasm32-freestanding
- Debug
- reference_types feature enabled
zig build-exe bug.zig -target wasm32-freestanding -fno-entry --export=foo -mcpu baseline+reference_types -ODebug
Validate with wabt's wasm-validate
wasm-validate bug.wasm
bug.wasm:000006a: error: type mismatch in call, expected [i64] but got [i32]
bug.wat
created with wasm2wat bug.wasm -o bug.wat --no-check
(module $bug.wasm
(type (;0;) (func (param i64)))
(type (;1;) (func (param i32)))
(func $foo (type 0) (param i64)
(local i64 i32 i64 i32)
i64.const 0
local.set 1
local.get 0
local.get 1
i64.gt_s
local.set 2
local.get 0
local.get 1
local.get 2
select
local.set 3
local.get 3
i32.wrap_i64
local.set 4
local.get 4
call $mem.doNotOptimizeAway__anon_1111
return)
(func $mem.doNotOptimizeAway__anon_1111 (type 0) (param i64)
(local i32 i32 i32 i64 i64 i32 i32 i32 i32 i32)
global.get $__stack_pointer
local.set 1
i32.const 16
local.set 2
local.get 1
local.get 2
i32.sub
local.set 3
local.get 3
global.set $__stack_pointer
i64.const 9223372036854775807
local.set 4
local.get 0
local.get 4
i64.and
local.set 5
local.get 3
local.get 5
i64.store offset=8
i32.const 8
local.set 6
local.get 3
local.get 6
i32.add
local.set 7
local.get 7
local.set 8
local.get 8
call $mem.doNotOptimizeAway__anon_1112
i32.const 16
local.set 9
local.get 3
local.get 9
i32.add
local.set 10
local.get 10
global.set $__stack_pointer
return)
(func $mem.doNotOptimizeAway__anon_1112 (type 1) (param i32)
(local i32 i32 i32 i32 i32 i32 i32 i32 i32)
global.get $__stack_pointer
local.set 1
i32.const 16
local.set 2
local.get 1
local.get 2
i32.sub
local.set 3
local.get 3
global.set $__stack_pointer
local.get 3
local.get 0
i32.store offset=12
i32.const 12
local.set 4
local.get 3
local.get 4
i32.add
local.set 5
local.get 3
local.get 5
i32.store offset=8
i32.const 8
local.set 6
local.get 3
local.get 6
i32.add
local.set 7
i32.const 16
local.set 8
local.get 3
local.get 8
i32.add
local.set 9
local.get 9
global.set $__stack_pointer
return)
(memory (;0;) 16)
(global $__stack_pointer (mut i32) (i32.const 1048576))
(export "memory" (memory 0))
(export "foo" (func $foo)))
Workaround:
@max with 0 creates u63. Changing the type back to i64 fixes the problem.
- const start_x = @max(position_x, 0);
+ const start_x: i64 = @max(position_x, 0);
Expected Behavior
Emitted wasm file is valid.