Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 15 Feb 2021 17:01:30 -0800
From:      Steve Kargl <sgk@troutmask.apl.washington.edu>
To:        Mark Millard <marklmi@yahoo.com>
Cc:        freebsd-current <freebsd-current@freebsd.org>
Subject:   Re: HEADSUP: math is broken with clang and optimization
Message-ID:  <20210216010130.GA87472@troutmask.apl.washington.edu>
In-Reply-To: <3FD4762E-8C74-4210-8DA9-9FB30E609205@yahoo.com>
References:  <3FD4762E-8C74-4210-8DA9-9FB30E609205.ref@yahoo.com> <3FD4762E-8C74-4210-8DA9-9FB30E609205@yahoo.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, Feb 15, 2021 at 03:27:08PM -0800, Mark Millard wrote:
> > 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@github.com:llvm/llvm-project.git llvmorg-11.0.1-0-g43ff75f2c3fe)
> Target: x86_64-unknown-freebsd14.0
> Thread model: posix
> InstalledDir: /usr/bin
> 

Doesn't surprise me.  gcc knows about freebsd special handling of
the i387 on i686-*-freebsd.  clang does not.

clang:
% cc -E -dM -c -march=i686 testf.c | egrep "(FLT_EVAL_METHOD|__ILP32|__LP64)"
#define FLT_EVAL_METHOD (-1)
#define __FLT_EVAL_METHOD__ 2
#define __ILP32__ 1

gcc10:
% gcc10 -E -dM -c -march=i686 testf.c | egrep "(FLT_EVAL_METHOD|__ILP32|__LP64)"
#define __FLT_EVAL_METHOD__ 2
#define __FLT_EVAL_METHOD_TS_18661_3__ 2
#define __ILP32__ 1
#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__

-- 
Steve



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20210216010130.GA87472>