http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51007
--- Comment #3 from Francois-Xavier Coudert <fxcoudert at gcc dot gnu.org> 2011-11-07 11:39:12 UTC --- Going further: I tried to compare the trees generated by the simple function below: #include <stdint.h> typedef union { __float128 value; struct { #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ unsigned negative:1; unsigned exponent:15; uint64_t mant_high:48; uint64_t mant_low:64; #else uint64_t mant_low:64; uint64_t mant_high:48; unsigned exponent:15; unsigned negative:1; #endif } ieee; } ieee854_float128; unsigned foo (__float128 x) { ieee854_float128 d; d.value = x; return d.ieee.exponent; } AFAICT, both the original and the optimized tree for darwin and mingw are identical. The assembly code generated for a common arch (-march=core2 -O0) differs: ***** on mingw ***** _foo: pushl %ebp movl %esp, %ebp subl $40, %esp movdqa 8(%ebp), %xmm0 movdqa %xmm0, -40(%ebp) movzwl -24(%ebp), %eax andw $32767, %ax movzwl %ax, %eax leave ret ***** on darwin ***** _foo: pushq %rbp movq %rsp, %rbp movdqa %xmm0, -32(%rbp) movdqa -32(%rbp), %xmm0 movdqa %xmm0, -16(%rbp) movzwl -2(%rbp), %eax andw $32767, %ax movzwl %ax, %eax popq %rbp ret Now, my assembly skills are pretty close to nil, so I can't figure out if the differences are meaningful, and what they mean. I only hope that I got it close enough that someone can, from here, understand where this code generation come from and how to fix it.