Between gcc-4.5-20090903 (correct) and gcc-4.5-20091008 (wrong), a bug was introduced in the expansion of _asm__() directives on AMD64. The bug has been reproduced also in gcc-4.5-20100107 and yesterday's first release of gcc-4.6-20100416. Here is test program, with leading comments that reflect its test results:
/*********************************************************************** Demonstrate a bug in the handling of __asm__() in recent gcc-4.5 and gcc-4.6 releases on AMD64: gcc-4.1-20070723 mysqrt(4) = 2 gcc-4.1-20071126 mysqrt(4) = 2 gcc-4.1-20071231 mysqrt(4) = 2 gcc-4.1-20080211 mysqrt(4) = 2 gcc-4.1-20080218 mysqrt(4) = 2 gcc-4.1-20080407 mysqrt(4) = 2 gcc-4.1-20080630 mysqrt(4) = 2 gcc-4.2-20061031 mysqrt(4) = 2 gcc-4.2-20070124 mysqrt(4) = 2 gcc-4.2-20070207 mysqrt(4) = 2 gcc-4.2-20070815 mysqrt(4) = 2 gcc-4.2-20070905 mysqrt(4) = 2 gcc-4.2-20071128 mysqrt(4) = 2 gcc-4.2-20071219 mysqrt(4) = 2 gcc-4.2-20071226 mysqrt(4) = 2 gcc-4.2-20080102 mysqrt(4) = 2 gcc-4.2-20080213 mysqrt(4) = 2 gcc-4.2-20080220 mysqrt(4) = 2 gcc-4.2-20080409 mysqrt(4) = 2 gcc-4.2-20080806 mysqrt(4) = 2 gcc-4.2-20081015 mysqrt(4) = 2 gcc-4.2-20081126 mysqrt(4) = 2 gcc-4.2-20090121 mysqrt(4) = 2 gcc-4.2-20090325 mysqrt(4) = 2 gcc-4.3-20061118 mysqrt(4) = 2 gcc-4.3-20070209 mysqrt(4) = 2 gcc-4.3-20070511 mysqrt(4) = 2 gcc-4.3-20070720 mysqrt(4) = 2 gcc-4.3-20070914 mysqrt(4) = 2 gcc-4.3-20081016 mysqrt(4) = 2 gcc-4.3-20081127 mysqrt(4) = 2 gcc-4.3-20090122 mysqrt(4) = 2 gcc-4.3-20090524 mysqrt(4) = 2 gcc-4.3-20090816 mysqrt(4) = 2 gcc-4.3-20100103 mysqrt(4) = 2 gcc-4.4-20081017 mysqrt(4) = 2 gcc-4.4-20081128 mysqrt(4) = 2 gcc-4.4-20090123 mysqrt(4) = 2 gcc-4.4-20090526 mysqrt(4) = 2 gcc-4.4-20090818 mysqrt(4) = 2 gcc-4.4-20090908 mysqrt(4) = 2 gcc-4.4-20100105 mysqrt(4) = 2 gcc-4.4-20100112 mysqrt(4) = 2 gcc-4.5-20090528 mysqrt(4) = 2 gcc-4.5-20090820 mysqrt(4) = 2 gcc-4.5-20090903 mysqrt(4) = 2 gcc-4.5-20091008 mysqrt(4) = 0 gcc-4.5-20100107 mysqrt(4) = 0 gcc-4.6-20100416 mysqrt(4) = 0 ***********************************************************************/ #include <stdio.h> #include <stdlib.h> double mysqrt(double x) { double result; __asm__ __volatile__("sqrtsd %0, %1" : "=x" (result) : "x" (x)); /* use AMD64 SSE2 instruction */ return (result); } int main(void) { double x, y; x = 4.0; y = mysqrt(x); (void)printf("mysqrt(%g) = %.17g\n", x, y); return (EXIT_SUCCESS); } -- Summary: Erroneous expansion of __asm__() directive Product: gcc Version: 4.5.0 Status: UNCONFIRMED Severity: major Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: beebe at math dot utah dot edu GCC build triplet: x86_64-unknown-linux-gnu GCC host triplet: x86_64-unknown-linux-gnu GCC target triplet: x86_64-unknown-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43782