[GHC] #14619: Output value of program changes upon compiling with -O optimizations

GHC ghc-devs at haskell.org
Wed Dec 27 19:53:51 UTC 2017


#14619: Output value of program changes upon compiling with -O optimizations
-------------------------------------+-------------------------------------
        Reporter:  sheaf             |                Owner:  (none)
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  8.2.2
      Resolution:                    |             Keywords:
Operating System:  Windows           |         Architecture:  x86_64
 Type of failure:  Incorrect result  |  (amd64)
  at runtime                         |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by RyanGlScott):

 I am curious as to why it's failing on earlier GHC versions. Here's a
 slightly modified version of the program that also prints different output
 depending on the optimization level:

 {{{#!hs
 module Main (main) where

 import Debug.Trace

 type V3 = (Double, Double, Double)

 infixl 6 <->
 infixl 7 <.>

 (<->) :: V3 -> V3 -> V3
 (<->) (x, y, z) (x', y', z') = (x-x', y-y', z-z')

 (<.>) :: V3 -> V3 -> Double
 (<.>) (x, y, z) (x', y', z') = x*x'+y*y'+z*z'

 sphereIntersection :: V3 -> V3 -> V3
 sphereIntersection orig dir
   | t1 > 0 = traceShow ("orig", orig) $
              traceShow ("dir", dir) $
              -- traceShow ("oc", oc) $
              traceShow ("b", b) $
              traceShow ("disc", disc) $
              traceShow ("sqrtDisc", sqrtDisc) $
              traceShow ("t1", t1) $
              dir
     where oc = (0, 0, 200) <-> orig
           b  = oc <.> dir
           disc =  50000 - oc <.> oc
           sqrtDisc = sqrt disc
           t1 = b - sqrtDisc
 {-# NOINLINE sphereIntersection #-}

 main :: IO ()
 main = print $ sphereIntersection (0, 0, 0) (0, 0, 1)
 }}}
 {{{
 $ ghc -O0 Foo.hs -fforce-recomp
 [1 of 1] Compiling Main             ( Foo.hs, Foo.o )
 Linking Foo.exe ...

 $ ./Foo.exe
 ("orig",(0.0,0.0,0.0))
 ("dir",(0.0,0.0,1.0))
 ("b",200.0)
 ("disc",10000.0)
 ("sqrtDisc",100.0)
 ("t1",100.0)
 (0.0,0.0,1.0)

 $ ghc -O1 Foo.hs -fforce-recomp
 [1 of 1] Compiling Main             ( Foo.hs, Foo.o )
 Linking Foo.exe ...

 $ ./Foo.exe
 ("orig",(0.0,0.0,0.0))
 ("dir",(0.0,0.0,0.0))
 ("b",200.0)
 ("disc",10000.0)
 ("sqrtDisc",100.0)
 ("t1",100.0)
 (0.0,0.0,0.0)
 }}}

 Notice that in the optimized version, GHC thinks the `dir` argument is
 `(0.0,0.0,0.0)`, when it should be `(0.0,0.0,1.0)`!

 To make things stranger, if you uncomment the `traceShow ("oc", oc) $`
 line, then the optimized program's answer is different (but still wrong):

 {{{
 $ ghc -O1 Foo.hs -fforce-recomp
 [1 of 1] Compiling Main             ( Foo.hs, Foo.o )
 Linking Foo.exe ...

 $ ./Foo.exe
 ("orig",(0.0,0.0,0.0))
 ("dir",(0.0,0.0,40000.0))
 ("oc",(0.0,0.0,200.0))
 ("b",200.0)
 ("disc",10000.0)
 ("sqrtDisc",100.0)
 ("t1",100.0)
 (0.0,0.0,40000.0)
 }}}

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14619#comment:8>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list