Output value of program changes upon compiling with -O optimizations
The optimisation pass seems to affect the behaviour of the attached program (a basic ray-sphere intersection test, 40 lines long, no dependencies).
Specifically, compiling the attached source file with -O or -O2, and considering the definition of main:
result = sphereIntersection testRay testSphere main :: IO() main = do print $ result print $ sphereIntersection testRay testSphere
I get the troubling output:
> bug.exe Just ((0.0,0.0,0.0),0.0) Just ((0.0,0.0,100.0),1.0)
This is especially troubling because the second component of the output should always be 1.0:
testRay = ((0, 0, 0),(0, 0, 1)) sphereIntersection (orig, dir@(_, _, dirz)) (c,r) | disc < 0 = Nothing | t1 > 0 = Just (t1 *> dir <+> orig, dirz) | t2 > 0 = Just (t2 *> dir <+> orig, dirz) | otherwise = Nothing where ...
as we are returning the "dirz" component of the input ray straight back out.
On the other hand, when the program is run without optimisations, I get the expected output:
> bug.exe Just ((0.0,0.0,100.0),1.0) Just ((0.0,0.0,100.0),1.0)
This behaviour was present on all versions of GHC that I tested (7.10.1, 8.0.1, 8.2.1, 8.2.2). I initially ran into this issue when I noticed that the profiling builds of my program produced different results, which was boiled down to this problem.