[LLVMdev] Representing -ffast-math at the IR level

Owen Anderson
Tue, 17 Apr 2012 17:16:07 -0000

Duncan,

On Apr 17, 2012, at 8:52 AM, Duncan Sands <baldrick at free.fr> wrote:

>>    Underflows may sound less important in this regard, but they can be
worse
>>    than overflows, because they can mostly or completely eliminate the
>>    significant bits, in complete silence, leaving the entire
computation
>>    worthless. Much of numerical analysis, especially in writing
floating point
>>    library functions, concerns the precise control of overflow and loss
of
>>    significance in specific operations. To the extent that
optimizations which
>>    make such control difficult or impossible, can render the use of a
compiler
>>    or backend unusable for that purpose.
>> 2. While the use of metadata for control of LLVM behavior is attractive
for its
>>    simplicity and power, the philosophy that it can be safely ignored
or even
>>    removed in some optimization passes would seem to doom its
effectiveness for
>>    controlling floating point optimizations. For anyone trying to use
source
>>    language and compiler option mechanisms to control for fp overflow
and
>>    underflow, this approach would seem ill conceived.
>
> I think there may be a misunderstanding here.  True, the design of metadata
is
> that it is not wrong to drop it.  However the compiler isn't trying to
drop it,
> it tries hard not to drop it: any cases of pointlessly dropped metadata are
a
> bug.  In this fpmath metadata is analogous to tbaa (type based alias
analysis
> metadata): if it is dropped you get conservatively correct results, but
some
> optimizations are missed.  Compiler writers don't like missing
optimizations!
> If you see any cases of fpmath metadata being dropped then please report
it.


There's a deeper concern here.  Suppose that we have a caller A, that is
compiled in "fast" mode, which calls B, which was compiled in
"strict" mode.  Suppose they both contain a computation of x*y, and
that B got inlined into A.

%mul_A = fmul float %x, %y !fpmath !{"fast"} ; Or however it's
spelled
%mul_B = fmul float %x, %y

GVN (and EarlyCSE, and InstCombine, ...) are going to to want to CSE the two
copies of x*y that arise.  If the version from A appears earlier than the
version from B, it will want to CSE the latter into the former.  This is not
legal, unless it also knows how to make the metadata on the early multiply
stricter.  However, that means that a pass like GVN or EarlyCSE cannot safely
ignore metadata that it does not understand!

This is a general problem with the semantics of LLVM metadata.  Being able to
strip it arbitrarily is not sufficient to guarantee that optimizations are
allowed to be completely ignorant of it.

--Owen