Skip site navigation (1)Skip section navigation (2)
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>
References:  <CAHNYxxNDskx3b8uEV%2BTxD8YUwDMQuw8YQtCYQNs0RNDbRx=1zg@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
> Am 11.01.2017 um 12:42 schrieb Jia-Shiun Li <jiashiun@gmail.com>:
>=20
> Hi all,
>=20
> 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]
>=20
> Turns out it was not graphviz but clang.
>=20
> 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]
>=20
> 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:=20

#pragma mark =E2=80=A2=E2=80=A2=E2=80=A2 Implementation of Missing Math =
Functions in FreeBSD =E2=80=A2=E2=80=A2=E2=80=A2

#ifdef __FreeBSD__

   ...

   #elif defined(__arm__)

      void sincos(double x, double *rsin, double *rcos)
      {
         *rsin =3D sin(x);
         *rcos =3D 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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?5DC099EB-CF9D-4BFB-9AA7-D53DF50B8064>