Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

asm goto miscompilation #74483

Copy link
Copy link
@dvyukov

Description

@dvyukov
Issue body actions

As far as I understand asm goto now supports output arguments on all paths. If I am reading this correctly, in this case asm goto corrupts local state (output variable has incorrect value). The code is:

#include <stdio.h>

long foo(long a, long b) {
    long x, y, z;
    asm goto(
      "movq %[a], %[x]; testq %[a], %[a]; jnz %l[label1]"
        : [x] "=&r"(x), [y] "=&r"(y), [z] "=&r"(z)
        : [a]"r"(a), [b]"r"(b)
        : "memory" : label1, label2);
    return 0;
    {
        label1:
        return x;
    }
    label2:
    return 1;
}

int main() {
  printf("%lu\n", foo(11, 22));
}

With -O3 the program correctly prints 11:
https://godbolt.org/z/x17GnP4nK

But with -O0 it prints 0:
https://godbolt.org/z/h7MM9YTfP

The generated code is:

foo(long, long):                               # @foo(long, long)
        pushq   %rbp
        movq    %rsp, %rbp
        movq    %rdi, -16(%rbp)
        movq    %rsi, -24(%rbp)
        movq    -16(%rbp), %rsi
        movq    -24(%rbp), %rdi
        movq    %rsi, %rax
        testq   %rsi, %rsi
        jne     .LBB0_2
        movq    %rdx, -96(%rbp)                 # 8-byte Spill
        movq    %rcx, -88(%rbp)                 # 8-byte Spill
        movq    %rax, -80(%rbp)                 # 8-byte Spill
        movq    %rdx, -72(%rbp)                 # 8-byte Spill
        movq    %rcx, -64(%rbp)                 # 8-byte Spill
        movq    %rax, -56(%rbp)                 # 8-byte Spill
        jmp     .LBB0_1
.LBB0_1:
        movq    -72(%rbp), %rax                 # 8-byte Reload
        movq    -64(%rbp), %rcx                 # 8-byte Reload
        movq    -56(%rbp), %rdx                 # 8-byte Reload
        movq    %rdx, -32(%rbp)
        movq    %rcx, -40(%rbp)
        movq    %rax, -48(%rbp)
        movq    $0, -8(%rbp)
        jmp     .LBB0_6
.LBB0_2:                                # Block address taken
        movq    %rdx, -96(%rbp)                 # 8-byte Spill
        movq    -80(%rbp), %rdx                 # 8-byte Reload
        movq    %rcx, -88(%rbp)                 # 8-byte Spill
        movq    -88(%rbp), %rcx                 # 8-byte Reload
        movq    %rax, -80(%rbp)                 # 8-byte Spill
        movq    -96(%rbp), %rax                 # 8-byte Reload
        movq    %rdx, -32(%rbp)
        movq    %rcx, -40(%rbp)
        movq    %rax, -48(%rbp)
        jmp     .LBB0_4
.LBB0_3:                                # Block address taken
        movq    %rdx, -96(%rbp)                 # 8-byte Spill
        movq    -80(%rbp), %rdx                 # 8-byte Reload
        movq    %rcx, -88(%rbp)                 # 8-byte Spill
        movq    -88(%rbp), %rcx                 # 8-byte Reload
        movq    %rax, -80(%rbp)                 # 8-byte Spill
        movq    -96(%rbp), %rax                 # 8-byte Reload
        movq    %rdx, -32(%rbp)
        movq    %rcx, -40(%rbp)
        movq    %rax, -48(%rbp)
        jmp     .LBB0_5
.LBB0_4:
        movq    -32(%rbp), %rax
        movq    %rax, -8(%rbp)
        jmp     .LBB0_6
.LBB0_5:
        movq    $1, -8(%rbp)
.LBB0_6:
        movq    -8(%rbp), %rax
        popq    %rbp
        retq

If we track the x variable, it's spilled to -80(%rbp), but then loaded from -32(%rbp):

foo(long, long):                               # @foo(long, long)
...
        movq    %rsi, %rax
...
        jne     .LBB0_2
...
.LBB0_2:                                # Block address taken
...
        movq    %rax, -80(%rbp)                 # 8-byte Spill
...
        jmp     .LBB0_4
...
.LBB0_4:
        movq    -32(%rbp), %rax
        movq    %rax, -8(%rbp)
        jmp     .LBB0_6
...
.LBB0_6:
        movq    -8(%rbp), %rax
        popq    %rbp
        retq

Metadata

Metadata

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    Morty Proxy This is a proxified and sanitized view of the page, visit original site.