Boost C++ Libraries: Ticket #3341: sp_counted_base_gcc_sparc.hpp compile failure on gcc.4.2.3 w/-O2 https://svn.boost.org/trac10/ticket/3341 <p> compare_and_swap() from sp_counted_base_gcc_sparc.hpp fails to compile here with gcc 4.2.3 configured thusly: </p> <p> -bash-3.00$ /opt/gcc-4.2.3/bin/g++ -v Using built-in specs. Target: sparc64-sun-solaris2.10 Configured with: ../src/configure --host=sparc64-sun-solaris2.10 --with-gnu-as --with-as=/opt/binutils-2.17/bin/as --with-gnu-ld --with-ld=/opt/binutils-2.17/bin/ld --with-pic --enable-languages=c,c++ --prefix=/opt/gcc-4.2.3 Thread model: posix gcc version 4.2.3 </p> <p> The problem is the "=m" asm constraint in this function, which allows memory references of any form. When compiling with optimisation, gcc avoids some address math and ends up emitting &lt;reg&gt;+&lt;offset&gt; for the first operand in its inlined call. 'as' then refuses to assemble this ('Illegal Operands'). If the function is not inlined, the dest_ parameter has the offset added to it before being passed to the function and it then compiles quite happily. Unfortunately, gcc does not have an asm constraint to specify that offsets should not be used in memory references. </p> <p> I'm working around this locally by making the function static and attribute(noinline), which works with a small code size cost. An alternate fix would be to load the memory address from another register in the asm expression, but that's beyond my gcc asm-fu. </p> <p> Alternately, this may be considered a bug in the compiler - but adding the missing constraint is more likely to be considered a feature request IMO, hence the bug report here first. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/3341 Trac 1.4.3 Peter Dimov Fri, 14 Aug 2009 11:35:29 GMT <link>https://svn.boost.org/trac10/ticket/3341#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3341#comment:1</guid> <description> <p> According to </p> <p> <a class="ext-link" href="http://gcc.gnu.org/onlinedocs/gcc/Simple-Constraints.html"><span class="icon">​</span>http://gcc.gnu.org/onlinedocs/gcc/Simple-Constraints.html</a> </p> <p> the proper constraint could be 'V' instead of 'm'. </p> </description> <category>Ticket</category> </item> <item> <author>jon_p_griffiths@…</author> <pubDate>Sat, 15 Aug 2009 18:14:40 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3341#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3341#comment:2</guid> <description> <blockquote class="citation"> <p> the proper constraint could be 'V' instead of 'm'. </p> </blockquote> <p> I tried +V before reporting but it also failed (with 'inconsistent asm contraints' IIRC). I found two sparc CAS implementations by googling (GASNet and the Linux kernel) - both use the following formulation: </p> <pre class="wiki">__asm__ __volatile("cas [%2], %3, %0\n\t" : "=&amp;r" (swap_) : "0" (swap_), "r" (dest_), "r" (compare_) : "memory"); </pre><p> This forces the address to be stored in a register, which avoids any offset addition in the emitted instruction. However, the Linux kernel implementation adds memory barriers before and after the CAS; it would be interesting to know whether they are really needed in this case. </p> <p> For reference, I've tested the following version; it seems to be running without issues here: </p> <pre class="wiki">inline int32_t compare_and_swap( volatile int32_t * dest_, int32_t compare_, int32_t swap_ ) { __asm__ __volatile__("membar #StoreLoad|#LoadLoad\n" "cas [%2], %3, %0\n" "membar #StoreLoad|#StoreStore\n" : "=&amp;r" (swap_) : "0" (swap_), "r" (dest_), "r" (compare_) : "memory"); return swap_; } </pre><p> Cheers, Jon </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Peter Dimov</dc:creator> <pubDate>Thu, 26 Nov 2009 18:21:23 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3341#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3341#comment:3</guid> <description> <p> (In <a class="changeset" href="https://svn.boost.org/trac10/changeset/57949" title="Fix SPARC asm operand failure. Refs #3678. Refs #3341.">[57949]</a>) Fix SPARC asm operand failure. Refs <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/3678" title="#3678: Bugs: Build failure on SPARC64 architecture (closed: fixed)">#3678</a>. Refs <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/3341" title="#3341: Bugs: sp_counted_base_gcc_sparc.hpp compile failure on gcc.4.2.3 w/-O2 (closed: fixed)">#3341</a>. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Peter Dimov</dc:creator> <pubDate>Thu, 26 Nov 2009 18:25:46 GMT</pubDate> <title>status changed https://svn.boost.org/trac10/ticket/3341#comment:4 https://svn.boost.org/trac10/ticket/3341#comment:4 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">assigned</span> </li> </ul> Ticket Peter Dimov Mon, 30 Nov 2009 20:17:16 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/3341#comment:5 https://svn.boost.org/trac10/ticket/3341#comment:5 <ul> <li><strong>status</strong> <span class="trac-field-old">assigned</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> (In <a class="changeset" href="https://svn.boost.org/trac10/changeset/58063" title="Merge [57949] to release. Fixes #3678. Fixes #3341.">[58063]</a>) Merge <a class="changeset" href="https://svn.boost.org/trac10/changeset/57949" title="Fix SPARC asm operand failure. Refs #3678. Refs #3341.">[57949]</a> to release. Fixes <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/3678" title="#3678: Bugs: Build failure on SPARC64 architecture (closed: fixed)">#3678</a>. Fixes <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/3341" title="#3341: Bugs: sp_counted_base_gcc_sparc.hpp compile failure on gcc.4.2.3 w/-O2 (closed: fixed)">#3341</a>. </p> Ticket