What would Your_Favorite_Compiler do?
cia_plant:     val x = unsafePerformIO $ readIORef x

    inc x = unsafePerformIO $ modifyIORef x (1+) >> readIORef x

    main = do
      x <- newIORef (10::Int)
      print $ val x + inc x

The result is 21.Edit: an explanation. GHC runs on graph reduction, and will do "normal order" reduction in the normal case. + is strict in both arguments, so (val x) will be fully evaluated before (inc x) is evaluated.If we replace with a lazy operator like (:), then we can get different results. Here is a program which will evaluate the (inc x) first:    main = do
      x <- newIORef (10::Int)
      print $ reverse $ val x : inc x : []

the expression is not fully evaluated until it is printed, and then it is evaluated in reverse order, so inc x runs before val x. The result is [11,11].Of course, none of this can be relied on. GHC does a lot of optimizations, and unsafe operations are unsafe.