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

Reply via email to