#Why is zig passing a @Vector(4, i32) on the stack in my local builds?

1 messages · Page 1 of 1 (latest)

fervent slate
#

I'm compiling this code locally and emitting the assembly:

pub fn bar(foo: @Vector(4, i32)) @Vector(4, i32) {
    return foo + @as(@Vector(4, i32), .{ 1, 2, 3, 4 });
}```
LLVM generates the following:
```asm
.LCPI1_0:
    .long    1
    .long    2
    .long    3
    .long    4
    .text
    .p2align    4, 0x90
main.bar:
    push    rbp
    mov    rbp, rsp
    vmovdqa    xmm0, xmmword ptr [rcx]
    vpaddd    xmm0, xmm0, xmmword ptr [rip + .LCPI1_0]
    pop    rbp
    ret

However, godbolt (https://godbolt.org/z/v438xWePT) generates the following, which passes the parameter in xmm0 instead of the stack:

.LCPI0_0:
        .long   1
        .long   2
        .long   3
        .long   4
example.bar:
        push    rbp
        mov     rbp, rsp
        vpaddd  xmm0, xmm0, xmmword ptr [rip + .LCPI0_0]
        pop     rbp
        ret

Why is godbolt's output different?
If relevant, here is my build.zig: https://zigbin.io/3b91f9
The build command I run locally is zig build asm -Doptimize=ReleaseFast

fossil cloud
#

what OS are you on?

fervent slate
#

windows

#

are u srs

fossil cloud
#

Any argument that doesn't fit in 8 bytes, or isn't 1, 2, 4, or 8 bytes, must be passed by reference.

#

you can use vectorcall on windows to make it pass the args in xmm0

fervent slate
#

this is so cooked </3

#

i will shrimply compile for linux instead

#

wait, i thought the default calling convention for non export functions was whatever deemed to be the fastest?

fossil cloud
#

in my experience it kinda just uses callconv(.c)

#

tbh it should maybe use vectorcall on windows

#

or even sysv

#

since windows calling convention is so bad

#

sysv on windows would mean you have to do some possibly expensive stack fixup on boundaries between zig functions and extern/export functions