https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128109

            Bug ID: 128109
           Summary: Unexpected result with "+m,r" asm operand
           Product: gcc
           Version: 16.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mumumu0722 at gmail dot com
  Target Milestone: ---

On x86_64-linux-gnu, the following program prints an unexpected value with GCC
16.2.0 at -O1 or -O2. Without optimization (-O0), the program prints the
expected value.

```
#include <stdio.h>

__attribute__((noinline))
int test(int *p)
{
    int observed;
    *p = 1;
    __asm__ volatile ("movl %1, %0"
                      : "=r,r" (observed), "+m,r" (*p));
    *p = 2;
    return observed;
}

int main(void)
{
    int x = 0;
    printf("expected: 1, actual: %d\n", test(&x));
}
```

```
gcc -O2 poc.c -o poc
./poc
# expected: 1, actual: 32766
```

Expected: observed == 1 -> "expected: 1, actual: 1" 

Actual: "expected: 1, actual: 32766" (the actual number varies). It seems that
*p = 1 is deleted in test:

test:
        movl (%rdi), %eax
        movl    $2, (%rdi)
        ret

https://godbolt.org/z/ndTWvoxbP

To my understanding, PR 124958 also concerns `"+m,r"`, but reports an incorrect
pointer access. In contrast, this testcase shows the elimination of a store to
`*p` before the inline assembly, even though the assembly reads its value.

Additional observations: -O2 -fno-dse produces the expected result.

Reply via email to