integerGcd sometimes returns an incorrect result
Summary
With GHC 9.0.1-alpha1, integerGcd
sometimes returns an incorrect result.
I suspect the cause is an out-of-bounds access in bigNatCompareWord#
.
Steps to reproduce
Run the following code
#!/usr/bin/env cabal
{- cabal:
build-depends: base, ghc-bignum, QuickCheck
-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MagicHash #-}
import GHC.Exts
import GHC.Num.BigNat (bigNatCompareWord#, bigNatFromWord#)
import GHC.Num.Integer (integerGcd)
import Test.QuickCheck
main :: IO ()
main = do
quickCheck $ withMaxSuccess 1000000 $
forAll (choose (2^63, 2^64-1)) $ \x ->
\y ->
integerGcd x (toInteger y) === toInteger (gcd (fromInteger x) y :: Word)
quickCheck $ withMaxSuccess 1000000 $
\x@(W# x#) -> let !x' = bigNatFromWord# x# in
\y@(W# y#) ->
bigNatCompareWord# x' y# === compare x y
with something like
$ cabal v2-run --with-compiler=/opt/ghc-9.0.1-alpha1/bin/ghc --constraint="QuickCheck -templatehaskell" Test.hs
Then, I get failures like
*** Failed! Falsified (after 1126 tests):
14205695611797621937
2
2 /= 1
*** Failed! Falsified (after 3 tests and 1 shrink):
1
1
GT /= EQ
Expected behavior
The test should succeed; both integerGcd
and bigNatCompareWord#
should do their work.
Environment
- GHC version used: GHC 9.0.1-alpha1
- Operating System: macOS 10.15.7
- System Architecture: x86_64