https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111097
Bug ID: 111097 Summary: mistifying bug triggered by trivial code change Product: gcc Version: 13.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: fabio at cannizzo dot net Target Milestone: --- Created attachment 55774 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55774&action=edit reproducible test case I come across a weird bug. If I instrument the code with traces, the bug disappears. If I remove some force inline attributes, the bug also disappears. Eventually I manage to reduce to a minimalist example. The attached file contains a class with a member state vector which is used as a circular buffer alignas(64) __m128i m_state[156]; The constructor fills it with some chosen numbers. The first time the method `genrand_uint32` is called, it invokes the `refill` function, which is supposed to modify all members of the `m_state` vector. Then we extract one by one the element in the vector as `uint32_t`. We print the 4 and last 4 elements of the state vector, reinterpreted as `uint32_t[]` before refill and after refill, and the content is correct. We also print the first and last 2 elements of the array extracted by `genrand_uint32`, which should match exactly the state vector after refill, but the first element is wrong. pre-refill: 3403902862 1263040418 ... 2214668603 3759392492 post-refill: 1643499593 2393179749 ... 1152747345 4215414382 extracted: 3403902862 2393179749 ... 1152747345 4215414382 To be clear, the first element extracted should be 1643499593, i.e. the correct output should be: pre-refill: 3403902862 1263040418 ... 2214668603 3759392492 post-refill: 1643499593 2393179749 ... 1152747345 4215414382 extracted: 1643499593 2393179749 ... 1152747345 4215414382 If I remove a few of the FORCE_INLINE macros, e.g. if I change FORCE_INLINE void refill() to NO_INLINE void refill() the error disappears. If I change 1 to 0 in this `#ifdef`, the error disappears. #if 1 // here p is of type __m128i* and tmp has type __m128i struct XV { __m128i m_v; XV(__m128i v) : m_v(v) {} }; ((XV *)p)[0] = tmp; #else p[0] = tmp; #endif If I reorder the `genrand_uint32` from if (m_prnd != end()) { // most likely case return *m_prnd++; } else { refill(); m_prnd = begin(); return *m_prnd++; } to if (m_prnd == end()) { refill(); m_prnd = begin(); } return *m_prnd++; the error disappears. A godbolt link to this code is also available: https://godbolt.org/z/v9b7z8c66