# A piece of code that causes LLVM Flang to generate NaN/Inf randomly

**URL:** <https://fortran-lang.discourse.group/t/a-piece-of-code-that-causes-llvm-flang-to-generate-nan-inf-randomly/10713>\
**Category:** Flang\
**Created:** [February 11, 2026, 5:39pm UTC](https://fortran-lang.discourse.group/t/a-piece-of-code-that-causes-llvm-flang-to-generate-nan-inf-randomly/10713 "2026-02-11T17:39:52Z")\
**Posts on this page:** 13\
**Page:** 2

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [February 17, 2026, 4:47pm UTC](https://fortran-lang.discourse.group/t/a-piece-of-code-that-causes-llvm-flang-to-generate-nan-inf-randomly/10713/21 "2026-02-17T16:47:59Z")

</div>

Yes, parallel operations can synchronize/reduce in different orders and produce different results. Also, anything involving random numbers (random from run to run), such as monte carlo simulations, will produce different results. But this code discussed here does not involve parallel execution or random number simulations, and it isn’t just that the results are different, it is sometimes the code traps exceptions, sometimes it doesn’t, and sometimes the exceptions differ. So something odd seems to be happening, and it seems to be related to the fast-math option; whether it is a programmer error or a compiler error remains to be determined.

---

<div class="post-metadata">

**Author:** ![septc](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/septc/32/77_2.png) [@septc](https://fortran-lang.discourse.group/u/septc)\
**Post date:** [February 17, 2026, 8:35pm UTC](https://fortran-lang.discourse.group/t/a-piece-of-code-that-causes-llvm-flang-to-generate-nan-inf-randomly/10713/22 "2026-02-17T20:35:27Z")

</div>

> [@tmj](#):
>
> One of the optimizations nuked the division; we never load anything into the descriptor - we see it allocate the space (56 bytes), save the pointer in the descriptor, but never populate it with results before the call.

To understand the meaning of the assembly code more, I have just tried using an LLM about the code. Then, it says the assembly code is built for x86-64 (not for ARM64); is this correct…?

~~Also, do you possibly know how to generate such an assembly code on mac (ARM64)? I have tried `-fverbose-asm` and `-emit-llvm`, but I could not get a (text-based) assembly code like the above… (though I got a binary `.bc` file instead).~~

I’m sorry for the noise, I was able to get the assembly code with the `-S` option! (I imagined that I may need some special option for flang…) `-S -emit-llvm` also gave me an intermediate file with `.ll`, and `-S -save-temps` gave `.mlir` files.

> [@themos](#):
>
> Having said all that, the actual bug that I see in LLVM-flang is that the runtime routine `Fortran::decimal::ConvertToDecimal<24>` hits a reference to an uninitialised variable, as valgrind reveals (after compiling with `-O2 -ffast-math`). This could be how different results end up in the output.

I’ve tried installing valgrind on my mac (M1), but Homebrew failed with the message “valgrind: Linux is required for this software”… So I wonder if you used Linux (or possibly Windows) for the above test with valgrind…?

---

<div class="post-metadata">

**Author:** ![JohnCampbell](https://avatars.discourse-cdn.com/v4/letter/j/5daacb/32.png) [@JohnCampbell](https://fortran-lang.discourse.group/u/JohnCampbell)\
**Post date:** [February 18, 2026, 12:25am UTC](https://fortran-lang.discourse.group/t/a-piece-of-code-that-causes-llvm-flang-to-generate-nan-inf-randomly/10713/23 "2026-02-18T00:25:10Z")

</div>

> [@RonShepard](#):
>
> it is sometimes the code traps exceptions, sometimes it doesn’t, and sometimes the exceptions differ.

The most likely explaination for this is there are uninitialised variables/memory being used, rather than `-ffast-math` issues.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [February 18, 2026, 1:05am UTC](https://fortran-lang.discourse.group/t/a-piece-of-code-that-causes-llvm-flang-to-generate-nan-inf-randomly/10713/24 "2026-02-18T01:05:54Z")

</div>

I agree that is usually the cause for this kind of behavior, but I did not see any uninitialized variables in the posted code. I only see literal constants that could compile to zero or to denormal floating point values. Those values are then used in expressions.

edit: Does anyone know what the standard says about initializations and assignments of literal constants that are smaller than `tiny()`? I think what I said above is correct, but I don’t know offhand the part of the standard that governs that behavior.

---

<div class="post-metadata">

**Author:** ![septc](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/septc/32/77_2.png) [@septc](https://fortran-lang.discourse.group/u/septc)\
**Post date:** [February 18, 2026, 1:55am UTC](https://fortran-lang.discourse.group/t/a-piece-of-code-that-causes-llvm-flang-to-generate-nan-inf-randomly/10713/25 "2026-02-18T01:55:22Z")

</div>

Hi Ron, I guess you could also try generating assembly codes or intermediate code and copy-paste them into some LLMs (with a prompt to explain the meaning line-by-line). I have tried a bit with ChatGPT, and it is pretty interesting to see the result (because I do not know how to read assembly etc… 😅) It might be even possible to ask about uninitialized variables at the assembly or intermediate level.

Also, the Github issue page (linked in the first post) has more information, with the last comment below:

- [flang-21 produces NaN and Inf when it should not, randomly · Issue #180957 · llvm/llvm-project · GitHub](https://github.com/llvm/llvm-project/issues/180957#issuecomment-3893412610)

---

<div class="post-metadata">

**Author:** ![themos](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/themos/32/521_2.png) [@themos](https://fortran-lang.discourse.group/u/themos)\
**Post date:** [February 18, 2026, 8:57am UTC](https://fortran-lang.discourse.group/t/a-piece-of-code-that-causes-llvm-flang-to-generate-nan-inf-randomly/10713/26 "2026-02-18T08:57:42Z")

</div>

> [@septc](#):
>
> So I wonder if you used Linux

Indeed I did.

---

<div class="post-metadata">

**Author:** ![themos](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/themos/32/521_2.png) [@themos](https://fortran-lang.discourse.group/u/themos)\
**Post date:** [February 18, 2026, 9:14am UTC](https://fortran-lang.discourse.group/t/a-piece-of-code-that-causes-llvm-flang-to-generate-nan-inf-randomly/10713/27 "2026-02-18T09:14:23Z")

</div>

I have reduced the reproducer further, it has nothing to do with denormal numbers.

```auto
use iso_fortran_env, only : RP => REAL32
implicit none
real(RP) :: a(14), b(14), c

a = 0.
b = a / maxval(a)
c = maxval(a)
print *, a/maxval(a), '|', b
print *, a/c, '|', b
end

```

---

<div class="post-metadata">

**Author:** ![tmj](https://avatars.discourse-cdn.com/v4/letter/t/ed655f/32.png) [@tmj](https://fortran-lang.discourse.group/u/tmj)\
**Post date:** [February 23, 2026, 2:37pm UTC](https://fortran-lang.discourse.group/t/a-piece-of-code-that-causes-llvm-flang-to-generate-nan-inf-randomly/10713/28 "2026-02-23T14:37:56Z")

</div>

But that’s just a different version of the same underlying issue - this new code only removed one step taken in the initial test case (the FTZ issue) and is simply performing an explicit 0./0. while telling the compiler to use optimizations which should assume there is no division by zero.

The optimizer is removing some of the ops since the compiler options were explicit in saying it is safe to do so. Thus we see the ops which would otherwise have filled the print buffer get removed - so you get whatever happened to be in memory.

---

<div class="post-metadata">

**Author:** ![themos](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/themos/32/521_2.png) [@themos](https://fortran-lang.discourse.group/u/themos)\
**Post date:** [February 23, 2026, 3:11pm UTC](https://fortran-lang.discourse.group/t/a-piece-of-code-that-causes-llvm-flang-to-generate-nan-inf-randomly/10713/29 "2026-02-23T15:11:16Z")

</div>

I believe that the Standard requires the output field to be initialized to blanks:  
_If the number of characters produced by the editing is smaller than the field width, leading blanks are inserted in the field._ (13.7.2.1 (p1) (c4) J3/26-007)

---

<div class="post-metadata">

**Author:** ![tmj](https://avatars.discourse-cdn.com/v4/letter/t/ed655f/32.png) [@tmj](https://fortran-lang.discourse.group/u/tmj)\
**Post date:** [February 23, 2026, 7:04pm UTC](https://fortran-lang.discourse.group/t/a-piece-of-code-that-causes-llvm-flang-to-generate-nan-inf-randomly/10713/30 "2026-02-23T19:04:47Z")

</div>

Is `0x3f9e0610` a valid REAL(KIND=4), or is that uninitialized memory due to a previous operation being deleted?

We could certainly `calloc()` the temporary in the specific location related to this particular issue so that the result is guaranteed not to be uninitialized memory. But this is still producing a wrong answer.

---

<div class="post-metadata">

**Author:** ![themos](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/themos/32/521_2.png) [@themos](https://fortran-lang.discourse.group/u/themos)\
**Post date:** [February 23, 2026, 7:19pm UTC](https://fortran-lang.discourse.group/t/a-piece-of-code-that-causes-llvm-flang-to-generate-nan-inf-randomly/10713/31 "2026-02-23T19:19:39Z")

</div>

I believe flang is not under any Standard-based obligation to produce a better/different answer for this case. From quality-of-implementation POV, it’s also what you can expect when minimum requirements are violated at runtime. My concern is that not clearing the output field with blanks could lead to proper Standard violation in other cases. I believe I have another test case that demonstrates this.

---

<div class="post-metadata">

**Author:** ![tmj](https://avatars.discourse-cdn.com/v4/letter/t/ed655f/32.png) [@tmj](https://fortran-lang.discourse.group/u/tmj)\
**Post date:** [February 23, 2026, 8:58pm UTC](https://fortran-lang.discourse.group/t/a-piece-of-code-that-causes-llvm-flang-to-generate-nan-inf-randomly/10713/32 "2026-02-23T20:58:47Z")

</div>

To be clear, I’m talking about the new reduced test case that uses explicit `0.` for `a`. The subnormal `a = 7.E-45` is a separate issue.

What I’m looking at is the data buffer upon which the blank-padded output buffer will be operating on. The format and the data to be formatted are different; the output field needs to be blank padded, yes. But that’s orthogonal to the question of if the buffer to be consumed contains valid data.

```auto
570 movl $56, %edi                                                       
571 callq malloc@PLT                                                      
572 movq %rax, %rbp                                                      
573 movq %rax, 440(%rsp)                                                 
574 movq $4, 448(%rsp)                                                   
575 movq %r12, 456(%rsp)                                                 
576 movq $1, 464(%rsp)                                                   
577 movq $14, 472(%rsp)                                                  
578 movq $4, 480(%rsp)                                                   
579 leaq 440(%rsp), %rsi                                                 
580 movq %r13, %rdi                                                      
581 callq _FortranAioOutputDescriptor@PLT

```

At best, one could use `calloc()` here - but is `0.` the correct answer or an indication something is wrong? Remember - `0x20202020` is a valid FP number as well, so you can’t just fill this buffer with “blanks” before (for example) passing it to mpfr for a translation resulting in a string of characters.

The compiler was requested y the user to perform an optimization which removed the lines located between 571 and 572 that would otherwise have populated the correct data into the data buffer - how does one detect that `_FortranAioOutputDescriptor` is being passed an uninitialized descriptor - other than enable fp traps (my preference) or use Valgrind?

---

<div class="post-metadata">

**Author:** ![zaikunzhang](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/zaikunzhang/32/785_2.png) [@zaikunzhang](https://fortran-lang.discourse.group/u/zaikunzhang)\
**Post date:** [February 24, 2026, 4:30am UTC](https://fortran-lang.discourse.group/t/a-piece-of-code-that-causes-llvm-flang-to-generate-nan-inf-randomly/10713/33 "2026-02-24T04:30:00Z")

</div>

Thank everyone for paying attention to this issue. Sorry I have been silent due to other business.

To avoid taking your time unnecessarily, I would like to let you know that the issue has been closed as completed by the LLVM maintainer:

> <https://github.com/llvm/llvm-project/issues/180957>
>
> With flang-21, the code at the end of the post generates NaN and Inf unexpectedl…y and \*\*randomly\*\*. 
> 
> The behavior can be reproduced by the following bash script. 
> \`\`\`bash
> rm -f a.out
> uname -a
> flang --version
> flang -fstack-arrays -std=f2018 -O3 -ffast-math -g test\_div\_flang.f90
> \# Run a.out 5 times to demonstrate the random NaN/Inf generation behavior
> for i in {1..5}; do
> echo "Run $i:"
> ./a.out
> done
> \`\`\`
> 
> N.B.: 
> 0. The \`-ffast-math\` flag is being used. I know, this is not recommended in practice, and it may give rise to un-mathematical results. However, the resutls should be deterministic. 
> 1. Keeping \`-ffast-math\`, different combinations of the compilation flags will lead to different results. 
> 2. Here are the results in my tests:
> - \[ubuntu\_x86.log\](https://github.com/user-attachments/files/25238070/ubuntu\_x86.log)
> - \[ubuntu\_arm.log\](https://github.com/user-attachments/files/25238072/ubuntu\_arm.log)
> - \[macos\_x86.log\](https://github.com/user-attachments/files/25238071/macos\_x86.log)
> - \[macos\_arm.log\](https://github.com/user-attachments/files/25238073/macos\_arm.log)
>     
> \*\*The results are not always the same across the runs. Look carefully :) \*\*
> 
> 3. The above results can be reproduced by forking https://github.com/zequipe/flang\_ranom\_nan and running the GitHub Actions. 
> 
> Thank you for taking a look.   
> 
> Code: 
> 
> \`\`\`fortran
> ! test\_div\_flang.f90
> program test\_div\_flang
> use iso\_fortran\_env, only : RP =\> REAL32
> 
> implicit none
> 
> ! The code may behave differently depending on the dimension of the array. Try them.
> real(RP) :: a(14), b(14), c
> a = \[0., 0., 7.E-45, 7.E-45, 0., 5.E-45, 0., 5.E-45, 5.E-45, 0., 0., 0., 0., 5.E-45\]
> 
> !real(RP) :: a(9), b(9), c
> !a = \[5.E-45, 0., 5.E-45, 5.E-45, 0., 0., 0., 0., 5.E-45\]
> !
> !real(RP) :: a(8), b(8), c
> !a = \[0., 5.E-45, 5.E-45, 0., 0., 0., 0., 5.E-45\]
> 
> b = a / maxval(abs(a))
> c = maxval(abs(a))
> 
> print \*, '\>\>\> Dimension = ', size(a)
> 
> print \*, a/maxval(abs(a)), '|', b
> print \*, (a/maxval(abs(a)))\*\*2, '|', b\*\*2
> print \* , '------------------'
> print \*, a, '|', a/maxval(abs(a)), '|', b
> print \*, a, '|', (a/maxval(abs(a)))\*\*2, '|', b\*\*2
> 
> print \* , '=================='
> 
> print \*, a/c, '|', b
> print \*, (a/c)\*\*2, '|', b\*\*2
> print \* , '------------------'
> print \*, a, '|', a/c, '|', b
> print \*, a, '|', (a/c)\*\*2, '|', b\*\*2
> 
> end program test\_div\_flang
> \`\`\`

To my understanding, the code and the optimization flags trigger undefined behaviour, so the result is not unexpected.

Many thanks to everyone again!

[Previous page](https://fortran-lang.discourse.group/t/a-piece-of-code-that-causes-llvm-flang-to-generate-nan-inf-randomly/10713.md?page=1)
