# Fixing GCC's Implementation of memory\_order\_consume

DevFeed: [Fixing GCC's Implementation of memory\_order\_consume](<https://devfeed.tech/articles/fixing-gcc-s-implementation-of-memory-order-consume-20999.md>)

Original publisher: [Read original article](<https://preshing.com/20141124/fixing-gccs-implementation-of-memory_order_consume>)

Author: Jeff Preshing

Published: 2014-11-24T11:25:00Z

Content type: article

Language: en

Sources: [Jeff Preshing](<https://devfeed.tech/sources/jeff-preshing.md>)

Topics: [gcc](<https://devfeed.tech/topics/gcc.md>), [Compiler](<https://devfeed.tech/topics/compiler.md>), [bug](<https://devfeed.tech/topics/bug.md>), [Concurrent Programming](<https://devfeed.tech/topics/concurrent-programming.md>), [Concurrency](<https://devfeed.tech/topics/concurrency.md>), [Arm](<https://devfeed.tech/topics/arm.md>)

Tags: [arm](<https://devfeed.tech/tags/arm.md>), [bug](<https://devfeed.tech/tags/bug.md>), [building](<https://devfeed.tech/tags/building.md>), [compiler](<https://devfeed.tech/tags/compiler.md>), [cppcon](<https://devfeed.tech/tags/cppcon.md>), [gcc](<https://devfeed.tech/tags/gcc.md>), [process](<https://devfeed.tech/tags/process.md>), [processors](<https://devfeed.tech/tags/processors.md>), [thread](<https://devfeed.tech/tags/thread.md>)

## AI overview

This article examines a bug in GCC 4.9.2's implementation of C++11 memory_order_consume. It explains the expected ordering guarantees, demonstrates the bug with a multithreaded example, and documents verifying and patching the compiler while building an AArch64 cross-compiler.

## Source excerpt

As I explained previously, there are two valid ways for a C++11 compiler to implement memory_order_consume: an efficient strategy and a heavy one. In the heavy strategy, the compiler simply treats memory_order_consume as an alias for memory_order_acquire. The heavy strategy is not what the designers of memory_order_consume had in mind, but technically, it's still compliant with the C++11 standard. There's a somewhat common misconception that all current C++11 compilers use the heavy strategy. I certainly had that impression until recently, and others I spoke to at CppCon 2014 seemed to have that impression as well. This belief turns out not to be true: GCC does not always use the heavy strategy (yet). GCC 4.9.2 actually has a bug in its implementation of memory_order_consume, as described in this GCC bug report. I was rather surprised to learn that, since it contradicted my own experience with GCC 4.8.3, in which the PowerPC compiler appeared to use the heavy strategy correctly. I decided to verify the bug on my own, which is why I recently took an interest in building GCC cross-compilers. This post will explain the bug and document the process of patching the compiler. An Example That Illustrates the Compiler Bug Imagine a bunch of threads repeatedly calling the following read function: #include <atomic> std::atomic<int> Guard(0); int Payload[1] = { 0xbadf00d }; int read() { int f = Guard.load(std::memory_order_consume); // load-consume if (f != 0) return Payload[f - f]; // plain load from Payload[f - f] return 0; } At some point, another thread comes along and calls write: int write() { Payload[0] = 42; // plain store to Payload[0] Guard.store(1, std::memory_order_release); // store-release } If the compiler is fully compliant with the current C++11 standard, then there are only two possible return values from read: 0 or 42. The outcome depends on the value seen by the load-consume highlighted above. If the load-consume sees 0, then obviously, read will return 0.