[Bug c/68868] New: atomic_init emits an unnecessary fence
msebor at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Sat Dec 12 00:49:00 GMT 2015
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68868
Bug ID: 68868
Summary: atomic_init emits an unnecessary fence
Product: gcc
Version: 6.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: msebor at gcc dot gnu.org
Target Milestone: ---
This is similar but not the same as as bug 68622. The following test case that
uses atomic_init() and shows that while libstdc++ handles the C++ case
efficiently, C does not and emits an unnecessary fence:
#if __cplusplus
# include <atomic>
using std::atomic_int;
using std::atomic_init;
#else
# include <stdatomic.h>
#endif
typedef atomic_int AI;
void foo (AI *ai)
{
atomic_init (ai, 123);
}
Gcc (in C mode) emits the following with -O2 on x86_64:
foo:
movl $123, (%rdi)
mfence
ret
G++, on the other hand, and Clang in both modes, emit the following efficient
code at -O2:
_Z3fooPSt6atomicIiE:
movl $123, (%rdi)
ret
The C code is worse because the C <stdatomic.h> header doesn't distinguish
initialization from assignment and implements the atomic_init() macro as plain
assignment:
#define atomic_init(PTR, VAL) \
do \
{ \
*(PTR) = (VAL); \
} \
while (0)
Defining atomic_init() as in the otherwise untested patch below gets rid of the
unnecessary fence:
--- ginclude/stdatomic.h (revision 231532)
+++ ginclude/stdatomic.h (working copy)
@@ -77,13 +77,13 @@
#define ATOMIC_VAR_INIT(VALUE) (VALUE)
-#define atomic_init(PTR, VAL) \
- do \
- { \
- *(PTR) = (VAL); \
- } \
- while (0)
+/* Initialize an atomic object pointed to by PTR with VALUE. */
+#define atomic_init(PTR, VALUE) __extension__ ({ \
+ __typeof__ (VALUE) __tmp = (VALUE); \
+ __atomic_store ((PTR), &__tmp, __ATOMIC_RELAXED); \
+ })
+
#define kill_dependency(Y) \
__extension__ \
({ \
More information about the Gcc-bugs
mailing list