[Bug c/114437] New: Inline asm with "+m,r" operand ignores input value
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114437 Bug ID: 114437 Summary: Inline asm with "+m,r" operand ignores input value Product: gcc Version: 13.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: xog4n...@a-n.cc Target Milestone: --- In the following snippet, GCC seems to assume that `arg` is not read by the asm statement and optimizes out previous stores when compiling on -O3: ``` extern int external_fn(int); extern int arg; int fn() { arg = 123; asm volatile("" : "+m,r"(arg) : : "memory"); return external_fn(arg); } ``` Resulting asm (123 is not stored, leaving `arg` uninitialized): ``` : 0: f3 0f 1e fa endbr64 4: 8b 3d 00 00 00 00 movedi,DWORD PTR [rip+0x0]# a a: e9 00 00 00 00 jmpf ``` The asm snippet comes from the `DoNotOptimize` function in Google Benchmark, where it is intended to prevent the compiler from optimizing away parts of a micro-benchmark: https://github.com/google/benchmark/blob/main/include/benchmark/benchmark.h#L518 Godbolt reproduction: https://godbolt.org/z/3W97dM9eW
[Bug middle-end/114437] Inline asm with "+m, r" operand ignores input value
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114437 --- Comment #3 from xog4n...@a-n.cc --- Just to confirm, is this an incorrect constraint for the intended goal of convincing the compiler that the value is used and modified, without actually doing either and preserving the value, or am I just using it wrong in this particular example? I'm somewhat surprised since this inline asm snippet is used in multiple well-known micro-benchmarking libraries. Is the following version correct? ``` asm volatile("" : "=m,r"(arg) : "0,0"(arg) : "memory"); ```
[Bug middle-end/114437] Inline asm with "+m, r" operand ignores input value
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114437 xog4n...@a-n.cc changed: What|Removed |Added Resolution|DUPLICATE |INVALID --- Comment #5 from xog4n...@a-n.cc --- I would prefer to use something else, but I'm not aware of any less hacky way to ensure that the compiler does not interfere with a benchmark. If there's any explicitly supported way to achieve that in GCC, I'm all ears, but I don't assume so given that each and every C++ benchmarking library I know uses inline asm.