Skip to content

Using gnu_asm_goto_with_outputs_full without optimizations returns uninitialized memory #60855

Closed
@josephcsible

Description

@josephcsible

Consider this C code:

#if !__has_extension(gnu_asm_goto_with_outputs_full)
#error Need the gnu_asm_goto_with_outputs_full extension
#endif
int main(void) {
    int x = 123;
    asm goto("mov %1, %0\n\tjmp %l[label]" : "=r" (x) : "r" (45) : : label);
    x = 6;
    label:
    return x;
}

It's supposed to return 45. But when compiled on Clang trunk (4be1764) without optimizations, it produces this assembly:

main:                                   # @main
        pushq   %rbp
        movq    %rsp, %rbp
        movl    $0, -4(%rbp)
        movl    $123, -8(%rbp)
        movl    $45, %eax
        movl    %eax, %eax
        jmp     .LBB0_3
        movl    %eax, -16(%rbp)                 # 4-byte Spill
        movl    %eax, -12(%rbp)                 # 4-byte Spill
        jmp     .LBB0_1
.LBB0_1:
        movl    -12(%rbp), %eax                 # 4-byte Reload
        movl    %eax, -8(%rbp)
        movl    $6, -8(%rbp)
.LBB0_2:
        movl    -8(%rbp), %eax
        popq    %rbp
        retq
.LBB0_3:                                # Block address taken
        movl    -16(%rbp), %eax                 # 4-byte Reload
        movl    %eax, -8(%rbp)
        jmp     .LBB0_2

Which ends up returning uninitialized memory (the -16(%rbp) from the third-to-last line) instead. If I instead compile with any optimization level (other than -O0), then it produces correct assembly.

https://godbolt.org/z/fnPcYY44G

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions