zig
zig copied to clipboard
stage2: function params get clobbered
Zig Version
0.9.0-dev.1686+696e51be4
Steps to Reproduce
compile and run this with the latest master stage2:
const plan9 = @import("std").os.plan9;
pub fn main() void {
const file = "a_file.f";
const str = "you got created!\n";
const fd = create(file, .ORDWR, 0o777);
_ = pwrite(fd, str, str.len, 0);
_ = close(fd);
}
pub fn pwrite(fd: usize, buf: [*]const u8, count: usize, offset: usize) usize {
return syscall4(.PWRITE, fd, @ptrToInt(buf), count, offset);
}
pub fn syscall4(sys: plan9.SYS, arg0: usize, arg1: usize, arg2: usize, arg3: usize) usize {
_ = sys;
_ = arg0;
_ = arg1;
_ = arg2;
_ = arg3;
if (arg1 == arg2) unreachable;
return arg1; // len
}
pub fn create(path: [*:0]const u8, omode: enum(usize) { ORDWR }, perms: usize) usize {
_ = path;
_ = omode;
_ = perms;
return 42;
}
pub fn close(fd: usize) usize {
if (fd != 42) unreachable;
return 0;
}
Expected Behavior
buf (arg1) and count (arg2) not to be the same in syscall4
Actual Behavior
buf (arg1) and count (arg2) are the same in syscall4:

Really interestingly, this issue goes away if we replace sys: plan9.SYS with sys: enum(usize) { PWRITE }, which is basically what std.os.plan9.SYS is:

The two assembly versions and the diff between them:
❯ cat zig/build-release/oldd
push rcx
push rsi
push rdi
push rbp
mov rbp,rsp
sub rsp,0x20
mov DWORD PTR [rbp-0x10],edi
mov DWORD PTR [rbp-0x18],esi
mov DWORD PTR [rbp-0x20],ecx
call QWORD PTR ds:0x4000068
mov rcx,rax
mov DWORD PTR [rbp-0x8],ecx
mov rax,QWORD PTR [rbp-0x8]
add rsp,0x20
pop rbp
pop rdi
pop rsi
pop rcx
ret
~/dev
❯ cat zig/build-release/newd
push rcx
push rsi
push rdi
push rbp
mov rbp,rsp
sub rsp,0x20
mov DWORD PTR [rbp-0x10],edi
mov rdi,0x33
mov DWORD PTR [rbp-0x18],esi
mov rsi,QWORD PTR [rbp-0x10]
mov rdx,QWORD PTR [rbp-0x18]
mov DWORD PTR [rbp-0x20],ecx
mov rcx,rdx
mov r8,QWORD PTR [rbp-0x20]
call QWORD PTR ds:0x4000068
mov rcx,rax
mov DWORD PTR [rbp-0x8],ecx
mov rax,QWORD PTR [rbp-0x8]
add rsp,0x20
pop rbp
pop rdi
pop rsi
pop rcx
ret
~/dev
❯ diff zig/build-release/oldd zig/build-release/newd
7a8
> mov rdi,0x33
8a10,11
> mov rsi,QWORD PTR [rbp-0x10]
> mov rdx,QWORD PTR [rbp-0x18]
9a13,14
> mov rcx,rdx
> mov r8,QWORD PTR [rbp-0x20]
~/dev
❯
new is using plan9.SYS, old is enum(usize) { PWRITE }