Skip to content

__builtin_fabs shouldn't lower to libm call #9391

@llvmbot

Description

@llvmbot
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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugzillaIssues migrated from bugzillawontfixIssue is real, but we can't or won't fix it. Not invalid

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions