sarda
sarda

Reputation: 213

LLVM not using machine instructions

I was testing the quality of code generated by LLVM vs gcc

I have a small program like this

#include<math.h>
double mysqrt(double a){
    return sqrt(a);
}

int main()
{
    mysqrt(0.1);
    return 1;
}

Clang was emitting

mysqrt:                                 # @mysqrt
# BB#0:                                 # %entry
jmp sqrt                    # TAILCALL

which means it was calling sqrt function

gcc was emitting

mysqrt:
.LFB25:
.cfi_startproc
subl    $28, %esp
.cfi_def_cfa_offset 32
fldl    32(%esp)
fld %st(0)
fsqrt
fucomi  %st(0), %st

which means it was using direct machine instruction fsqrt (which i suppose is much faster than calling function). This was done for X86 machine with O3 level of optimization. Does anybody know why LLVM is calling function instead of using machine instruction?

Upvotes: 2

Views: 350

Answers (2)

David Greene
David Greene

Reputation: 414

To expand on Jens Gustedt's answer, in addition to the C standard issues with error checking, there is also an IEEE floating point (IEEE-754) conformance issue. The fsqrt instruction does not adhere to the IEEE standard. Specifically, the x86 floating-point stack does 80-bit arithmetic which is not an IEEE standard. You will get slightly different answers than you would with IEEE double-precision arithmetic. clang's -ffast-math option tells the compiler that it is ok to use the higher-precision instructions on x86.

While the C standard doesn't mandate IEEE-754 (except in an optional appendix), most implementations these days assume that's what the user wants. The system ABI usually specifies the floating point format. The x86-64 System V (Linux, essentially) standard mandates IEEE-754 for float and double and 80-bit precision for long double.

Using long double in mysqrt would allow the compiler to use 80-bit arithmetic but you might still need -ffast-math to tell the compiler to dispense with error checks.

Upvotes: 3

Jens Gustedt
Jens Gustedt

Reputation: 78903

The behavior of gcc is not standard C, since that inlined call is missing error checks. To have standard conforming behavior with gcc, compile with option -std=c99 or similar. To force clang to forget about its standard compliance something like -ffast-math might help.

Upvotes: 9

Related Questions