2011-02-10 63 views
21

假设我有:乘以0优化

double f(const double *r) { 
    return 0*(r[0]*r[1]); 
} 

应该编译器能够优化出来的段,或者它仍然必须执行的操作,以防值可能是INF或NaN?

gcc -O3 -S test.c: 

     .file "test.c" 
     .text 
     .p2align 4,,15 
.globl f 
     .type f, @function 
f: 
.LFB0: 
     .cfi_startproc 
     movsd (%rdi), %xmm0 
     mulsd 8(%rdi), %xmm0 
     mulsd .LC0(%rip), %xmm0 
     ret 
     .cfi_endproc 
.LFE0: 
     .size f, .-f 
     .section  .rodata.cst8,"aM",@progbits,8 
     .align 8 
.LC0: 
     .long 0 
     .long 0 
     .ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3" 
     .section  .note.GNU-stack,"",@progbits 

似乎没有消除?

啊哈:

gcc -O3 -ffast-math -S test.c 

     .file "test.c" 
     .text 
     .p2align 4,,15 
.globl f 
     .type f, @function 
f: 
.LFB0: 
     .cfi_startproc 
     xorpd %xmm0, %xmm0 
     ret 
     .cfi_endproc 
.LFE0: 
     .size f, .-f 
     .ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3" 
     .section  .note.GNU-stack,"",@progbits 

回答

13

它不仅infNaN阻止优化那里,它也标志 - 0.0 *负面的东西是-0.0,否则就0.0,所以你确实有计算的r[0]*r[1]的迹象。

13

取决于编译器是否实现了IEEE754。 C和C++都不要求编译器支持NaN,但IEEE754支持。

+2

好的,不得不用'-fast-math`强制时髦的数学。 – Anycorn 2011-02-10 10:48:48