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.