https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121560
Bug ID: 121560 Summary: Atomic no-operations are not optimized away Product: gcc Version: 16.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: sebastian.hu...@embedded-brains.de Target Milestone: --- Relaxed atomic operations which do not change the value of an atomic object and the current value is not used are not optimized away. Consider the following test cases. #include <stdatomic.h> void f(int *i) { *i += 0; } void g(atomic_int *i) { (void)atomic_fetch_add_explicit(i, 0, memory_order_relaxed); } gcc -O2 -S -o - test.c -fdump-tree-all ;; Function f (f, funcdef_no=0, decl_uid=4680, cgraph_uid=1, symbol_order=0) void f (int * i) { <bb 2> [local count: 1073741824]: return; } ;; Function g (g, funcdef_no=1, decl_uid=4683, cgraph_uid=2, symbol_order=1) void g (atomic atomic_int * i) { <bb 2> [local count: 1073741824]: __atomic_fetch_add_4 (i_2(D), 0, 0); [tail call] return; } Another test case with instrumented code: int a(int i); int b(int i); int f(int i) { if (i) { return a(i); } else { return b(i); } } gcc -O2 -fprofile-update=atomic -fcondition-coverage -S -o - test.c -fdump-tree-all ;; Function f (f, funcdef_no=0, decl_uid=4621, cgraph_uid=1, symbol_order=0) int f (int i) { int _1; int _6; int _8; <bb 2> [local count: 1073741824]: if (i_3(D) != 0) goto <bb 3>; [50.00%] else goto <bb 4>; [50.00%] <bb 3> [local count: 536870912]: __atomic_fetch_or_8 (&__gcov8.f[0], 1, 0); __atomic_fetch_or_8 (&__gcov8.f[1], 0, 0); _8 = a (i_3(D)); [tail call] goto <bb 5>; [100.00%] <bb 4> [local count: 536870912]: __atomic_fetch_or_8 (&__gcov8.f[0], 0, 0); __atomic_fetch_or_8 (&__gcov8.f[1], 1, 0); _6 = b (0); [tail call] <bb 5> [local count: 1073741824]: # _1 = PHI <_8(3), _6(4)> return _1; } Comment from Jeff Law: "I think the question will turn into whether or not we want the instrumentation code to try and optimize away unnecessary ops or if it should be left to the gimple optimizers. In the opptimized dump we can see stuff like this: > __atomic_fetch_or_8 (&__gcov8.f[1], 0, 0); So that's not going to change the value at &__gcov8.f[1] and we don't use the result, so we don't actually need to do the load either. So this could in theory just be removed at the gimple phase. Or at least that's how it seems to me." For reference, see: https://gcc.gnu.org/pipermail/gcc-patches/2025-August/692634.html