Date: Wed, 11 Jan 2017 14:01:45 -0200 From: "Dr. Rolf Jansen" <rj@obsigna.com> To: freebsd-arm@freebsd.org Subject: Re: clang on armv6 incorrectly emits call to sincos() Message-ID: <5DC099EB-CF9D-4BFB-9AA7-D53DF50B8064@obsigna.com> In-Reply-To: <CAHNYxxNDskx3b8uEV%2BTxD8YUwDMQuw8YQtCYQNs0RNDbRx=1zg@mail.gmail.com>
index | next in thread | previous in thread | raw e-mail
> Am 11.01.2017 um 12:42 schrieb Jia-Shiun Li <jiashiun@gmail.com>:
>
> Hi all,
>
> I was looking into build failure after graphviz been updated to 2.40.1. On
> amd64 it builds fine. But on armv6 aka rpi2 when linking, it complained
> about undefined reference to sincos. [1]
>
> Turns out it was not graphviz but clang.
>
> When compling with -ffast-math, clang folds adjancent calls to sin() and
> cos() into one call to sincos(), which FreeBSD does not have. Thus the
> linking error. A minimal example source file is provided in [2]. Commands
> [3], and my environment. [4]
>
> Think this optimization should be turned off for armv6 from base
> clang/llvm, instead of patching individual ports or ports infrastructure.
> Or is it possibly due to crosscompiling world? I haven't tried if natively
> built world works. Ideas?
I ran into the same issue when porting my software to armv6 (BeagleBone Black).
Since FreeBSD is missing many math functions, I anyway need to keep a libm supplement for FreeBSD around. So, leaving -ffast-math in place, I simply added to the supplement implementation:
#pragma mark ••• Implementation of Missing Math Functions in FreeBSD •••
#ifdef __FreeBSD__
...
#elif defined(__arm__)
void sincos(double x, double *rsin, double *rcos)
{
*rsin = sin(x);
*rcos = cos(x);
}
#endif
#endif
My Header file of my libm FreeBSD supplement got:
#ifdef __FreeBSD__
...
#elif defined(__arm__)
// long double is double
#define erfl(x) erf(x)
#define powl(x,y) pow(x,y)
#define tgammal(x) tgamma(x)
#define csinl(z) csin(z)
#define casinl(z) casin(z)
#define ccosl(z) ccos(z)
#define cacosl(z) cacos(z)
#define ctanl(z) ctan(z)
#define catanl(z) catan(z)
#define cexpl(z) cexp(z)
#define csinhl(z) csinh(z)
#define casinhl(z) casinh(z)
#define ccoshl(z) ccosh(z)
#define cacoshl(z) cacosh(z)
#define ctanhl(z) ctanh(z)
#define catanhl(z) catanh(z)
static inline long double complex cpowl(long double complex x, long double complex y)
{ return cpow(x, y); }
static inline long double complex clogl(long double complex z)
{ return clog(z); }
#endif
#endif
I assume that for the FreeBSD project it is much easier to complete libm instead of asking the upstream LLVM/clang project for rewriting the optimizing behaviour, which may have unknown implications to many other projects as well.
Best regards
Rolf
home |
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?5DC099EB-CF9D-4BFB-9AA7-D53DF50B8064>
