Boost C++ Libraries: Ticket #10850: gcc-x86-implementation of "atomic_exchange_and_add" triggers intel's "unitialized variable" runtime check https://svn.boost.org/trac10/ticket/10850 <p> The current implementation of atomic_exchange_and_add for gcc x86 is (<a class="ext-link" href="http://svn.boost.org/svn/boost/trunk/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp"><span class="icon">​</span>http://svn.boost.org/svn/boost/trunk/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp</a>) as following: </p> <p> inline int atomic_exchange_and_add( int * pw, int dv ) { </p> <blockquote> <p> <em> int r = *pw; </em> *pw += dv; <em> return r; </em></p> </blockquote> <blockquote> <p> int r; </p> </blockquote> <blockquote> <p> <span class="underline">asm</span> <span class="underline">volatile</span> ( </p> <blockquote> <p> "lock\n\t" "xadd %1, %0": "=m"( *pw ), "=r"( r ): <em> outputs (%0, %1) "m"( *pw ), "1"( dv ): </em> inputs (%2, %3 == %1) "memory", "cc" <em> clobbers </em></p> </blockquote> <p> ); </p> </blockquote> <blockquote> <p> return r; </p> </blockquote> <p> } </p> <p> This unfortunately triggers the "unitialized variable" runtime check of the Intel c++ compiler. Since r is actually superfluous, a simple patch can fix the problem: </p> <p> inline int atomic_exchange_and_add( int * pw, int dv ) { </p> <blockquote> <p> <em> int r = *pw; </em> *pw += dv; <em> return r; </em></p> </blockquote> <p> </p> <blockquote> <p> <span class="underline">asm</span> <span class="underline">volatile</span> ( </p> <blockquote> <p> "lock\n\t" "xadd %1, %0": "+m"( *pw ), "+r"( dv ): <em> input/output (%0, %1) </em></p> <blockquote> <p> : </p> </blockquote> <p> "memory", "cc" <em> clobbers </em></p> </blockquote> <p> ); </p> </blockquote> <p> </p> <blockquote> <p> return dv; </p> </blockquote> <p> } My colleague, who wrote the patch, checked that the generated assembler code is almost identical to the original one. "Almost" in the sense, that the removal of r changes some offsets. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/10850 Trac 1.4.3 fabian.hachenberg@… Thu, 04 Dec 2014 18:23:51 GMT <link>https://svn.boost.org/trac10/ticket/10850#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/10850#comment:1</guid> <description> <p> Sorry for the messup of code blocks. </p> <p> Here's the original code </p> <pre class="wiki">inline int atomic_exchange_and_add( int * pw, int dv ) { // int r = *pw; // *pw += dv; // return r; int r; __asm__ __volatile__ ( "lock\n\t" "xadd %1, %0": "=m"( *pw ), "=r"( r ): // outputs (%0, %1) "m"( *pw ), "1"( dv ): // inputs (%2, %3 == %1) "memory", "cc" // clobbers ); return r; } </pre><p> Here's the patches version </p> <pre class="wiki">inline int atomic_exchange_and_add( int * pw, int dv ) { // int r = *pw; // *pw += dv; // return r; __asm__ __volatile__ ( "lock\n\t" "xadd %1, %0": "+m"( *pw ), "+r"( dv ): // input/output (%0, %1) : "memory", "cc" // clobbers ); return dv; } </pre> </description> <category>Ticket</category> </item> </channel> </rss>