# Surprising @fastmath behavior

**URL:** https://discourse.julialang.org/t/surprising-fastmath-behavior/54600
**Category:** Performance
**Tags:** fast-math
**Created:** [February 4, 2021, 9:04am UTC](https://discourse.julialang.org/t/surprising-fastmath-behavior/54600 "2021-02-04T09:04:50Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![Christian\_Rorvik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christian_rorvik/32/965_2.png) [@Christian\_Rorvik](https://discourse.julialang.org/u/Christian_Rorvik)
#### Post date: [February 4, 2021, 9:04am UTC](https://discourse.julialang.org/t/surprising-fastmath-behavior/54600/1 "2021-02-04T09:04:50Z")

</div>

Here’s something that caught me off guard. Example is reduced to trivial code, but I caught this in a much more complex context.

```nohighlight
function foo(a, b, c)
    @fastmath x = a * b + c
    isnan(x) ? 0.0 : x
end
code_native(foo, (Float64, Float64, Float64); debuginfo = :none, syntax = :intel)

```

Outputs:

```nohighlight
	vfmadd213sd	xmm0, xmm1, xmm2 # xmm0 = (xmm1 * xmm0) + xmm2
	ret

```

For reference, without `@fastmath`:

```nohighlight
	vmulsd	xmm0, xmm0, xmm1
	vaddsd	xmm0, xmm0, xmm2
	vcmpordsd	xmm1, xmm0, xmm0
	vandpd	xmm0, xmm1, xmm0
	ret

```

So `@fastmath` doesn’t just affect the computation of `x` (enabling fma in this case), but it attached some metadata to `x` to say its value can never be `NaN`. I always assumed `@fastmath` would apply to the expression only, and not subsequent assumptions the compiler could make, but is this what’s expected?

A few notes

- In the real use case where this came computation and `NaN` check are two separate function that happen to be inlined in a parent scope. For this to fail in this manner, the inliner has to decide to include both parts, which makes it a fickle bug to discover.
- Yes, I know `@fastmath` comes with big warning labels and all bets are off. I just want to know if this is intended in the design of it.
- Yes, I know in this case I can use `muladd()`, it’s a reduced example.

---

<div class="post-metadata">

### Author: ![moeddel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/moeddel/32/18641_2.png) [@moeddel](https://discourse.julialang.org/u/moeddel)
#### Post date: [February 4, 2021, 9:53am UTC](https://discourse.julialang.org/t/surprising-fastmath-behavior/54600/2 "2021-02-04T09:53:22Z")

</div>

According to the docs  
[https://llvm.org/docs/LangRef.html#fast-math-flags](https://llvm.org/docs/LangRef.html#fast-math-flags)  
`@fastmath` enables the `nnan` flag, which allows for optimizations to assume the arguments and result are not NaN.

With this in mind I would say that what you encountered is to be expected.

If you use `muladd` you get the correct behaviour.

```julia
function foo(a, b, c)
    x = muladd(a,b,c)
    return isnan(x) ? 0.0 : x
end

code_native(foo, (Float64, Float64, Float64); debuginfo = :none, syntax = :intel)

```

outputs

```julia
vfmadd213sd	xmm0, xmm1, xmm2 # xmm0 = (xmm1 * xmm0) + xmm2
vcmpordsd	xmm1, xmm0, xmm0
vandpd	xmm0, xmm1, xmm0
ret

```

---

<div class="post-metadata">

### Author: ![Christian\_Rorvik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/christian_rorvik/32/965_2.png) [@Christian\_Rorvik](https://discourse.julialang.org/u/Christian_Rorvik)
#### Post date: [February 4, 2021, 10:38am UTC](https://discourse.julialang.org/t/surprising-fastmath-behavior/54600/3 "2021-02-04T10:38:40Z")

</div>

I’m aware it enables `nnan` for the expression, and that’s what in many cases I want (e.g., for `min/max`), and yes I know I can use `muladd` to achieve the specific effect in this specific code. My only question is whether it’s intended for `@fastmath` to attach assumptions to resulting variables and subsequent computation outside the scope of its expression.

– EDIT –  
Reading the LLVM docs closer, it’s free to assume the results are not `NaN` or produce a poison value, so if Julia `@fastmath` is a direct translation to the LLVM decorator, that makes sense. Thanks for pointing out the link.

---

<div class="post-metadata">

### Author: ![moeddel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/moeddel/32/18641_2.png) [@moeddel](https://discourse.julialang.org/u/moeddel)
#### Post date: [February 4, 2021, 10:45am UTC](https://discourse.julialang.org/t/surprising-fastmath-behavior/54600/4 "2021-02-04T10:45:54Z")

</div>

> [@Christian\_Rorvik](#):
>
> – EDIT –  
> Reading the LLVM docs closer, it’s free to assume the results are not `NaN` or produce a poison value, so if Julia `@fastmath` is a direct translation to the LLVM decorator, that makes sense. Thanks for pointing out the link.

This was the point I was trying to make.
