Skip to content

Constant folding on 'mod/Word' - incorrect result

Compiling this with GHC 7.10.3 on both MacOS and Linux with '-O' producess results '5 0'.

module Main where

testfn :: Word -> IO ()
testfn wseq = do
  print $ wseq `mod` 1

main = do
  testfn 5
  print $ (5 :: Word) `mod` 1

Changing type to Int produces correct result. It has probably something to do with compiler/prelude/PrelRules.hs - the rules for Int and Word differ. It seems to me that it should be optimized the same way, but the culprit seems to be the 'rightIdentityDynFlags onew' - that seems to be a clear bug (if it does what I think it does).

primOpRules nm IntRemOp    = mkPrimOpRule nm 2 [ nonZeroLit 1 >> binaryLit (intOp2 rem)
                                               , leftZero zeroi
                                               , do l <- getLiteral 1
                                                    dflags <- getDynFlags
                                                    guard (l == onei dflags)
                                                    retLit zeroi
                                               , equalArgs >> retLit zeroi
                                               , equalArgs >> retLit zeroi ]
primOpRules nm WordRemOp   = mkPrimOpRule nm 2 [ nonZeroLit 1 >> binaryLit (wordOp2 rem)
                                               , rightIdentityDynFlags onew ]

I found it in different code where lots of inlining reduced some branch of code into this and produced wrong result.

Trac metadata
Trac field Value
Version 7.10.3
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Prelude
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