Skip to content

Semantically-equivalent expressions evaluating at different values with -O1

The following code shows inconsistent results when compiled with -O1:

import Data.Bits ((.&.))

flags :: Int -> [Int]
flags x = filter (\y -> x .&. y > 0) [1, 128, 129, 255]

main :: IO ()
main = do
  putStrLn $ show $ flags $ 255   -- These lines should display
  putStrLn  (show  (flags   255)) -- the same value, right?

-- It appears that this is related to something that started
-- with GHC 7.10, but was also changed in GHC 8.0, as we can
-- see from the following tests:
--
-- Stack snapshot lts-0.7 (GHC 7.8.3), with -O2
-- [1,128,129,255]
-- [1,128,129,255]
--
-- Stack snapshot lts-2.22 (GHC 7.8.4) with -O2
-- [1,128,129,255]
-- [1,128,129,255]
--
-- Stack snapshot lts-3.22 (GHC 7.10.2) with -O2
-- [1]
-- [1]
--
-- Stack snapshot lts-6.30 (GHC 7.10.3) with -O2
-- [1]
-- [1]
--
-- Stack snapshot lts-7.20 (GHC 8.0.1) with -O2
-- [1]
-- [1,128,129,255]
--
-- Stack snapshot lts-8.5 (GHC 8.0.2) with -O2
-- [1]
-- [1,128,129,255]
--
-- In GHC 8.0.2, compiling with any of the following...
--   -O0
--   -O2 -fno-cmm-sink
--   -O2 -fno-enable-rewrite-rules
--
-- ...we get the expected results:
-- [1,128,129,255]
-- [1,128,129,255]
--
-- Using only -O1, we get the abnormal behavior again:
-- [1]
-- [1,128,129,255]
Trac metadata
Trac field Value
Version 8.0.2
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information