Simon Jakobi pushed to branch wip/sjakobi/T21176-integer-bits at Glasgow Haskell Compiler / GHC

Commits:

11 changed files:

Changes:

  • changelog.d/T21176
    1
    +section: ghc-internal
    
    2
    +synopsis: Give ``setBit``, ``clearBit`` and ``complementBit`` explicit definitions in ``instance Bits Integer``, backed by new ``integerSetBit[#]``, ``integerClearBit[#]`` and ``integerComplementBit[#]`` functions. These avoid the intermediate ``Integer`` allocations of the previous default methods, although allocation is not eliminated entirely — notably the negative (``IN``) cases would require in-place mutation, which is left as future work. As a trade-off, constant folding of these operations now applies only to small (machine-word-sized) literal arguments; the previous default methods folded literal ``Integer`` arguments of any size via the ``integerOr``/``integerAnd``/``integerXor`` rules.
    
    3
    +issues: #21176
    
    4
    +mrs: !7772

  • changelog.d/config
    ... ... @@ -27,7 +27,7 @@ sections: {
    27 27
       cmm               Cmm
    
    28 28
       build-tools       Build tools
    
    29 29
       base              ``base`` library
    
    30
    -  ghc-prim          ``ghc-prim`` library
    
    30
    +  ghc-internal      ``ghc-internal`` library
    
    31 31
       ghc-lib           ``ghc`` library
    
    32 32
       ghc-heap          ``ghc-heap`` library
    
    33 33
       ghc-experimental  ``ghc-experimental`` library
    

  • libraries/base/changelog.md
    1 1
     # Changelog for [`base` package](http://hackage.haskell.org/package/base)
    
    2 2
     
    
    3 3
     ## 4.24.0.0 *TBA*
    
    4
    +  * Give `setBit`, `clearBit` and `complementBit` explicit definitions in `instance Bits Integer`, reducing intermediate allocations. ([GHC #21176](https://gitlab.haskell.org/ghc/ghc/-/issues/21176))
    
    4 5
       * Add `Bounded` instances for `Double`, `Float`, `CDouble` and `CFloat`. ([CLC proposal #402](https://github.com/haskell/core-libraries-committee/issues/402))
    
    5 6
       * Ensure that `Data.List.elem` and `notElem` can be specialized even when no list fusion happens. ([CLC proposal #412)(https://github.com/haskell/core-libraries-committee/issues/412))
    
    6 7
     
    

  • libraries/ghc-internal/src/GHC/Internal/Bignum/Integer.hs
    ... ... @@ -133,6 +133,12 @@ module GHC.Internal.Bignum.Integer
    133 133
         , integerBit
    
    134 134
         , integerTestBit#
    
    135 135
         , integerTestBit
    
    136
    +    , integerSetBit#
    
    137
    +    , integerSetBit
    
    138
    +    , integerClearBit#
    
    139
    +    , integerClearBit
    
    140
    +    , integerComplementBit#
    
    141
    +    , integerComplementBit
    
    136 142
         , integerShiftR#
    
    137 143
         , integerShiftR
    
    138 144
         , integerShiftL#
    
    ... ... @@ -707,6 +713,113 @@ integerTestBit# (IN x) i
    707 713
     integerTestBit :: Integer -> Word -> Bool
    
    708 714
     integerTestBit !i (W# n) = isTrue# (integerTestBit# i n)
    
    709 715
     
    
    716
    +{- Note [INLINE for constant folding of bit operations]
    
    717
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    718
    +While there are no dedicated constant-folding rules for
    
    719
    +integerSetBit#/integerClearBit#/integerComplementBit#, we do INLINE them (and
    
    720
    +their Word-argument wrappers and the corresponding Bits Integer methods) to make
    
    721
    +the underlying primops accessible for constant folding, e.g. so that
    
    722
    +`clearBit (bit 0) 0 :: Integer` folds to `IS 0#`. Test T8832 checks the folding
    
    723
    +for all three operations.
    
    724
    +-}
    
    725
    +
    
    726
    +-- | Set the /n/-th bit.
    
    727
    +--
    
    728
    +-- Fake 2's complement for negative values (might be slow)
    
    729
    +--
    
    730
    +-- @since 10.201.0
    
    731
    +integerSetBit# :: Integer -> Word# -> Integer
    
    732
    +{-# INLINE integerSetBit# #-} -- See Note [INLINE for constant folding of bit operations]
    
    733
    +integerSetBit# n@(IS x) i
    
    734
    +   | isTrue# (i `ltWord#` (WORD_SIZE_IN_BITS## `minusWord#` 1##))
    
    735
    +   = IS (x `orI#` uncheckedIShiftL# 1# (word2Int# i))
    
    736
    +   | isTrue# (x >=# 0#)
    
    737
    +   = IP (bigNatSetBit# (bigNatFromWord# (int2Word# x)) i)
    
    738
    +   | True
    
    739
    +   = n
    
    740
    +integerSetBit# (IP x) i = IP (bigNatSetBit# x i)
    
    741
    +integerSetBit# (IN x) i = integerFromBigNatNeg#
    
    742
    +                             (bigNatAddWord#
    
    743
    +                                (bigNatClearBit# (bigNatSubWordUnsafe# x 1##) i)
    
    744
    +                                1##)
    
    745
    +
    
    746
    +-- | Set the /n/-th bit.
    
    747
    +--
    
    748
    +-- Fake 2's complement for negative values (might be slow)
    
    749
    +--
    
    750
    +-- @since 10.201.0
    
    751
    +integerSetBit :: Integer -> Word -> Integer
    
    752
    +{-# INLINE integerSetBit #-} -- See Note [INLINE for constant folding of bit operations]
    
    753
    +integerSetBit !i (W# n) = integerSetBit# i n
    
    754
    +
    
    755
    +-- | Clear the /n/-th bit.
    
    756
    +--
    
    757
    +-- Fake 2's complement for negative values (might be slow)
    
    758
    +--
    
    759
    +-- @since 10.201.0
    
    760
    +integerClearBit# :: Integer -> Word# -> Integer
    
    761
    +{-# INLINE integerClearBit# #-} -- See Note [INLINE for constant folding of bit operations]
    
    762
    +integerClearBit# n@(IS x) i
    
    763
    +   | isTrue# (i `ltWord#` (WORD_SIZE_IN_BITS## `minusWord#` 1##))
    
    764
    +   = IS (x `andI#` notI# (uncheckedIShiftL# 1# (word2Int# i)))
    
    765
    +   | isTrue# (x >=# 0#)
    
    766
    +   = n
    
    767
    +   | True
    
    768
    +   = IN (bigNatAddWord#
    
    769
    +           (bigNatSetBit#
    
    770
    +             (bigNatFromWord#
    
    771
    +                (minusWord# (int2Word# (negateInt# x)) 1##))
    
    772
    +             i)
    
    773
    +           1##)
    
    774
    +integerClearBit# (IP x) i = integerFromBigNat# (bigNatClearBit# x i)
    
    775
    +integerClearBit# (IN x) i = IN (bigNatAddWord#
    
    776
    +                                  (bigNatSetBit# (bigNatSubWordUnsafe# x 1##) i)
    
    777
    +                                  1##)
    
    778
    +
    
    779
    +-- | Clear the /n/-th bit.
    
    780
    +--
    
    781
    +-- Fake 2's complement for negative values (might be slow)
    
    782
    +--
    
    783
    +-- @since 10.201.0
    
    784
    +integerClearBit :: Integer -> Word -> Integer
    
    785
    +{-# INLINE integerClearBit #-} -- See Note [INLINE for constant folding of bit operations]
    
    786
    +integerClearBit !i (W# n) = integerClearBit# i n
    
    787
    +
    
    788
    +-- | Reverse the /n/-th bit.
    
    789
    +--
    
    790
    +-- Fake 2's complement for negative values (might be slow)
    
    791
    +--
    
    792
    +-- @since 10.201.0
    
    793
    +integerComplementBit# :: Integer -> Word# -> Integer
    
    794
    +{-# INLINE integerComplementBit# #-} -- See Note [INLINE for constant folding of bit operations]
    
    795
    +integerComplementBit# (IS x) i
    
    796
    +   | isTrue# (i `ltWord#` (WORD_SIZE_IN_BITS## `minusWord#` 1##))
    
    797
    +   = IS (x `xorI#` uncheckedIShiftL# 1# (word2Int# i))
    
    798
    +   | isTrue# (x >=# 0#)
    
    799
    +   = IP (bigNatSetBit# (bigNatFromWord# (int2Word# x)) i)
    
    800
    +   | True
    
    801
    +   = IN (bigNatAddWord#
    
    802
    +           (bigNatSetBit#
    
    803
    +              (bigNatFromWord# (minusWord# (int2Word# (negateInt# x)) 1##))
    
    804
    +              i)
    
    805
    +           1##)
    
    806
    +integerComplementBit# (IP x) i = integerFromBigNat# (bigNatComplementBit# x i)
    
    807
    +integerComplementBit# (IN x) i = integerFromBigNatNeg#
    
    808
    +                                    (bigNatAddWord#
    
    809
    +                                       (bigNatComplementBit#
    
    810
    +                                          (bigNatSubWordUnsafe# x 1##)
    
    811
    +                                          i)
    
    812
    +                                       1##)
    
    813
    +
    
    814
    +-- | Reverse the /n/-th bit.
    
    815
    +--
    
    816
    +-- Fake 2's complement for negative values (might be slow)
    
    817
    +--
    
    818
    +-- @since 10.201.0
    
    819
    +integerComplementBit :: Integer -> Word -> Integer
    
    820
    +{-# INLINE integerComplementBit #-} -- See Note [INLINE for constant folding of bit operations]
    
    821
    +integerComplementBit !i (W# n) = integerComplementBit# i n
    
    822
    +
    
    710 823
     -- | Shift-right operation
    
    711 824
     --
    
    712 825
     -- Fake 2's complement for negative values (might be slow)
    

  • libraries/ghc-internal/src/GHC/Internal/Bits.hs
    ... ... @@ -564,6 +564,15 @@ instance Bits Integer where
    564 564
                  | otherwise = integerShiftR x (fromIntegral (negate i))
    
    565 565
        testBit x i = integerTestBit x (fromIntegral i)
    
    566 566
        zeroBits    = integerZero
    
    567
    +   -- INLINE on setBit/clearBit/complementBit preserves constant folding;
    
    568
    +   -- see Note [INLINE for constant folding of bit operations] in
    
    569
    +   -- GHC.Internal.Bignum.Integer.
    
    570
    +   setBit x i = integerSetBit x (fromIntegral i)
    
    571
    +   {-# INLINE setBit #-}
    
    572
    +   clearBit x i = integerClearBit x (fromIntegral i)
    
    573
    +   {-# INLINE clearBit #-}
    
    574
    +   complementBit x i = integerComplementBit x (fromIntegral i)
    
    575
    +   {-# INLINE complementBit #-}
    
    567 576
     
    
    568 577
        bit (I# i)  = integerBit# (int2Word# i)
    
    569 578
        popCount x  = I# (integerPopCount# x)
    

  • testsuite/tests/interface-stability/ghc-bignum-exports.stdout
    ... ... @@ -201,8 +201,12 @@ module GHC.Num.Integer where
    201 201
       integerBit# :: GHC.Internal.Prim.Word# -> Integer
    
    202 202
       integerCheck :: Integer -> GHC.Internal.Types.Bool
    
    203 203
       integerCheck# :: Integer -> GHC.Internal.Bignum.Primitives.Bool#
    
    204
    +  integerClearBit :: Integer -> GHC.Internal.Types.Word -> Integer
    
    205
    +  integerClearBit# :: Integer -> GHC.Internal.Prim.Word# -> Integer
    
    204 206
       integerCompare :: Integer -> Integer -> GHC.Internal.Types.Ordering
    
    205 207
       integerComplement :: Integer -> Integer
    
    208
    +  integerComplementBit :: Integer -> GHC.Internal.Types.Word -> Integer
    
    209
    +  integerComplementBit# :: Integer -> GHC.Internal.Prim.Word# -> Integer
    
    206 210
       integerDecodeDouble# :: GHC.Internal.Prim.Double# -> (# Integer, GHC.Internal.Prim.Int# #)
    
    207 211
       integerDiv :: Integer -> Integer -> Integer
    
    208 212
       integerDivMod :: Integer -> Integer -> (Integer, Integer)
    
    ... ... @@ -266,6 +270,8 @@ module GHC.Num.Integer where
    266 270
       integerQuotRem# :: Integer -> Integer -> (# Integer, Integer #)
    
    267 271
       integerRecipMod# :: Integer -> GHC.Internal.Bignum.Natural.Natural -> (# GHC.Internal.Bignum.Natural.Natural | () #)
    
    268 272
       integerRem :: Integer -> Integer -> Integer
    
    273
    +  integerSetBit :: Integer -> GHC.Internal.Types.Word -> Integer
    
    274
    +  integerSetBit# :: Integer -> GHC.Internal.Prim.Word# -> Integer
    
    269 275
       integerShiftL :: Integer -> GHC.Internal.Types.Word -> Integer
    
    270 276
       integerShiftL# :: Integer -> GHC.Internal.Prim.Word# -> Integer
    
    271 277
       integerShiftR :: Integer -> GHC.Internal.Types.Word -> Integer
    

  • testsuite/tests/numeric/should_run/T21176.hs
    1
    +module Main where
    
    2
    +
    
    3
    +import Data.Bits
    
    4
    +import Data.Int (Int32, Int64)
    
    5
    +import Data.Foldable (for_)
    
    6
    +import GHC.Num.Integer (integerCheck)
    
    7
    +
    
    8
    +integers :: [Integer]
    
    9
    +integers = concatMap neighbours [minInt64, minInt32, 0, maxInt32, maxInt64]
    
    10
    +  where
    
    11
    +    neighbours i = [i - 2, i - 1, i, i + 1, i + 2]
    
    12
    +    minInt64 = toInteger (minBound :: Int64)
    
    13
    +    minInt32 = toInteger (minBound :: Int32)
    
    14
    +    maxInt32 = toInteger (maxBound :: Int32)
    
    15
    +    maxInt64 = toInteger (maxBound :: Int64)
    
    16
    +
    
    17
    +bits :: [Int]
    
    18
    +bits = [0, 1, x - 1, x, x + 1]
    
    19
    +  where x = finiteBitSize (0 :: Int) - 1
    
    20
    +
    
    21
    +testXBit :: String -> (Integer -> Int -> Integer) -> (Integer -> Int -> Integer) -> IO ()
    
    22
    +testXBit name f model = do
    
    23
    +  putStrLn name
    
    24
    +  for_ integers $ \i ->
    
    25
    +    for_ bits $ \b -> do
    
    26
    +      let actual   = f i b
    
    27
    +          expected = model i b
    
    28
    +          valid    = if integerCheck actual then "valid"   else "invalid"
    
    29
    +          matches  = if actual == expected  then "matches" else "differs"
    
    30
    +      putStrLn $ "  " ++ show i ++ " " ++ show b ++ " -> " ++ show actual
    
    31
    +              ++ "  [" ++ valid ++ ", " ++ matches ++ "]"
    
    32
    +  putStrLn ""
    
    33
    +
    
    34
    +main :: IO ()
    
    35
    +main = do
    
    36
    +  testXBit "setBit"        setBit        (\i b -> i .|. bit b)
    
    37
    +  testXBit "clearBit"      clearBit      (\i b -> i .&. complement (bit b))
    
    38
    +  testXBit "complementBit" complementBit (\i b -> i `xor` bit b)

  • testsuite/tests/numeric/should_run/T21176.stdout
    1
    +setBit
    
    2
    +  -9223372036854775810 0 -> -9223372036854775809  [valid, matches]
    
    3
    +  -9223372036854775810 1 -> -9223372036854775810  [valid, matches]
    
    4
    +  -9223372036854775810 62 -> -9223372036854775810  [valid, matches]
    
    5
    +  -9223372036854775810 63 -> -2  [valid, matches]
    
    6
    +  -9223372036854775810 64 -> -9223372036854775810  [valid, matches]
    
    7
    +  -9223372036854775809 0 -> -9223372036854775809  [valid, matches]
    
    8
    +  -9223372036854775809 1 -> -9223372036854775809  [valid, matches]
    
    9
    +  -9223372036854775809 62 -> -9223372036854775809  [valid, matches]
    
    10
    +  -9223372036854775809 63 -> -1  [valid, matches]
    
    11
    +  -9223372036854775809 64 -> -9223372036854775809  [valid, matches]
    
    12
    +  -9223372036854775808 0 -> -9223372036854775807  [valid, matches]
    
    13
    +  -9223372036854775808 1 -> -9223372036854775806  [valid, matches]
    
    14
    +  -9223372036854775808 62 -> -4611686018427387904  [valid, matches]
    
    15
    +  -9223372036854775808 63 -> -9223372036854775808  [valid, matches]
    
    16
    +  -9223372036854775808 64 -> -9223372036854775808  [valid, matches]
    
    17
    +  -9223372036854775807 0 -> -9223372036854775807  [valid, matches]
    
    18
    +  -9223372036854775807 1 -> -9223372036854775805  [valid, matches]
    
    19
    +  -9223372036854775807 62 -> -4611686018427387903  [valid, matches]
    
    20
    +  -9223372036854775807 63 -> -9223372036854775807  [valid, matches]
    
    21
    +  -9223372036854775807 64 -> -9223372036854775807  [valid, matches]
    
    22
    +  -9223372036854775806 0 -> -9223372036854775805  [valid, matches]
    
    23
    +  -9223372036854775806 1 -> -9223372036854775806  [valid, matches]
    
    24
    +  -9223372036854775806 62 -> -4611686018427387902  [valid, matches]
    
    25
    +  -9223372036854775806 63 -> -9223372036854775806  [valid, matches]
    
    26
    +  -9223372036854775806 64 -> -9223372036854775806  [valid, matches]
    
    27
    +  -2147483650 0 -> -2147483649  [valid, matches]
    
    28
    +  -2147483650 1 -> -2147483650  [valid, matches]
    
    29
    +  -2147483650 62 -> -2147483650  [valid, matches]
    
    30
    +  -2147483650 63 -> -2147483650  [valid, matches]
    
    31
    +  -2147483650 64 -> -2147483650  [valid, matches]
    
    32
    +  -2147483649 0 -> -2147483649  [valid, matches]
    
    33
    +  -2147483649 1 -> -2147483649  [valid, matches]
    
    34
    +  -2147483649 62 -> -2147483649  [valid, matches]
    
    35
    +  -2147483649 63 -> -2147483649  [valid, matches]
    
    36
    +  -2147483649 64 -> -2147483649  [valid, matches]
    
    37
    +  -2147483648 0 -> -2147483647  [valid, matches]
    
    38
    +  -2147483648 1 -> -2147483646  [valid, matches]
    
    39
    +  -2147483648 62 -> -2147483648  [valid, matches]
    
    40
    +  -2147483648 63 -> -2147483648  [valid, matches]
    
    41
    +  -2147483648 64 -> -2147483648  [valid, matches]
    
    42
    +  -2147483647 0 -> -2147483647  [valid, matches]
    
    43
    +  -2147483647 1 -> -2147483645  [valid, matches]
    
    44
    +  -2147483647 62 -> -2147483647  [valid, matches]
    
    45
    +  -2147483647 63 -> -2147483647  [valid, matches]
    
    46
    +  -2147483647 64 -> -2147483647  [valid, matches]
    
    47
    +  -2147483646 0 -> -2147483645  [valid, matches]
    
    48
    +  -2147483646 1 -> -2147483646  [valid, matches]
    
    49
    +  -2147483646 62 -> -2147483646  [valid, matches]
    
    50
    +  -2147483646 63 -> -2147483646  [valid, matches]
    
    51
    +  -2147483646 64 -> -2147483646  [valid, matches]
    
    52
    +  -2 0 -> -1  [valid, matches]
    
    53
    +  -2 1 -> -2  [valid, matches]
    
    54
    +  -2 62 -> -2  [valid, matches]
    
    55
    +  -2 63 -> -2  [valid, matches]
    
    56
    +  -2 64 -> -2  [valid, matches]
    
    57
    +  -1 0 -> -1  [valid, matches]
    
    58
    +  -1 1 -> -1  [valid, matches]
    
    59
    +  -1 62 -> -1  [valid, matches]
    
    60
    +  -1 63 -> -1  [valid, matches]
    
    61
    +  -1 64 -> -1  [valid, matches]
    
    62
    +  0 0 -> 1  [valid, matches]
    
    63
    +  0 1 -> 2  [valid, matches]
    
    64
    +  0 62 -> 4611686018427387904  [valid, matches]
    
    65
    +  0 63 -> 9223372036854775808  [valid, matches]
    
    66
    +  0 64 -> 18446744073709551616  [valid, matches]
    
    67
    +  1 0 -> 1  [valid, matches]
    
    68
    +  1 1 -> 3  [valid, matches]
    
    69
    +  1 62 -> 4611686018427387905  [valid, matches]
    
    70
    +  1 63 -> 9223372036854775809  [valid, matches]
    
    71
    +  1 64 -> 18446744073709551617  [valid, matches]
    
    72
    +  2 0 -> 3  [valid, matches]
    
    73
    +  2 1 -> 2  [valid, matches]
    
    74
    +  2 62 -> 4611686018427387906  [valid, matches]
    
    75
    +  2 63 -> 9223372036854775810  [valid, matches]
    
    76
    +  2 64 -> 18446744073709551618  [valid, matches]
    
    77
    +  2147483645 0 -> 2147483645  [valid, matches]
    
    78
    +  2147483645 1 -> 2147483647  [valid, matches]
    
    79
    +  2147483645 62 -> 4611686020574871549  [valid, matches]
    
    80
    +  2147483645 63 -> 9223372039002259453  [valid, matches]
    
    81
    +  2147483645 64 -> 18446744075857035261  [valid, matches]
    
    82
    +  2147483646 0 -> 2147483647  [valid, matches]
    
    83
    +  2147483646 1 -> 2147483646  [valid, matches]
    
    84
    +  2147483646 62 -> 4611686020574871550  [valid, matches]
    
    85
    +  2147483646 63 -> 9223372039002259454  [valid, matches]
    
    86
    +  2147483646 64 -> 18446744075857035262  [valid, matches]
    
    87
    +  2147483647 0 -> 2147483647  [valid, matches]
    
    88
    +  2147483647 1 -> 2147483647  [valid, matches]
    
    89
    +  2147483647 62 -> 4611686020574871551  [valid, matches]
    
    90
    +  2147483647 63 -> 9223372039002259455  [valid, matches]
    
    91
    +  2147483647 64 -> 18446744075857035263  [valid, matches]
    
    92
    +  2147483648 0 -> 2147483649  [valid, matches]
    
    93
    +  2147483648 1 -> 2147483650  [valid, matches]
    
    94
    +  2147483648 62 -> 4611686020574871552  [valid, matches]
    
    95
    +  2147483648 63 -> 9223372039002259456  [valid, matches]
    
    96
    +  2147483648 64 -> 18446744075857035264  [valid, matches]
    
    97
    +  2147483649 0 -> 2147483649  [valid, matches]
    
    98
    +  2147483649 1 -> 2147483651  [valid, matches]
    
    99
    +  2147483649 62 -> 4611686020574871553  [valid, matches]
    
    100
    +  2147483649 63 -> 9223372039002259457  [valid, matches]
    
    101
    +  2147483649 64 -> 18446744075857035265  [valid, matches]
    
    102
    +  9223372036854775805 0 -> 9223372036854775805  [valid, matches]
    
    103
    +  9223372036854775805 1 -> 9223372036854775807  [valid, matches]
    
    104
    +  9223372036854775805 62 -> 9223372036854775805  [valid, matches]
    
    105
    +  9223372036854775805 63 -> 18446744073709551613  [valid, matches]
    
    106
    +  9223372036854775805 64 -> 27670116110564327421  [valid, matches]
    
    107
    +  9223372036854775806 0 -> 9223372036854775807  [valid, matches]
    
    108
    +  9223372036854775806 1 -> 9223372036854775806  [valid, matches]
    
    109
    +  9223372036854775806 62 -> 9223372036854775806  [valid, matches]
    
    110
    +  9223372036854775806 63 -> 18446744073709551614  [valid, matches]
    
    111
    +  9223372036854775806 64 -> 27670116110564327422  [valid, matches]
    
    112
    +  9223372036854775807 0 -> 9223372036854775807  [valid, matches]
    
    113
    +  9223372036854775807 1 -> 9223372036854775807  [valid, matches]
    
    114
    +  9223372036854775807 62 -> 9223372036854775807  [valid, matches]
    
    115
    +  9223372036854775807 63 -> 18446744073709551615  [valid, matches]
    
    116
    +  9223372036854775807 64 -> 27670116110564327423  [valid, matches]
    
    117
    +  9223372036854775808 0 -> 9223372036854775809  [valid, matches]
    
    118
    +  9223372036854775808 1 -> 9223372036854775810  [valid, matches]
    
    119
    +  9223372036854775808 62 -> 13835058055282163712  [valid, matches]
    
    120
    +  9223372036854775808 63 -> 9223372036854775808  [valid, matches]
    
    121
    +  9223372036854775808 64 -> 27670116110564327424  [valid, matches]
    
    122
    +  9223372036854775809 0 -> 9223372036854775809  [valid, matches]
    
    123
    +  9223372036854775809 1 -> 9223372036854775811  [valid, matches]
    
    124
    +  9223372036854775809 62 -> 13835058055282163713  [valid, matches]
    
    125
    +  9223372036854775809 63 -> 9223372036854775809  [valid, matches]
    
    126
    +  9223372036854775809 64 -> 27670116110564327425  [valid, matches]
    
    127
    +
    
    128
    +clearBit
    
    129
    +  -9223372036854775810 0 -> -9223372036854775810  [valid, matches]
    
    130
    +  -9223372036854775810 1 -> -9223372036854775812  [valid, matches]
    
    131
    +  -9223372036854775810 62 -> -13835058055282163714  [valid, matches]
    
    132
    +  -9223372036854775810 63 -> -9223372036854775810  [valid, matches]
    
    133
    +  -9223372036854775810 64 -> -27670116110564327426  [valid, matches]
    
    134
    +  -9223372036854775809 0 -> -9223372036854775810  [valid, matches]
    
    135
    +  -9223372036854775809 1 -> -9223372036854775811  [valid, matches]
    
    136
    +  -9223372036854775809 62 -> -13835058055282163713  [valid, matches]
    
    137
    +  -9223372036854775809 63 -> -9223372036854775809  [valid, matches]
    
    138
    +  -9223372036854775809 64 -> -27670116110564327425  [valid, matches]
    
    139
    +  -9223372036854775808 0 -> -9223372036854775808  [valid, matches]
    
    140
    +  -9223372036854775808 1 -> -9223372036854775808  [valid, matches]
    
    141
    +  -9223372036854775808 62 -> -9223372036854775808  [valid, matches]
    
    142
    +  -9223372036854775808 63 -> -18446744073709551616  [valid, matches]
    
    143
    +  -9223372036854775808 64 -> -27670116110564327424  [valid, matches]
    
    144
    +  -9223372036854775807 0 -> -9223372036854775808  [valid, matches]
    
    145
    +  -9223372036854775807 1 -> -9223372036854775807  [valid, matches]
    
    146
    +  -9223372036854775807 62 -> -9223372036854775807  [valid, matches]
    
    147
    +  -9223372036854775807 63 -> -18446744073709551615  [valid, matches]
    
    148
    +  -9223372036854775807 64 -> -27670116110564327423  [valid, matches]
    
    149
    +  -9223372036854775806 0 -> -9223372036854775806  [valid, matches]
    
    150
    +  -9223372036854775806 1 -> -9223372036854775808  [valid, matches]
    
    151
    +  -9223372036854775806 62 -> -9223372036854775806  [valid, matches]
    
    152
    +  -9223372036854775806 63 -> -18446744073709551614  [valid, matches]
    
    153
    +  -9223372036854775806 64 -> -27670116110564327422  [valid, matches]
    
    154
    +  -2147483650 0 -> -2147483650  [valid, matches]
    
    155
    +  -2147483650 1 -> -2147483652  [valid, matches]
    
    156
    +  -2147483650 62 -> -4611686020574871554  [valid, matches]
    
    157
    +  -2147483650 63 -> -9223372039002259458  [valid, matches]
    
    158
    +  -2147483650 64 -> -18446744075857035266  [valid, matches]
    
    159
    +  -2147483649 0 -> -2147483650  [valid, matches]
    
    160
    +  -2147483649 1 -> -2147483651  [valid, matches]
    
    161
    +  -2147483649 62 -> -4611686020574871553  [valid, matches]
    
    162
    +  -2147483649 63 -> -9223372039002259457  [valid, matches]
    
    163
    +  -2147483649 64 -> -18446744075857035265  [valid, matches]
    
    164
    +  -2147483648 0 -> -2147483648  [valid, matches]
    
    165
    +  -2147483648 1 -> -2147483648  [valid, matches]
    
    166
    +  -2147483648 62 -> -4611686020574871552  [valid, matches]
    
    167
    +  -2147483648 63 -> -9223372039002259456  [valid, matches]
    
    168
    +  -2147483648 64 -> -18446744075857035264  [valid, matches]
    
    169
    +  -2147483647 0 -> -2147483648  [valid, matches]
    
    170
    +  -2147483647 1 -> -2147483647  [valid, matches]
    
    171
    +  -2147483647 62 -> -4611686020574871551  [valid, matches]
    
    172
    +  -2147483647 63 -> -9223372039002259455  [valid, matches]
    
    173
    +  -2147483647 64 -> -18446744075857035263  [valid, matches]
    
    174
    +  -2147483646 0 -> -2147483646  [valid, matches]
    
    175
    +  -2147483646 1 -> -2147483648  [valid, matches]
    
    176
    +  -2147483646 62 -> -4611686020574871550  [valid, matches]
    
    177
    +  -2147483646 63 -> -9223372039002259454  [valid, matches]
    
    178
    +  -2147483646 64 -> -18446744075857035262  [valid, matches]
    
    179
    +  -2 0 -> -2  [valid, matches]
    
    180
    +  -2 1 -> -4  [valid, matches]
    
    181
    +  -2 62 -> -4611686018427387906  [valid, matches]
    
    182
    +  -2 63 -> -9223372036854775810  [valid, matches]
    
    183
    +  -2 64 -> -18446744073709551618  [valid, matches]
    
    184
    +  -1 0 -> -2  [valid, matches]
    
    185
    +  -1 1 -> -3  [valid, matches]
    
    186
    +  -1 62 -> -4611686018427387905  [valid, matches]
    
    187
    +  -1 63 -> -9223372036854775809  [valid, matches]
    
    188
    +  -1 64 -> -18446744073709551617  [valid, matches]
    
    189
    +  0 0 -> 0  [valid, matches]
    
    190
    +  0 1 -> 0  [valid, matches]
    
    191
    +  0 62 -> 0  [valid, matches]
    
    192
    +  0 63 -> 0  [valid, matches]
    
    193
    +  0 64 -> 0  [valid, matches]
    
    194
    +  1 0 -> 0  [valid, matches]
    
    195
    +  1 1 -> 1  [valid, matches]
    
    196
    +  1 62 -> 1  [valid, matches]
    
    197
    +  1 63 -> 1  [valid, matches]
    
    198
    +  1 64 -> 1  [valid, matches]
    
    199
    +  2 0 -> 2  [valid, matches]
    
    200
    +  2 1 -> 0  [valid, matches]
    
    201
    +  2 62 -> 2  [valid, matches]
    
    202
    +  2 63 -> 2  [valid, matches]
    
    203
    +  2 64 -> 2  [valid, matches]
    
    204
    +  2147483645 0 -> 2147483644  [valid, matches]
    
    205
    +  2147483645 1 -> 2147483645  [valid, matches]
    
    206
    +  2147483645 62 -> 2147483645  [valid, matches]
    
    207
    +  2147483645 63 -> 2147483645  [valid, matches]
    
    208
    +  2147483645 64 -> 2147483645  [valid, matches]
    
    209
    +  2147483646 0 -> 2147483646  [valid, matches]
    
    210
    +  2147483646 1 -> 2147483644  [valid, matches]
    
    211
    +  2147483646 62 -> 2147483646  [valid, matches]
    
    212
    +  2147483646 63 -> 2147483646  [valid, matches]
    
    213
    +  2147483646 64 -> 2147483646  [valid, matches]
    
    214
    +  2147483647 0 -> 2147483646  [valid, matches]
    
    215
    +  2147483647 1 -> 2147483645  [valid, matches]
    
    216
    +  2147483647 62 -> 2147483647  [valid, matches]
    
    217
    +  2147483647 63 -> 2147483647  [valid, matches]
    
    218
    +  2147483647 64 -> 2147483647  [valid, matches]
    
    219
    +  2147483648 0 -> 2147483648  [valid, matches]
    
    220
    +  2147483648 1 -> 2147483648  [valid, matches]
    
    221
    +  2147483648 62 -> 2147483648  [valid, matches]
    
    222
    +  2147483648 63 -> 2147483648  [valid, matches]
    
    223
    +  2147483648 64 -> 2147483648  [valid, matches]
    
    224
    +  2147483649 0 -> 2147483648  [valid, matches]
    
    225
    +  2147483649 1 -> 2147483649  [valid, matches]
    
    226
    +  2147483649 62 -> 2147483649  [valid, matches]
    
    227
    +  2147483649 63 -> 2147483649  [valid, matches]
    
    228
    +  2147483649 64 -> 2147483649  [valid, matches]
    
    229
    +  9223372036854775805 0 -> 9223372036854775804  [valid, matches]
    
    230
    +  9223372036854775805 1 -> 9223372036854775805  [valid, matches]
    
    231
    +  9223372036854775805 62 -> 4611686018427387901  [valid, matches]
    
    232
    +  9223372036854775805 63 -> 9223372036854775805  [valid, matches]
    
    233
    +  9223372036854775805 64 -> 9223372036854775805  [valid, matches]
    
    234
    +  9223372036854775806 0 -> 9223372036854775806  [valid, matches]
    
    235
    +  9223372036854775806 1 -> 9223372036854775804  [valid, matches]
    
    236
    +  9223372036854775806 62 -> 4611686018427387902  [valid, matches]
    
    237
    +  9223372036854775806 63 -> 9223372036854775806  [valid, matches]
    
    238
    +  9223372036854775806 64 -> 9223372036854775806  [valid, matches]
    
    239
    +  9223372036854775807 0 -> 9223372036854775806  [valid, matches]
    
    240
    +  9223372036854775807 1 -> 9223372036854775805  [valid, matches]
    
    241
    +  9223372036854775807 62 -> 4611686018427387903  [valid, matches]
    
    242
    +  9223372036854775807 63 -> 9223372036854775807  [valid, matches]
    
    243
    +  9223372036854775807 64 -> 9223372036854775807  [valid, matches]
    
    244
    +  9223372036854775808 0 -> 9223372036854775808  [valid, matches]
    
    245
    +  9223372036854775808 1 -> 9223372036854775808  [valid, matches]
    
    246
    +  9223372036854775808 62 -> 9223372036854775808  [valid, matches]
    
    247
    +  9223372036854775808 63 -> 0  [valid, matches]
    
    248
    +  9223372036854775808 64 -> 9223372036854775808  [valid, matches]
    
    249
    +  9223372036854775809 0 -> 9223372036854775808  [valid, matches]
    
    250
    +  9223372036854775809 1 -> 9223372036854775809  [valid, matches]
    
    251
    +  9223372036854775809 62 -> 9223372036854775809  [valid, matches]
    
    252
    +  9223372036854775809 63 -> 1  [valid, matches]
    
    253
    +  9223372036854775809 64 -> 9223372036854775809  [valid, matches]
    
    254
    +
    
    255
    +complementBit
    
    256
    +  -9223372036854775810 0 -> -9223372036854775809  [valid, matches]
    
    257
    +  -9223372036854775810 1 -> -9223372036854775812  [valid, matches]
    
    258
    +  -9223372036854775810 62 -> -13835058055282163714  [valid, matches]
    
    259
    +  -9223372036854775810 63 -> -2  [valid, matches]
    
    260
    +  -9223372036854775810 64 -> -27670116110564327426  [valid, matches]
    
    261
    +  -9223372036854775809 0 -> -9223372036854775810  [valid, matches]
    
    262
    +  -9223372036854775809 1 -> -9223372036854775811  [valid, matches]
    
    263
    +  -9223372036854775809 62 -> -13835058055282163713  [valid, matches]
    
    264
    +  -9223372036854775809 63 -> -1  [valid, matches]
    
    265
    +  -9223372036854775809 64 -> -27670116110564327425  [valid, matches]
    
    266
    +  -9223372036854775808 0 -> -9223372036854775807  [valid, matches]
    
    267
    +  -9223372036854775808 1 -> -9223372036854775806  [valid, matches]
    
    268
    +  -9223372036854775808 62 -> -4611686018427387904  [valid, matches]
    
    269
    +  -9223372036854775808 63 -> -18446744073709551616  [valid, matches]
    
    270
    +  -9223372036854775808 64 -> -27670116110564327424  [valid, matches]
    
    271
    +  -9223372036854775807 0 -> -9223372036854775808  [valid, matches]
    
    272
    +  -9223372036854775807 1 -> -9223372036854775805  [valid, matches]
    
    273
    +  -9223372036854775807 62 -> -4611686018427387903  [valid, matches]
    
    274
    +  -9223372036854775807 63 -> -18446744073709551615  [valid, matches]
    
    275
    +  -9223372036854775807 64 -> -27670116110564327423  [valid, matches]
    
    276
    +  -9223372036854775806 0 -> -9223372036854775805  [valid, matches]
    
    277
    +  -9223372036854775806 1 -> -9223372036854775808  [valid, matches]
    
    278
    +  -9223372036854775806 62 -> -4611686018427387902  [valid, matches]
    
    279
    +  -9223372036854775806 63 -> -18446744073709551614  [valid, matches]
    
    280
    +  -9223372036854775806 64 -> -27670116110564327422  [valid, matches]
    
    281
    +  -2147483650 0 -> -2147483649  [valid, matches]
    
    282
    +  -2147483650 1 -> -2147483652  [valid, matches]
    
    283
    +  -2147483650 62 -> -4611686020574871554  [valid, matches]
    
    284
    +  -2147483650 63 -> -9223372039002259458  [valid, matches]
    
    285
    +  -2147483650 64 -> -18446744075857035266  [valid, matches]
    
    286
    +  -2147483649 0 -> -2147483650  [valid, matches]
    
    287
    +  -2147483649 1 -> -2147483651  [valid, matches]
    
    288
    +  -2147483649 62 -> -4611686020574871553  [valid, matches]
    
    289
    +  -2147483649 63 -> -9223372039002259457  [valid, matches]
    
    290
    +  -2147483649 64 -> -18446744075857035265  [valid, matches]
    
    291
    +  -2147483648 0 -> -2147483647  [valid, matches]
    
    292
    +  -2147483648 1 -> -2147483646  [valid, matches]
    
    293
    +  -2147483648 62 -> -4611686020574871552  [valid, matches]
    
    294
    +  -2147483648 63 -> -9223372039002259456  [valid, matches]
    
    295
    +  -2147483648 64 -> -18446744075857035264  [valid, matches]
    
    296
    +  -2147483647 0 -> -2147483648  [valid, matches]
    
    297
    +  -2147483647 1 -> -2147483645  [valid, matches]
    
    298
    +  -2147483647 62 -> -4611686020574871551  [valid, matches]
    
    299
    +  -2147483647 63 -> -9223372039002259455  [valid, matches]
    
    300
    +  -2147483647 64 -> -18446744075857035263  [valid, matches]
    
    301
    +  -2147483646 0 -> -2147483645  [valid, matches]
    
    302
    +  -2147483646 1 -> -2147483648  [valid, matches]
    
    303
    +  -2147483646 62 -> -4611686020574871550  [valid, matches]
    
    304
    +  -2147483646 63 -> -9223372039002259454  [valid, matches]
    
    305
    +  -2147483646 64 -> -18446744075857035262  [valid, matches]
    
    306
    +  -2 0 -> -1  [valid, matches]
    
    307
    +  -2 1 -> -4  [valid, matches]
    
    308
    +  -2 62 -> -4611686018427387906  [valid, matches]
    
    309
    +  -2 63 -> -9223372036854775810  [valid, matches]
    
    310
    +  -2 64 -> -18446744073709551618  [valid, matches]
    
    311
    +  -1 0 -> -2  [valid, matches]
    
    312
    +  -1 1 -> -3  [valid, matches]
    
    313
    +  -1 62 -> -4611686018427387905  [valid, matches]
    
    314
    +  -1 63 -> -9223372036854775809  [valid, matches]
    
    315
    +  -1 64 -> -18446744073709551617  [valid, matches]
    
    316
    +  0 0 -> 1  [valid, matches]
    
    317
    +  0 1 -> 2  [valid, matches]
    
    318
    +  0 62 -> 4611686018427387904  [valid, matches]
    
    319
    +  0 63 -> 9223372036854775808  [valid, matches]
    
    320
    +  0 64 -> 18446744073709551616  [valid, matches]
    
    321
    +  1 0 -> 0  [valid, matches]
    
    322
    +  1 1 -> 3  [valid, matches]
    
    323
    +  1 62 -> 4611686018427387905  [valid, matches]
    
    324
    +  1 63 -> 9223372036854775809  [valid, matches]
    
    325
    +  1 64 -> 18446744073709551617  [valid, matches]
    
    326
    +  2 0 -> 3  [valid, matches]
    
    327
    +  2 1 -> 0  [valid, matches]
    
    328
    +  2 62 -> 4611686018427387906  [valid, matches]
    
    329
    +  2 63 -> 9223372036854775810  [valid, matches]
    
    330
    +  2 64 -> 18446744073709551618  [valid, matches]
    
    331
    +  2147483645 0 -> 2147483644  [valid, matches]
    
    332
    +  2147483645 1 -> 2147483647  [valid, matches]
    
    333
    +  2147483645 62 -> 4611686020574871549  [valid, matches]
    
    334
    +  2147483645 63 -> 9223372039002259453  [valid, matches]
    
    335
    +  2147483645 64 -> 18446744075857035261  [valid, matches]
    
    336
    +  2147483646 0 -> 2147483647  [valid, matches]
    
    337
    +  2147483646 1 -> 2147483644  [valid, matches]
    
    338
    +  2147483646 62 -> 4611686020574871550  [valid, matches]
    
    339
    +  2147483646 63 -> 9223372039002259454  [valid, matches]
    
    340
    +  2147483646 64 -> 18446744075857035262  [valid, matches]
    
    341
    +  2147483647 0 -> 2147483646  [valid, matches]
    
    342
    +  2147483647 1 -> 2147483645  [valid, matches]
    
    343
    +  2147483647 62 -> 4611686020574871551  [valid, matches]
    
    344
    +  2147483647 63 -> 9223372039002259455  [valid, matches]
    
    345
    +  2147483647 64 -> 18446744075857035263  [valid, matches]
    
    346
    +  2147483648 0 -> 2147483649  [valid, matches]
    
    347
    +  2147483648 1 -> 2147483650  [valid, matches]
    
    348
    +  2147483648 62 -> 4611686020574871552  [valid, matches]
    
    349
    +  2147483648 63 -> 9223372039002259456  [valid, matches]
    
    350
    +  2147483648 64 -> 18446744075857035264  [valid, matches]
    
    351
    +  2147483649 0 -> 2147483648  [valid, matches]
    
    352
    +  2147483649 1 -> 2147483651  [valid, matches]
    
    353
    +  2147483649 62 -> 4611686020574871553  [valid, matches]
    
    354
    +  2147483649 63 -> 9223372039002259457  [valid, matches]
    
    355
    +  2147483649 64 -> 18446744075857035265  [valid, matches]
    
    356
    +  9223372036854775805 0 -> 9223372036854775804  [valid, matches]
    
    357
    +  9223372036854775805 1 -> 9223372036854775807  [valid, matches]
    
    358
    +  9223372036854775805 62 -> 4611686018427387901  [valid, matches]
    
    359
    +  9223372036854775805 63 -> 18446744073709551613  [valid, matches]
    
    360
    +  9223372036854775805 64 -> 27670116110564327421  [valid, matches]
    
    361
    +  9223372036854775806 0 -> 9223372036854775807  [valid, matches]
    
    362
    +  9223372036854775806 1 -> 9223372036854775804  [valid, matches]
    
    363
    +  9223372036854775806 62 -> 4611686018427387902  [valid, matches]
    
    364
    +  9223372036854775806 63 -> 18446744073709551614  [valid, matches]
    
    365
    +  9223372036854775806 64 -> 27670116110564327422  [valid, matches]
    
    366
    +  9223372036854775807 0 -> 9223372036854775806  [valid, matches]
    
    367
    +  9223372036854775807 1 -> 9223372036854775805  [valid, matches]
    
    368
    +  9223372036854775807 62 -> 4611686018427387903  [valid, matches]
    
    369
    +  9223372036854775807 63 -> 18446744073709551615  [valid, matches]
    
    370
    +  9223372036854775807 64 -> 27670116110564327423  [valid, matches]
    
    371
    +  9223372036854775808 0 -> 9223372036854775809  [valid, matches]
    
    372
    +  9223372036854775808 1 -> 9223372036854775810  [valid, matches]
    
    373
    +  9223372036854775808 62 -> 13835058055282163712  [valid, matches]
    
    374
    +  9223372036854775808 63 -> 0  [valid, matches]
    
    375
    +  9223372036854775808 64 -> 27670116110564327424  [valid, matches]
    
    376
    +  9223372036854775809 0 -> 9223372036854775808  [valid, matches]
    
    377
    +  9223372036854775809 1 -> 9223372036854775811  [valid, matches]
    
    378
    +  9223372036854775809 62 -> 13835058055282163713  [valid, matches]
    
    379
    +  9223372036854775809 63 -> 1  [valid, matches]
    
    380
    +  9223372036854775809 64 -> 27670116110564327425  [valid, matches]
    
    381
    +

  • testsuite/tests/numeric/should_run/all.T
    ... ... @@ -101,3 +101,4 @@ test('T24245', normal, compile_and_run, [''])
    101 101
     test('T25653', normal, compile_and_run, [''])
    
    102 102
     test('T18619', exit_code(1), compile_and_run, [''])
    
    103 103
     test('T26230', normal, compile_and_run, [''])
    
    104
    +test('T21176', normal, compile_and_run, [''])

  • testsuite/tests/simplCore/should_compile/T8832.hs
    ... ... @@ -23,3 +23,9 @@ T(w32,Word32)
    23 23
     T(w64,Word64)
    
    24 24
     
    
    25 25
     T(z,Integer)
    
    26
    +
    
    27
    +zset :: Integer
    
    28
    +zset = setBit (bit 0) 0
    
    29
    +
    
    30
    +zcompl :: Integer
    
    31
    +zcompl = complementBit (bit 0) 0

  • testsuite/tests/simplCore/should_compile/T8832.stdout
    ... ... @@ -8,4 +8,6 @@ w8 = GHC.Internal.Word.W8# 0#Word8
    8 8
     w16 = GHC.Internal.Word.W16# 0#Word16
    
    9 9
     w32 = GHC.Internal.Word.W32# 0#Word32
    
    10 10
     w64 = GHC.Internal.Word.W64# 0#Word64
    
    11
    -z = GHC.Internal.Bignum.Integer.IS 0#
    11
    +zcompl = GHC.Internal.Bignum.Integer.IS 0#
    
    12
    +zset = GHC.Internal.Bignum.Integer.IS 1#
    
    13
    +z = zcompl