[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