Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Sun, 1 Apr 2018 16:29:06 +0200
From: Szabolcs Nagy <>
Subject: Re: Views on bare metal port

* ardi <> [2018-04-01 13:19:01 +0200]:
> On Wed, Jan 31, 2018 at 7:25 PM, Szabolcs Nagy <> wrote:
> >
> > note that in particular for math code llvm is problematic.
> >
> > i'm not aware of any issues in musl libm currently, but
> > rounding mode changes can break in unexpected ways because
> > there is no support for -frounding-math (last time i checked
> > the few cases where it matters clang did not miscompile those,
> > but this is not actively tested)
> >
> > an illustration of the kind of things that can go wrong:
> >
> > we don't have equivalent hacks in musl.
> Being a clang user, this comment has worried me, because, according to
> this bug report, there's a risk of generating wrong code:
> However, a participant in the bug comments, argues that this doesn't
> really violate standards compliance, just that a C99 feature is not
> implemented yet, and that a warning will be triggered:
> >> (quoting Richard Smith at bug report above):
> >>
> >> You are mistaken. Setting the rounding mode
> >> without using #pragma STDC FENV_ACCESS ON
> >> invokes undefined behavior. See C11 7.6.1/2. (This
> >> pragma does not exist in C++, so <cfenv> is
> >> unusable, but that's not our fault...)
> >>

this is half true:

the default state of FENV_ACCESS is implementation defined,
when it's off then accessing the fenv is indeed ub.

in clang the default is off (which is fine) but there
is no way to turn it on (which is a conformance bug).

c++ is of course broken, unusable for numeric code.

> >> Clang doesn't support that pragma, making this
> >> an unimplemented feature from C99, for which we
> >> will produce a warning or error. That's the subject of
> >> this enhancement request.

this is false:

c99 fenv semantics is fully implementible without
supporting the pragma: never do code transformations
that break under fenv access, this is correct with
whatever pragma usage.
(musl code uses the pragma so there is no ub)

> Now, and to the point that really interests me (generating safe code
> from a clang+musl environment):
> - What kind of math operations can be affected by this bug?
> - Is there any workaround at this moment?
> - Or is gcc the only compiler that can generate valid math code with
> musl at this moment and we should better wait until clang gets bug
> 8100 fixed?

in short:

most things will work even if musl is compiled by a
compiler without fenv access support, but it won't
be fully conforming when the caller changes or tests
the fenv.

in detail:

floating-point code may give wrong results in
non-nearest rounding mode, although in practice
optimizations that significantly break things are
rare (one example is const folding with nearest
rounding mode assumption)

floating-point code that itself changes rounding
mode can break badly, this is rare in practice,
but happened e.g in fma (which was indeed miscompiled
but we have a different algorithm now which has no
fenv access)

floating-point status flags may be wrong so code
that makes decisions based on that can be broken.

so if user code always calls libc apis with default
rounding mode and does not use the fenv status then
everything should work correctly with a miscompiled
musl, except fmaf and fmal which change the rounding
mode and lrint* and nearbyint* which check the status
flags can in principle be broken, however they are
written in a way that it's unlikely that the compiler
would do some code breaking transformation.

if you want to call libc functions with non-nearest
rounding mode then you can get wrong results or if
you test the status flags they may be wrong (even in
nearest rounding mode), but in those case you should
also worry about the calling code not just libc.

gcc does not support the fenv access pragma either
but it has -frounding-math which correctly compiles
all cases when a function must work with arbitrary
rounding mode (e.g. it does not do incorrect const
foldings), however it still miscompiles a few cases
when a function itself changes rounding mode
(floating-point operations must not be moved across
function calls in that case, but gcc does) and
sometimes it does not handle floating-point status
flags correctly (if the only side-effect of an
operation is the fenv status then gcc can optimize
it away so status flag settings may be missing,
there is an -ftrapping-math option which should take
care of this but it does not do anything useful)

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.