Skip to content

Inline asm memory operands not properly referenced #10367

Open
@N00byEdge

Description

@N00byEdge

Zig compiler version

0.11.0-dev.4271+1aacfa718

Steps to reproduce

Equivalent C code, works fine with gcc:

void f() {
    asm volatile("movl %[value], %[ptr]"
            :
            : [ptr] "m" (*(volatile int *)0x444444)
            , [value] "ir" ((int)0x414141)
            : "memory"
    );
}

In zig:

export fn f() void {
    asm volatile ("movl %[value], %[ptr]"
        :
        : [ptr] "m" (@as(*volatile u32, @ptrFromInt(0x444444)).*)
        , [value] "ir" (@as(u32, 0x414141))
        : "memory"
    );
}

The memory operand ("m") takes a memory reference, not a value (you should dereference a pointer or provide a value on the stack in the operand)

Expected behaviour

Something equivalent to the C codegen:

 mov    eax,0x444444
 mov    DWORD PTR [rax],0x414141 // This is the generated inline asm instr

Actual behaviour

Zig is deciding to dereference the pointer, but providing the memory location on the stack with the dereferenced value, not actually storing the value to the requested memory operand

 mov    eax,0x444444
 mov    eax, DWORD PTR [rax]
 mov    DWORD PTR [rbp - offset], eax
 mov    DWORD PTR [rbp - offset], 0x414141 // This is the generated inline asm instr

Notes

I know this may be a hard issue to solve, but I suggest at least disabling memory operands that take a pointer deref/other rvalue with a link to this issue for now. Passing a stack variable as a memory operand still works.

Metadata

Metadata

Assignees

No one assigned

    Labels

    arch-x86_6464-bit x86backend-llvmThe LLVM backend outputs an LLVM IR Module.bugObserved behavior contradicts documented or intended behaviormiscompilationThe compiler reports success but produces semantically incorrect code.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions