[LLVMdev] Wrong tan

Gonsolo gonsolo at gmail.com
Sat Jun 16 12:52:09 PDT 2007


Hi!

Dale Johannesen schrieb:
>
> On Jun 16, 2007, at 12:35 AM, Duncan Sands wrote:
>
>>> Result compiled with llvm-g++ 2.0:
>>> tan float: -2.18504
>>> tan double: 0.309336
>>
>> This may be due to bug 1505.
>
> It fails on x86 using x87 floating point, with the inliner not run,
> because of 1505, yes.  Gonsolo, is that your situation?
>

I tried a simple "llvm-g++ -o simple tan.bug.cc"
Output:
tan float: -2.18504
tan double: 0.309336

> (What happens is, there is  a wrapper in the header file for std::tan(float),
> like this:
>
>   inline float
>   tan(float __x)
>   { return __builtin_tanf(__x); }
>
> This wrapper is miscompiled due to 1505; when the inliner is run, no problem.)
>
> (But, when opt -std-compile-opts is run, the 'tan' call is evaluated at compile
> time, while 'tanf' resolves to a libc call.  This is undesirable, since the whole
> reason tanf exists is that it's supposed to be faster than tan.  Of course you
> have to be very careful about doing FP operations at compile time, but I
> assume this is being done right; it's getting the right answer here, anyway.)

I also tried:

1. g++

Output:
tan float: 0.309336
tan double: 0.309336

Works.

2. lli

Output:
tan float: 0.309336
tan double: 0.309336

Works

3. lli with opt

Output:
tan float: 0.309336
tan double: 0.309336

Works.

4. opt + llc  + as + g++

Output:
tan float: 0.309336
tan double: 0.309336

Works

5. opt + llc + as + llvm-g++

Output:
tan float: 0
tan double: 0

????

In summary: Everything works except linking with llvm-g++!

Gonsolo


Appendix A:

<tan_bug.cc>
#include <iostream>
#include <cmath>

int main()
{
        float a = 0.3;
        double b = 0.3;

        float result_a = std::tan( a );
        float result_b = std::tan( b );
        std::cout << "tan float: " << result_a << std::endl;
        std::cout << "tan double: " << result_b << std::endl;
}

</tan_bug.cc>

Appendix B:

<Makefile>

all: test_g++ test_llvm-g++ test_interpreter test_interpreter_opt
test_native_g++ test_native_llvm-g++

.PHONY: c clean test_simple test_interpreter test_interpreter_opt
test_native_g++ test_native_llvm-g++

test_g++: simple_g++
        ./simple_g++

test_llvm-g++: simple_llvm
        ./simple_llvm

test_interpreter: emit.bc
        lli emit.bc

test_interpreter_opt: opt.bc
        lli opt.bc

test_native_g++:  native_g++
        ./native_g++

test_native_llvm-g++: native_llvm-g++
        ./native_llvm-g++

simple_g++: tan_bug.cc
        g++ -o simple_g++ tan_bug.cc

simple_llvm: tan_bug.cc
        llvm-g++ -o simple_llvm tan_bug.cc

emit.bc: tan_bug.cc
        llvm-g++ -c --emit-llvm -o emit.bc tan_bug.cc

opt.bc: emit.bc
        opt -std-compile-opts emit.bc -o opt.bc

opt.s: opt.bc
        llc opt.bc -o opt.s

opt.o: opt.s
        as opt.s -o opt.o

native_g++: opt.o
        g++ -o native_g++ opt.o

native_llvm-g++: opt.o
        llvm-g++ -o native_llvm-g++ opt.o

c: clean
clean:
        rm -f simple_g++ simple_llvm emit.bc opt.bc opt.s opt.o
native_g++ native_llvm-g++

</Makefile>

Appendix C:

Thanks for your quick reply!!



More information about the llvm-dev mailing list