gcc lacks the ability to output condition variables from an asm block which forces you to shove the value of the condition variable into a general purpose register and output that instead. i didn't expect it to work, but i thought that maybe the gcc optimiser would be smart enough to reorder code of this form: if (x) y = 1; else y = 0; ... if (y) a (); else b (); to simply: if (x) a (); else b (); it turns out that gcc *is* smart enough to do that, and it even works with 'asm goto'. fantastic! bad news is that when things get just a little more complicated (ie: trying to do the same thing twice within a function) then gcc throws this: at.c:30:1: internal compiler error: in cfg_layout_merge_blocks, at cfgrtl.c:2721 This is Fedora 16. Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.6.2/lto-wrapper Target: x86_64-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux Thread model: posix gcc version 4.6.2 20111027 (Red Hat 4.6.2-1) (GCC) Here's the code: #include <stddef.h> extern void a (void); extern void b (void); int bit_set (int *address, int bit_address) { asm goto ("lock bts %1, (%0)\n" "jc %l[contended]" : /* no output */ : "r" (address), "r" ((size_t) bit_address) : "cc", "memory" : contended); return 0; contended: return 1; } void do_stuff (int *address) { if (bit_set (address, 23)) a (); else b (); bit_set (address, 2); }
Sorry -- forgot to mention: you need to compile with at least -O2 to trigger the bug.
Please attach the Preprocessed source with the report.. -- Fedora Bugzappers volunteer triage team https://fedoraproject.org/wiki/BugZappers
Preprocessed source isn't needed, stddef.h header is included with gcc and the include even isn't really needed if you replace size_t with unsigned long. Tracking this upstream.
Thank you for the bug report.I believe this bug is fixed in upstream please go to this link: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51767 For further assistance also, that link must be useful and let me close this upstream feel free to open it at any time. -- Fedora Bugzappers volunteer triage team https://fedoraproject.org/wiki/BugZappers