HEADSUP: math is broken with clang and optimization

Mark Millard marklmi at yahoo.com
Mon Feb 15 23:27:19 UTC 2021


> On Mon, Feb 15, 2021 at 01:03:36PM -0800, Steve Kargl wrote:
> > On Mon, Feb 15, 2021 at 12:49:13PM -0800, Steve Kargl wrote:
> > > On Sun, Feb 14, 2021 at 01:59:58PM -0800, Steve Kargl wrote:
> > > > Just a headsup for anyone doing numerical work with
> > > > FreeBSD-current.  clang with optimization of -O1 or
> > > > higher produces wrong results.  Testing 1 million 
> > > > complex values of ccoshf and limiting |z| < 20,
> > > > shows
> > > > 
> > > 
> > > This is either an in-ling bug or discarding a cast issue.
> > > With everything in the same file so clang has dp_ccosh
> > > available to it when compiling main.
> > > 
> > 
> > Code builds and works as expected with gcc 10.2and
> > gcc 11.0.0.
> > 
> 
> Can't find a list of options that is equivalent to -O1,
> so cannot test various optimizations.
> 
> Notice that -march=i686 gives the wrong results and
> -march=core2 gives the correct result.  Trying -march=i686
> -msse -msse2 gives the correct result.  It seems that
> clang does not understand how the x87 (on i585-freebsd).

I tried looking around some and got the following
that might be contributing: variations in
__FLT_EVAL_METHOD__ used . . .

# cc -target i386-unknown-freebsd14.0 -march=i686 -O2 -x c /dev/null -dM -E | egrep "(FLT_EVAL_METHOD|ILP32|LP64)"
#define _ILP32 1
#define __FLT_EVAL_METHOD__ 2
#define __ILP32__ 1

# cc -target i386-unknown-freebsd14.0 -march=core2 -O2 -x c /dev/null -dM -E | egrep "(FLT_EVAL_METHOD|ILP32|LP64)"
#define _ILP32 1
#define __FLT_EVAL_METHOD__ 0
#define __ILP32__ 1

# cc -target x86_64-unknown-freebsd14.0 -march=core2 -O2 -x c /dev/null -dM -E | egrep "(FLT_EVAL_METHOD|ILP32|LP64)"
#define _LP64 1
#define __FLT_EVAL_METHOD__ 0
#define __LP64__ 1

FYI: It does not look like FreeBSD's /usr/include/x86/float.h
matches all the detail:

#if __ISO_C_VISIBLE >= 1999
#ifdef __LP64__
#define FLT_EVAL_METHOD 0               /* no promotions */
#else
#define FLT_EVAL_METHOD (-1)            /* i387 semantics are...interesting */
#endif
. . .
#endif


For reference:

# cc -target i386-unknown-freebsd14.0 -O2 -x c /dev/null -dM -E | egrep "(FLT_EVAL_METHOD|ILP32|LP64)"
#define _ILP32 1
#define __FLT_EVAL_METHOD__ 2
#define __ILP32__ 1

# cc -target x86_64-unknown-freebsd14.0 -O2 -x c /dev/null -dM -E | egrep "(FLT_EVAL_METHOD|ILP32|LP64)"
#define _LP64 1
#define __FLT_EVAL_METHOD__ 0
#define __LP64__ 1

# cc -target x86_64-unknown-freebsd14.0 -march=i686 -O2 -x c /dev/null -dM -E | grep FLT_EVAL_METHOD | sort
error: unknown target CPU 'i686'
note: valid target CPU values are: nocona, core2, penryn, bonnell, atom, silvermont, slm, goldmont, goldmont-plus, tremont, nehalem, corei7, westmere, sandybridge, corei7-avx, ivybridge, core-avx-i, haswell, core-avx2, broadwell, skylake, skylake-avx512, skx, cascadelake, cooperlake, cannonlake, icelake-client, icelake-server, tigerlake, knl, knm, k8, athlon64, athlon-fx, opteron, k8-sse3, athlon64-sse3, opteron-sse3, amdfam10, barcelona, btver1, btver2, bdver1, bdver2, bdver3, bdver4, znver1, znver2, x86-64

# cc -v
FreeBSD clang version 11.0.1 (git at github.com:llvm/llvm-project.git llvmorg-11.0.1-0-g43ff75f2c3fe)
Target: x86_64-unknown-freebsd14.0
Thread model: posix
InstalledDir: /usr/bin

===
Mark Millard
marklmi at yahoo.com
( dsl-only.net went
away in early 2018-Mar)



More information about the freebsd-current mailing list