Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 8 Nov 2012 16:11:36 +1100 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Jung-uk Kim <jkim@FreeBSD.org>
Cc:        svn-src-head@FreeBSD.org, svn-src-all@FreeBSD.org, src-committers@FreeBSD.org, Dimitry Andric <dim@FreeBSD.org>
Subject:   Re: svn commit: r242715 - head/sys/conf
Message-ID:  <20121108151338.G2278@besplex.bde.org>
In-Reply-To: <509AE28E.4020908@FreeBSD.org>
References:  <201211072215.qA7MFSYX017265@svn.freebsd.org> <509AE28E.4020908@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 7 Nov 2012, Jung-uk Kim wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> On 2012-11-07 17:15:28 -0500, Dimitry Andric wrote:
>> Author: dim Date: Wed Nov  7 22:15:28 2012 New Revision: 242715
>> URL: http://svnweb.freebsd.org/changeset/base/242715
>>
>> Log: For kernel builds with PROFLEVEL >= 1, such as LINT, don't
>> attempt to use the -falign-functions option if the compiler is
>> clang, as the flag is not supported.

This just breaks the warning.  The alignment is needed for PROFLEVEL >= 1
(that is any profiling at all) to actually work.  Constants in
<machine/profile.h> depend on it, or rather the reverse -- the alignment
supports these constants.

PROFLEVEL >= 2 depends more critically on the alignment, but is more
completely broken.

>> Modified: head/sys/conf/kern.pre.mk
>> ==============================================================================
>>
> - --- head/sys/conf/kern.pre.mk	Wed Nov  7 22:11:38 2012	(r242714)
>> +++ head/sys/conf/kern.pre.mk	Wed Nov  7 22:15:28 2012	(r242715) @@
>> -102,7 +102,10 @@ CLANG_NO_IAS= -no-integrated-as .endif
>>
>> .if defined(PROFLEVEL) && ${PROFLEVEL} >= 1 -CFLAGS+=	-DGPROF
>> -falign-functions=16 +CFLAGS+=	-DGPROF +.if ${COMPILER_TYPE} !=
>> "clang" +CFLAGS+=	-falign-functions=16 +.endif .if ${PROFLEVEL} >=
>> 2 CFLAGS+=	-DGPROF4 -DGUPROF PROF=	-pg -mprofiler-epilogue
>
> FYI, PROF needs a similar work-around:
>
> % clang -c -pg -mprofiler-epilogue test.c
> clang: warning: argument unused during compilation: '-mprofiler-epilogue'

Again, this just breaks the warning.  The main part of the complete
brokenness of PROFLEVEL >= 2 is that gcc doesn't ignore this option,
but it just doesn't work.  I got tired of fixing breakages of this 
a few rounds ago.  A previous round used -finstrument-functions, but
this generated bloated code and is much worse now since it now
generates instrumentation for all the little inline functions like
curthread that you don't want to instrument, unless you use large
complicatins to kill their instrumentation selectively (there is
an attribute for this, but there seems to be no compiler flag for
a less-selective kill).

clang's lack of support for other gcc flags is annoying.  One such
flag is -mpreferred-stack-boundary.  This is important for reducing
kernel stack bloat with gcc.  clang has better stack alignment so
it doesn't really need the flag, but using it gives anyoying warnings
so you have to ifdef for it...

clang also has lots of floating point bugs.  Some are shared with gcc
but act a little differently so that the workarounds for them in gcc
don't ameliorate them.  The last 3 that I noticed are:

- overflowing multiplications of constants are misoptimized to infinity
   with no overflow.  gcc has a similar bug for underflowing
   multiplications of constants.  clang has this too.  libm has many
   lines of work-arounds for the missing underflow but not for the
   missing overflow.  Perhaps the missing exceptions are permitted
   by the default for the FENV_ACCESS pragma, and in that case the
   bug might be a different default.  Neither gcc nor clang supports
   C99 here, so they have essentially null support for the pragma
   and null support for what it controls.  gcc defaults to a setting
   that is fairly fail-safe, and even documents this in its info
   page.

- clang fails to optimize division by (integer) 2 into multiplication
   by (floating point with the correct type) 0.5 in the case of long
   doubles on one supported arch (i386 IIRC).  Both compilers optimize
   all other cases, including floats and doubles on all arches.  clang
   with -ffast-math optimizes the broken case, but -ffast-math is
   generally unsafe and not even fast; it shouldn't be necessary for
   this, since this is one of the few floating point strength reductions
   that is always safe.  This detail is not documented for either clang
   or gcc.  clang doesn't even document the existence of -ffast-math in
   its man page.

   Several uncommitted libm functions use the spelling of (integer) 2
   to avoid ifdefs and/or different code to get the type right for 0.5.
   The result is that the case of long doubles on i386 is pessimized.
   clang has many other efficiency and ABI problems on i386, including
   the next one.

- clang doesn't align long doubles on i386 when this is possible.  The
   i386 ABI is unfortunately broken for long doubles (and doubles), and
   only requires 4-byte alignment.  However, 8-byte alignment is possible
   in many cases (e.g., for all auto and static objects).  Both compilers
   use 8-byte alignment for doubles in all cases and should do the same
   for long doubles (or perhaps 16-byte, but that just waste space on
   most or all current CPUs AFAIR, even for ABI where the ABI requires
   at least the size of a long double to be 16).  clang only does 4-byte
   alignment for long doubles, at least in the important case of static
   constants.  (static constants are handled by both compilers by
   replacing them by unnamed objects having better locality and alignment
   if possible.  x86 allows just a few cases where the object is an
   immediate constant.)

I mostly don't notice other floating point bugs in clang because I
noticed them before and have scattered work-arounds for them.  Not
very many.  The largest ones involve FLT_EVAL_METHOD, float_t and
double_t.  On i386, these are broken in both the clang and the
FreeBSD headers.  The headers just use the gcc values with no
ifdefs.  Correct ifdefs are not easy to write because compiler
pre-defines like __FLT_EVAL_METHOD are even more broken.  The
broken FLT_EVAL_METHOD, float_t and double_t mainly give inefficencies
because they are mostly fail-safe.  When you try to fix them, you
get larger ABI problems.

Bruce



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