[llvm-dev] different output with fast-math flag

Fabian Giesen via llvm-dev llvm-dev at lists.llvm.org
Tue Aug 21 18:00:55 PDT 2018


The generated code doesn't actually change between the two variants in 
this case. The actual difference here happens during the link step.

Specifying "-ffast-math" on the clang invocation that spawns the linker 
causes "crtfastmath.o" to get linked (Clang 
ToolChain::AddFastMathRuntimeIfAvailable).

crtfastmath.o puts the CPU in FTZ+DAZ mode (subnormals flushed to zero, 
subnormals are treated as zero).

1.0 / max in your program is a subnormal value, which hence gets flushed 
to zero.

If you don't want this to happen, don't specify -ffast-math on the clang 
invocation that calls the linker:

[fabiang at fabiang-pc-i7 flttest]$ clang -ffast-math fmath.c && ./a.out
d:0.000000e+00:
[fabiang at fabiang-pc-i7 flttest]$ clang -c -ffast-math fmath.c -o fmath.o 
&& clang fmath.o && ./a.out
d:1.000000e+00:

but more generally, if you want special values such as infinities, NaNs, 
subnormals and underflow/overflow conditions to be handled precisely 
(with full IEEE compliance), _don't use -ffast-math_.

You're explicitly opting out of compliance here, and yes, sometimes the 
differences are substantial.

-Fabian

On 8/21/2018 9:50 AM, sangeeta chowdhary via llvm-dev wrote:
> This is of course not homework. I am trying to understand how fast math 
> optimizations work in llvm. When I compared IR for both the programs, 
> the only thing I have noticed is that fdiv and fmul are replaced with 
> fdiv fast and fmul fast. Not sure what happens in fdiv fast and fmul fast.
> I feel that its because d/max is really small number and fast-math does 
> not care about small numbers and consider them to zero but this is so 
> incorrect.
> 
> On Tue, Aug 21, 2018 at 12:45 PM Stephen Canon <scanon at apple.com 
> <mailto:scanon at apple.com>> wrote:
> 
>>     On Aug 21, 2018, at 11:17 AM, sangeeta chowdhary via llvm-dev
>>     <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote:
>>
>>     Why the output is different for this below program when compiled
>>     using clang with fast-math optimization
>>
>>     #include<stdio.h>
>>
>>     intmain() {
>>     doubled = 1.0;
>>     doublemax = 1.79769e+308;
>>     d /= max;
>>     printf("d:%e:\n", d);
>>     d *= max;
>>     printf("d:%e:\n", d);
>>     return0;
>>     }
>>
>>     prints 0 with fast math but 1 without fast math.
> 
>     Please do not ask llvm-dev to do your homework. If this is genuinely
>     not a school assignment, reply to me off-list and I’ll help you
>     understand what’s happening here.
> 
>     – Steve
> 
> 
> 
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
> 


More information about the llvm-dev mailing list