The program listed below involves only integers, and is deterministic. When compiled with the IFX 20211123 build with /Od on Windows 11, the output is
Ifort and other Fortran compilers give the same result. When IFX is used with /O2, etc., the output is
The program does cause integer overflow, but the code is part of a random number generator, performing lots of shifts and bit operations, so the overflow should be handled as usual.
Here is the program source.
Module sk64_m Implicit None Integer, Parameter :: i8 = selected_int_kind(18) Integer (Kind=i8) :: q = 5797281239641574547_i8, carry = 36243678541_i8 Contains subroutine refill() Implicit None Integer (Kind=i8) :: z z = ishft(ishft(q,41),-1) + ishft(ishft(q,39),-1) + ishft(carry,-1) carry = ishft(q, -23) + ishft(q, -25) + ishft(z, -63) print '(i21)',carry Return End subroutine refill End Module sk64_m Program tk64 Use sk64_m call refill() End Program tk64
Since everything is known ahead of time, it would be interesting to see how much code was removed by the optimization.
In theory, it could have precomputed the final value of carry, and just printed out the precomputed value. The difference would
then be in how the compiler itself handled the computation rather than how it would have worked if all the computations were performed in compiled code.
Does (your version) of ifx generate the correct result with optimizations disabled?
The ishft should be treating the numbers as unsigned (even though Fortran only supports signed INTEGERs).
Look at the disassembly code to verify that the shift instructions are unsigned.
Secondly, you have a value (q) that is shifted left nn positions immediately followed by shift right 1 position. Check to see if the optimization contains both shifts as opposed to shifting left nn-1 positions. This are not the same as the correct way will always result in 0 in the msb position and the incorrect way will not.