-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Description
| Bugzilla Link | 9019 |
| Resolution | WONTFIX |
| Resolved on | Feb 17, 2011 17:38 |
| Version | trunk |
| OS | Linux |
| Reporter | LLVM Bugzilla Contributor |
Extended Description
This program:
float f(float x) {
return __builtin_fabsf(x);
}
requires -lm when built by clang -O0 but not when built by gcc or clang -O2. GCC emits this code at -O2 levels (-O0 has no call either):
f:
.LFB0:
.cfi_startproc
movss .LC0(%rip), %xmm1
andps %xmm1, %xmm0
ret
.cfi_endproc
[...]
.LC0:
.long 2147483647
.long 0
.long 0
.long 0
without -fno-errno or -ffast-math or any other such flags. Clang -O2 will emit this IR:
define float @f(float %x) nounwind readnone {
entry:
%call = tail call float @fabsf(float %x)
ret float %call
}
but in llc -O0 we emit the call as written and in llc -O2 we replace it with an andps like gcc.
Either llc -O0 should learn to lower fabs/fabsf calls to 'and', or clang should lower __builtin_fabs differently. I think I prefer the latter, but the backend would need to be improved first. The lowering in LLVM IR would be:
define float @f(float %x) {
%cast = bitcast float %x to i32
%abs.i = and i32 %cast, 2147483647
%abs = bitcast i32 %abs.i to float
ret float %abs
}
which produces this sub-optimal code through llc -O2:
movd %xmm0, %eax
andl $2147483647, %eax # imm = 0x7FFFFFFF
movd %eax, %xmm0
ret