The program below compiles and runs when compiled without any compiler options, but hangs in the call to sqrt when compiled with -O. All simple changes I made to it make it run through. The system I'm working on is a dual processor IBM blade with 2Gb of memory, running RedHat enterprise. Please contact me if you need further specs. I compiled using version 3.2.3 20030502 of gcc, 3.4.0 myself with no special configuration options: > gcc-3.4.0 -v Reading specs from /usr/local/lib/gcc/i686-pc-linux-gnu/3.4.0/specs Configured with: ./configure --program-suffix=-3.4.0 Thread model: posix gcc version 3.4.0 Again "g++-3.4.0 -O test.cc; ./a.out" hangs indefinately, while "g++-3.4.0 test.cc; ./a.out" exits. I changed inclusion of math.h to explicit def of NAN and direct call to __builtin_sqrt so that temp files would be smaller. Daniel test.cc: # define NAN \ (__extension__ \ ((union { unsigned __l __attribute__((__mode__(__SI__))); float __d; }) \ { __l: 0x7fc00000UL }).__d) inline double fmax(double a, double b) { if (a < b) return b; else return a; } double f() { return __builtin_sqrt(NAN/fmax(1., 1./.0)); } int main() { double u = f(); return 0; } test.ii: # 1 "test.cc" # 1 "<built-in>" # 1 "<command line>" # 1 "test.cc" inline double fmax(double a, double b) { if (a < b) return b; else return a; } double f() { return __builtin_sqrt((__extension__ ((union { unsigned __l __attribute__((__mode__(__SI__))); float __d; }) { __l: 0x7fc00000UL }).__d)/fmax(1., 1./.0)); } int main() { double u = f(); return 0; } test.s: .file "test.cc" .section .rodata.cst8,"aM",@progbits,8 .align 8 .LC3: .long 0 .long 0 .text .align 2 .globl _Z1fv .type _Z1fv, @function _Z1fv: .LFB3: pushl %ebp .LCFI0: movl %esp, %ebp .LCFI1: subl $4, %esp .LCFI2: movl $2143289344, %eax movl %eax, -4(%ebp) flds -4(%ebp) fld1 fld %st(0) fdivl .LC3 fucom %st(1) fnstsw %ax sahf ja .L16 fstp %st(0) jmp .L15 .L16: fstp %st(1) jmp .L15 .L18: fstp %st(1) .L15: fdivr %st(1), %st fsqrt fucom %st(0) fnstsw %ax sahf jp .L17 je .L6 fstp %st(0) jmp .L14 .L17: fstp %st(0) .L14: fld1 fld %st(0) fdivl .LC3 fucom %st(1) fnstsw %ax sahf ja .L18 fstp %st(0) jmp .L15 .L6: fstp %st(1) leave ret .LFE3: .size _Z1fv, .-_Z1fv .align 2 .globl main .type main, @function main: .LFB4: pushl %ebp .LCFI3: movl %esp, %ebp .LCFI4: subl $8, %esp .LCFI5: andl $-16, %esp subl $16, %esp call _Z1fv fstp %st(0) movl $0, %eax leave ret .LFE4: .size main, .-main .section .note.GNU-stack,"",@progbits .ident "GCC: (GNU) 3.4.0"
A simpler testcase for 3.4.0 and above: inline double fmax(double a, double b) { return (a<=b)? b : a; } double f() { return __builtin_sqrt(__builtin_nan("")/fmax(1., 1./.0)); } int main() { double u = f(); return 0; } Confirmed.
Fixed or really masked so much I can no longer reproduce it with any variant of the source.
This bug seems to have resurfaced in 3.4.3. It is actually enough to have a negative argument to sqrt.
What builtin_sqrt does is: try fsqrt if result is ok (fucom on it sets flags for =), return it else call library sqrt This was coded badly in gcc 3.4.1, causing an infinite loop (btw, I can't find where the asm code is) The bug seems corrected in gcc 3.4.3