recursion-ninja pushed to branch wip/fix-26109 at Glasgow Haskell Compiler / GHC

Commits:

29 changed files:

Changes:

  • .gitlab/generate-ci/gen_ci.hs
    ... ... @@ -478,7 +478,7 @@ opsysVariables _ (Windows {}) = mconcat
    478 478
       , "LANG" =: "en_US.UTF-8"
    
    479 479
       , "CABAL_INSTALL_VERSION" =: "3.10.2.0"
    
    480 480
       , "HADRIAN_ARGS" =: "--docs=no-sphinx-pdfs"
    
    481
    -  , "GHC_VERSION" =: "9.6.4"
    
    481
    +  , "GHC_VERSION" =: "9.10.1"
    
    482 482
       ]
    
    483 483
     opsysVariables _ _ = mempty
    
    484 484
     
    

  • .gitlab/jobs.yaml
    ... ... @@ -3698,7 +3698,7 @@
    3698 3698
           "BUILD_FLAVOUR": "validate",
    
    3699 3699
           "CABAL_INSTALL_VERSION": "3.10.2.0",
    
    3700 3700
           "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    3701
    -      "GHC_VERSION": "9.6.4",
    
    3701
    +      "GHC_VERSION": "9.10.1",
    
    3702 3702
           "HADRIAN_ARGS": "--docs=no-sphinx-pdfs",
    
    3703 3703
           "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    3704 3704
           "LANG": "en_US.UTF-8",
    
    ... ... @@ -3761,7 +3761,7 @@
    3761 3761
           "BUILD_FLAVOUR": "validate",
    
    3762 3762
           "CABAL_INSTALL_VERSION": "3.10.2.0",
    
    3763 3763
           "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    3764
    -      "GHC_VERSION": "9.6.4",
    
    3764
    +      "GHC_VERSION": "9.10.1",
    
    3765 3765
           "HADRIAN_ARGS": "--docs=no-sphinx-pdfs",
    
    3766 3766
           "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    3767 3767
           "LANG": "en_US.UTF-8",
    
    ... ... @@ -5579,7 +5579,7 @@
    5579 5579
           "BUILD_FLAVOUR": "release",
    
    5580 5580
           "CABAL_INSTALL_VERSION": "3.10.2.0",
    
    5581 5581
           "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    5582
    -      "GHC_VERSION": "9.6.4",
    
    5582
    +      "GHC_VERSION": "9.10.1",
    
    5583 5583
           "HADRIAN_ARGS": "--docs=no-sphinx-pdfs",
    
    5584 5584
           "IGNORE_PERF_FAILURES": "all",
    
    5585 5585
           "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    ... ... @@ -5643,7 +5643,7 @@
    5643 5643
           "BUILD_FLAVOUR": "release",
    
    5644 5644
           "CABAL_INSTALL_VERSION": "3.10.2.0",
    
    5645 5645
           "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    5646
    -      "GHC_VERSION": "9.6.4",
    
    5646
    +      "GHC_VERSION": "9.10.1",
    
    5647 5647
           "HADRIAN_ARGS": "--docs=no-sphinx-pdfs",
    
    5648 5648
           "IGNORE_PERF_FAILURES": "all",
    
    5649 5649
           "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    ... ... @@ -7982,7 +7982,7 @@
    7982 7982
           "BUILD_FLAVOUR": "validate",
    
    7983 7983
           "CABAL_INSTALL_VERSION": "3.10.2.0",
    
    7984 7984
           "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    7985
    -      "GHC_VERSION": "9.6.4",
    
    7985
    +      "GHC_VERSION": "9.10.1",
    
    7986 7986
           "HADRIAN_ARGS": "--docs=no-sphinx-pdfs",
    
    7987 7987
           "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    7988 7988
           "LANG": "en_US.UTF-8",
    
    ... ... @@ -8044,7 +8044,7 @@
    8044 8044
           "BUILD_FLAVOUR": "validate",
    
    8045 8045
           "CABAL_INSTALL_VERSION": "3.10.2.0",
    
    8046 8046
           "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    8047
    -      "GHC_VERSION": "9.6.4",
    
    8047
    +      "GHC_VERSION": "9.10.1",
    
    8048 8048
           "HADRIAN_ARGS": "--docs=no-sphinx-pdfs",
    
    8049 8049
           "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check",
    
    8050 8050
           "LANG": "en_US.UTF-8",
    

  • compiler/GHC/Builtin/primops.txt.pp
    ... ... @@ -148,6 +148,7 @@ defaults
    148 148
        vector           = []
    
    149 149
        deprecated_msg   = {}      -- A non-empty message indicates deprecation
    
    150 150
        div_like         = False   -- Second argument expected to be non zero - used for tests
    
    151
    +   defined_bits     = Nothing -- The number of bits the operation is defined for (if not all bits)
    
    151 152
     
    
    152 153
     -- Note [When do out-of-line primops go in primops.txt.pp]
    
    153 154
     -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    ... ... @@ -1065,8 +1066,10 @@ primop CtzOp "ctz#" GenPrimOp Word# -> Word#
    1065 1066
     
    
    1066 1067
     primop   BSwap16Op   "byteSwap16#"   GenPrimOp   Word# -> Word#
    
    1067 1068
         {Swap bytes in the lower 16 bits of a word. The higher bytes are undefined. }
    
    1069
    +    with defined_bits = 16
    
    1068 1070
     primop   BSwap32Op   "byteSwap32#"   GenPrimOp   Word# -> Word#
    
    1069 1071
         {Swap bytes in the lower 32 bits of a word. The higher bytes are undefined. }
    
    1072
    +    with defined_bits = 32
    
    1070 1073
     primop   BSwap64Op   "byteSwap64#"   GenPrimOp   Word64# -> Word64#
    
    1071 1074
         {Swap bytes in a 64 bits of a word.}
    
    1072 1075
     primop   BSwapOp     "byteSwap#"     GenPrimOp   Word# -> Word#
    
    ... ... @@ -1074,10 +1077,13 @@ primop BSwapOp "byteSwap#" GenPrimOp Word# -> Word#
    1074 1077
     
    
    1075 1078
     primop   BRev8Op    "bitReverse8#"   GenPrimOp   Word# -> Word#
    
    1076 1079
         {Reverse the order of the bits in a 8-bit word.}
    
    1080
    +    with defined_bits = 8
    
    1077 1081
     primop   BRev16Op   "bitReverse16#"   GenPrimOp   Word# -> Word#
    
    1078 1082
         {Reverse the order of the bits in a 16-bit word.}
    
    1083
    +    with defined_bits = 16
    
    1079 1084
     primop   BRev32Op   "bitReverse32#"   GenPrimOp   Word# -> Word#
    
    1080 1085
         {Reverse the order of the bits in a 32-bit word.}
    
    1086
    +    with defined_bits = 32
    
    1081 1087
     primop   BRev64Op   "bitReverse64#"   GenPrimOp   Word64# -> Word64#
    
    1082 1088
         {Reverse the order of the bits in a 64-bit word.}
    
    1083 1089
     primop   BRevOp     "bitReverse#"     GenPrimOp   Word# -> Word#
    

  • compiler/GHC/Cmm/CommonBlockElim.hs
    ... ... @@ -29,6 +29,7 @@ import GHC.Utils.Word64 (truncateWord64ToWord32)
    29 29
     import Control.Arrow (first, second)
    
    30 30
     import Data.List.NonEmpty (NonEmpty (..))
    
    31 31
     import qualified Data.List.NonEmpty as NE
    
    32
    +import GHC.Real (infinity,notANumber)
    
    32 33
     
    
    33 34
     -- -----------------------------------------------------------------------------
    
    34 35
     -- Eliminate common blocks
    
    ... ... @@ -167,7 +168,12 @@ hash_block block =
    167 168
     
    
    168 169
             hash_lit :: CmmLit -> Word32
    
    169 170
             hash_lit (CmmInt i _) = fromInteger i
    
    170
    -        hash_lit (CmmFloat r _) = truncate r
    
    171
    +        hash_lit (CmmFloat r _)
    
    172
    +          -- handle these special cases as `truncate` fails on non-fractional numbers (#26229)
    
    173
    +          | r == infinity   = 9999999
    
    174
    +          | r == -infinity  = 9999998
    
    175
    +          | r == notANumber = 6666666
    
    176
    +          | otherwise       = truncate r
    
    171 177
             hash_lit (CmmVec ls) = hash_list hash_lit ls
    
    172 178
             hash_lit (CmmLabel _) = 119 -- ugh
    
    173 179
             hash_lit (CmmLabelOff _ i) = cvt $ 199 + i
    

  • compiler/GHC/CmmToLlvm/CodeGen.hs
    ... ... @@ -230,23 +230,22 @@ genCall t@(PrimTarget (MO_Prefetch_Data localityInt)) [] args
    230 230
         statement $ Expr $ Call StdCall fptr (argVars' ++ argSuffix) []
    
    231 231
       | otherwise = panic $ "prefetch locality level integer must be between 0 and 3, given: " ++ (show localityInt)
    
    232 232
     
    
    233
    --- Handle PopCnt, Clz, Ctz, and BSwap that need to only convert arg
    
    234
    --- and return types
    
    235
    -genCall t@(PrimTarget (MO_PopCnt w)) dsts args =
    
    236
    -    genCallSimpleCast w t dsts args
    
    237
    -
    
    238
    -genCall t@(PrimTarget (MO_Pdep w)) dsts args =
    
    239
    -    genCallSimpleCast2 w t dsts args
    
    240
    -genCall t@(PrimTarget (MO_Pext w)) dsts args =
    
    241
    -    genCallSimpleCast2 w t dsts args
    
    242
    -genCall t@(PrimTarget (MO_Clz w)) dsts args =
    
    243
    -    genCallSimpleCast w t dsts args
    
    244
    -genCall t@(PrimTarget (MO_Ctz w)) dsts args =
    
    245
    -    genCallSimpleCast w t dsts args
    
    246
    -genCall t@(PrimTarget (MO_BSwap w)) dsts args =
    
    247
    -    genCallSimpleCast w t dsts args
    
    248
    -genCall t@(PrimTarget (MO_BRev w)) dsts args =
    
    249
    -    genCallSimpleCast w t dsts args
    
    233
    +-- Handle Clz, Ctz, BRev, BSwap, Pdep, Pext, and PopCnt that need to only
    
    234
    +-- convert arg and return types
    
    235
    +genCall (PrimTarget op@(MO_Clz w)) [dst] args =
    
    236
    +    genCallSimpleCast w op dst args
    
    237
    +genCall (PrimTarget op@(MO_Ctz w)) [dst] args =
    
    238
    +    genCallSimpleCast w op dst args
    
    239
    +genCall (PrimTarget op@(MO_BRev w)) [dst] args =
    
    240
    +    genCallSimpleCast w op dst args
    
    241
    +genCall (PrimTarget op@(MO_BSwap w)) [dst] args =
    
    242
    +    genCallSimpleCast w op dst args
    
    243
    +genCall (PrimTarget op@(MO_Pdep w)) [dst] args =
    
    244
    +    genCallSimpleCast w op dst args
    
    245
    +genCall (PrimTarget op@(MO_Pext w)) [dst] args =
    
    246
    +    genCallSimpleCast w op dst args
    
    247
    +genCall (PrimTarget op@(MO_PopCnt w)) [dst] args =
    
    248
    +    genCallSimpleCast w op dst args
    
    250 249
     
    
    251 250
     genCall (PrimTarget (MO_AtomicRMW width amop)) [dst] [addr, n] = runStmtsDecls $ do
    
    252 251
         addrVar <- exprToVarW addr
    
    ... ... @@ -640,63 +639,28 @@ genCallExtract _ _ _ _ =
    640 639
     -- since GHC only really has i32 and i64 types and things like Word8 are backed
    
    641 640
     -- by an i32 and just present a logical i8 range. So we must handle conversions
    
    642 641
     -- from i32 to i8 explicitly as LLVM is strict about types.
    
    643
    -genCallSimpleCast :: Width -> ForeignTarget -> [CmmFormal] -> [CmmActual]
    
    644
    -              -> LlvmM StmtData
    
    645
    -genCallSimpleCast w t@(PrimTarget op) [dst] args = do
    
    646
    -    let width = widthToLlvmInt w
    
    647
    -        dstTy = cmmToLlvmType $ localRegType dst
    
    648
    -
    
    649
    -    fname                       <- cmmPrimOpFunctions op
    
    650
    -    (fptr, _, top3)             <- getInstrinct fname width [width]
    
    651
    -
    
    652
    -    (dstV, _dst_ty)             <- getCmmReg (CmmLocal dst)
    
    653
    -
    
    654
    -    let (_, arg_hints) = foreignTargetHints t
    
    655
    -    let args_hints = zip args arg_hints
    
    656
    -    (argsV, stmts2, top2)       <- arg_vars args_hints ([], nilOL, [])
    
    657
    -    (argsV', stmts4)            <- castVars Signed $ zip argsV [width]
    
    658
    -    (retV, s1)                  <- doExpr width $ Call StdCall fptr argsV' []
    
    659
    -    (retVs', stmts5)            <- castVars (cmmPrimOpRetValSignage op) [(retV,dstTy)]
    
    660
    -    let retV'                    = singletonPanic "genCallSimpleCast" retVs'
    
    661
    -    let s2                       = Store retV' dstV Nothing []
    
    662
    -
    
    663
    -    let stmts = stmts2 `appOL` stmts4 `snocOL`
    
    664
    -                s1 `appOL` stmts5 `snocOL` s2
    
    665
    -    return (stmts, top2 ++ top3)
    
    666
    -genCallSimpleCast _ _ dsts _ =
    
    667
    -    panic ("genCallSimpleCast: " ++ show (length dsts) ++ " dsts")
    
    668
    -
    
    669
    --- Handle simple function call that only need simple type casting, of the form:
    
    670
    ---   truncate arg >>= \a -> call(a) >>= zext
    
    671
    ---
    
    672
    --- since GHC only really has i32 and i64 types and things like Word8 are backed
    
    673
    --- by an i32 and just present a logical i8 range. So we must handle conversions
    
    674
    --- from i32 to i8 explicitly as LLVM is strict about types.
    
    675
    -genCallSimpleCast2 :: Width -> ForeignTarget -> [CmmFormal] -> [CmmActual]
    
    676
    -              -> LlvmM StmtData
    
    677
    -genCallSimpleCast2 w t@(PrimTarget op) [dst] args = do
    
    678
    -    let width = widthToLlvmInt w
    
    679
    -        dstTy = cmmToLlvmType $ localRegType dst
    
    680
    -
    
    681
    -    fname                       <- cmmPrimOpFunctions op
    
    682
    -    (fptr, _, top3)             <- getInstrinct fname width (const width <$> args)
    
    683
    -
    
    684
    -    (dstV, _dst_ty)             <- getCmmReg (CmmLocal dst)
    
    685
    -
    
    686
    -    let (_, arg_hints) = foreignTargetHints t
    
    687
    -    let args_hints = zip args arg_hints
    
    688
    -    (argsV, stmts2, top2)       <- arg_vars args_hints ([], nilOL, [])
    
    689
    -    (argsV', stmts4)            <- castVars Signed $ zip argsV (const width <$> argsV)
    
    690
    -    (retV, s1)                  <- doExpr width $ Call StdCall fptr argsV' []
    
    691
    -    (retVs', stmts5)             <- castVars (cmmPrimOpRetValSignage op) [(retV,dstTy)]
    
    692
    -    let retV'                    = singletonPanic "genCallSimpleCast2" retVs'
    
    693
    -    let s2                       = Store retV' dstV Nothing []
    
    642
    +genCallSimpleCast :: Width -> CallishMachOp -> CmmFormal -> [CmmActual]
    
    643
    +                  -> LlvmM StmtData
    
    644
    +genCallSimpleCast specW op dst args = do
    
    645
    +    let width   = widthToLlvmInt specW
    
    646
    +        argsW   = const width <$> args
    
    647
    +        dstType = cmmToLlvmType $ localRegType dst
    
    648
    +        signage = cmmPrimOpRetValSignage op
    
    649
    +
    
    650
    +    fname                 <- cmmPrimOpFunctions op
    
    651
    +    (fptr, _, top3)       <- getInstrinct fname width argsW
    
    652
    +    (dstV, _dst_ty)       <- getCmmReg (CmmLocal dst)
    
    653
    +    let (_, arg_hints)     = foreignTargetHints $ PrimTarget op
    
    654
    +    let args_hints         = zip args arg_hints
    
    655
    +    (argsV, stmts2, top2) <- arg_vars args_hints ([], nilOL, [])
    
    656
    +    (argsV', stmts4)      <- castVars signage $ zip argsV argsW
    
    657
    +    (retV, s1)            <- doExpr width $ Call StdCall fptr argsV' []
    
    658
    +    (retV', stmts5)       <- castVar signage retV dstType
    
    659
    +    let s2                 = Store retV' dstV Nothing []
    
    694 660
     
    
    695 661
         let stmts = stmts2 `appOL` stmts4 `snocOL`
    
    696
    -                s1 `appOL` stmts5 `snocOL` s2
    
    662
    +                s1 `snocOL` stmts5 `snocOL` s2
    
    697 663
         return (stmts, top2 ++ top3)
    
    698
    -genCallSimpleCast2 _ _ dsts _ =
    
    699
    -    panic ("genCallSimpleCast2: " ++ show (length dsts) ++ " dsts")
    
    700 664
     
    
    701 665
     -- | Create a function pointer from a target.
    
    702 666
     getFunPtrW :: (LMString -> LlvmType) -> ForeignTarget
    
    ... ... @@ -811,11 +775,47 @@ castVar signage v t | getVarType v == t
    811 775
                 Signed      -> LM_Sext
    
    812 776
                 Unsigned    -> LM_Zext
    
    813 777
     
    
    814
    -
    
    815 778
     cmmPrimOpRetValSignage :: CallishMachOp -> Signage
    
    816 779
     cmmPrimOpRetValSignage mop = case mop of
    
    817
    -    MO_Pdep _   -> Unsigned
    
    818
    -    MO_Pext _   -> Unsigned
    
    780
    +    -- Some bit-wise operations /must/ always treat the input and output values
    
    781
    +    -- as 'Unsigned' in order to return the expected result values when pre/post-
    
    782
    +    -- operation bit-width truncation and/or extension occur. For example,
    
    783
    +    -- consider the Bit-Reverse operation:
    
    784
    +    --
    
    785
    +    -- If the result of a Bit-Reverse is treated as signed,
    
    786
    +    -- an positive input can result in an negative output, i.e.:
    
    787
    +    --
    
    788
    +    --   identity(0x03) = 0x03 = 00000011
    
    789
    +    --   breverse(0x03) = 0xC0 = 11000000
    
    790
    +    --
    
    791
    +    -- Now if an extension is performed after the operation to
    
    792
    +    -- promote a smaller bit-width value into a larger bit-width
    
    793
    +    -- type, it is expected that the /bit-wise/ operations will
    
    794
    +    -- not be treated /numerically/ as signed.
    
    795
    +    --
    
    796
    +    -- To illustrate the difference, consider how a signed extension
    
    797
    +    -- for the type i16 to i32 differs for out values above:
    
    798
    +    --   ext_zeroed(i32, breverse(0x03)) = 0x00C0 = 0000000011000000
    
    799
    +    --   ext_signed(i32, breverse(0x03)) = 0xFFC0 = 1111111111000000
    
    800
    +    --
    
    801
    +    -- Here we can see that the former output is the expected result
    
    802
    +    -- of a bit-wise operation which needs to be promoted to a larger
    
    803
    +    -- bit-width type. The latter output is not desirable when we must
    
    804
    +    -- constraining a value into a range of i16 within an i32 type.
    
    805
    +    --
    
    806
    +    -- Hence we always treat the "signage" as unsigned for Bit-Reverse!
    
    807
    +    --
    
    808
    +    -- The same reasoning applied to Bit-Reverse above applies to the other
    
    809
    +    -- bit-wise operations; do not sign extend a possibly negated number!
    
    810
    +    MO_BRev   _ -> Unsigned
    
    811
    +    MO_BSwap  _ -> Unsigned
    
    812
    +    MO_Clz    _ -> Unsigned
    
    813
    +    MO_Ctz    _ -> Unsigned
    
    814
    +    MO_Pdep   _ -> Unsigned
    
    815
    +    MO_Pext   _ -> Unsigned
    
    816
    +    MO_PopCnt _ -> Unsigned
    
    817
    +
    
    818
    +    -- All other cases, default to preserving the numeric sign when extending.
    
    819 819
         _           -> Signed
    
    820 820
     
    
    821 821
     -- | Decide what C function to use to implement a CallishMachOp
    

  • compiler/GHC/Tc/Solver/Equality.hs
    ... ... @@ -197,12 +197,8 @@ zonkEqTypes ev eq_rel ty1 ty2
    197 197
             then tycon tc1 tys1 tys2
    
    198 198
             else bale_out ty1 ty2
    
    199 199
     
    
    200
    -    go ty1 ty2
    
    201
    -      | Just (ty1a, ty1b) <- tcSplitAppTyNoView_maybe ty1
    
    202
    -      , Just (ty2a, ty2b) <- tcSplitAppTyNoView_maybe ty2
    
    203
    -      = do { res_a <- go ty1a ty2a
    
    204
    -           ; res_b <- go ty1b ty2b
    
    205
    -           ; return $ combine_rev mkAppTy res_b res_a }
    
    200
    +    -- If you are temppted to add a case for AppTy/AppTy, be careful
    
    201
    +    -- See Note [zonkEqTypes and the PKTI]
    
    206 202
     
    
    207 203
         go ty1@(LitTy lit1) (LitTy lit2)
    
    208 204
           | lit1 == lit2
    
    ... ... @@ -278,6 +274,32 @@ zonkEqTypes ev eq_rel ty1 ty2
    278 274
         combine_rev f (Right tys) (Right ty) = Right (f ty tys)
    
    279 275
     
    
    280 276
     
    
    277
    +{- Note [zonkEqTypes and the PKTI]
    
    278
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    279
    +Because `zonkEqTypes` does /partial/ zonking, we need to be very careful
    
    280
    +to maintain the Purely Kinded Type Invariant: see GHC.Tc.Gen/HsType
    
    281
    +HsNote [The Purely Kinded Type Invariant (PKTI)].
    
    282
    +
    
    283
    +In #26256 we try to solve this equality constraint:
    
    284
    +   Int :-> Maybe Char ~# k0 Int (m0 Char)
    
    285
    +where m0 and k0 are unification variables, and
    
    286
    +   m0 :: Type -> Type
    
    287
    +It happens that m0 was already unified
    
    288
    +   m0 := (w0 :: kappa)
    
    289
    +where kappa is another unification variable that is also already unified:
    
    290
    +   kappa := Type->Type.
    
    291
    +So the original type satisifed the PKTI, but a partially-zonked form
    
    292
    +   k0 Int (w0 Char)
    
    293
    +does not!! (This a bit reminiscent of Note [mkAppTyM].)
    
    294
    +
    
    295
    +The solution I have adopted is simply to make `zonkEqTypes` bale out on `AppTy`.
    
    296
    +After all, it's only supposed to be a quick hack to see if two types are already
    
    297
    +equal; if we bale out we'll just get into the "proper" canonicaliser.
    
    298
    +
    
    299
    +The only tricky thing about this approach is that it relies on /omitting/
    
    300
    +code -- for the AppTy/AppTy case!  Hence this Note
    
    301
    +-}
    
    302
    +
    
    281 303
     {- *********************************************************************
    
    282 304
     *                                                                      *
    
    283 305
     *           canonicaliseEquality
    

  • docs/users_guide/conf.py
    ... ... @@ -35,8 +35,6 @@ nitpick_ignore = [
    35 35
         ("envvar", "TMPDIR"),
    
    36 36
     
    
    37 37
         ("c:type", "bool"),
    
    38
    -
    
    39
    -    ("extension", "RelaxedPolyRec"),
    
    40 38
     ]
    
    41 39
     
    
    42 40
     rst_prolog = """
    

  • docs/users_guide/expected-undocumented-flags.txt
    ... ... @@ -14,7 +14,6 @@
    14 14
     -XPolymorphicComponents
    
    15 15
     -XRecordPuns
    
    16 16
     -XRelaxedLayout
    
    17
    --XRelaxedPolyRec
    
    18 17
     -copy-libs-when-linking
    
    19 18
     -dannot-lint
    
    20 19
     -dppr-ticks
    

  • docs/users_guide/exts/doandifthenelse.rst
    ... ... @@ -8,7 +8,7 @@ Do And If Then Else
    8 8
     
    
    9 9
         :since: 7.0.1
    
    10 10
     
    
    11
    -    :status: Included in :extension:`Haskell2010`
    
    11
    +    :status: Included in :extension:`GHC2024`, :extension:`GHC2021`, :extension:`Haskell2010`
    
    12 12
     
    
    13 13
         Allow semicolons in ``if`` expressions.
    
    14 14
     
    

  • docs/users_guide/exts/relaxed_poly_rec.rst
    1
    +.. _relaxed-poly-rec:
    
    2
    +
    
    3
    +Generalised typing of mutually recursive bindings
    
    4
    +-------------------------------------------------
    
    5
    +
    
    6
    +.. extension:: RelaxedPolyRec
    
    7
    +    :shortdesc: Generalised typing of mutually recursive bindings.
    
    8
    +
    
    9
    +    :since: 6.8.1
    
    10
    +
    
    11
    +    :status: Included in :extension:`GHC2024`, :extension:`GHC2021`, :extension:`Haskell2010`
    
    12
    +
    
    13
    +See :ref:`infelicities-recursive-groups` for a description of this extension.
    
    14
    +This is a long-standing GHC extension. Around the time of GHC 7.6.3, this
    
    15
    +extension became required as part of a typechecker refactoring.
    
    16
    +The ``-XRelaxedPolyRec`` flag is now deprecated (since the feature is always
    
    17
    +enabled) and may be removed at some future time.

  • docs/users_guide/exts/types.rst
    ... ... @@ -30,3 +30,4 @@ Types
    30 30
         type_errors
    
    31 31
         defer_type_errors
    
    32 32
         roles
    
    33
    +    relaxed_poly_rec

  • libraries/ghc-internal/cbits/pdep.c
    ... ... @@ -24,20 +24,23 @@ hs_pdep64(StgWord64 src, StgWord64 mask)
    24 24
       return result;
    
    25 25
     }
    
    26 26
     
    
    27
    +// When dealing with values of bit-width shorter than uint64_t, ensure to
    
    28
    +// cast the return value to correctly truncate the undefined upper bits.
    
    29
    +// This is *VERY* important when GHC is using the LLVM backend!
    
    27 30
     StgWord
    
    28 31
     hs_pdep32(StgWord src, StgWord mask)
    
    29 32
     {
    
    30
    -  return hs_pdep64(src, mask);
    
    33
    +  return (StgWord) ((StgWord32) hs_pdep64(src, mask));
    
    31 34
     }
    
    32 35
     
    
    33 36
     StgWord
    
    34 37
     hs_pdep16(StgWord src, StgWord mask)
    
    35 38
     {
    
    36
    -  return hs_pdep64(src, mask);
    
    39
    +  return (StgWord) ((StgWord16) hs_pdep64(src, mask));
    
    37 40
     }
    
    38 41
     
    
    39 42
     StgWord
    
    40 43
     hs_pdep8(StgWord src, StgWord mask)
    
    41 44
     {
    
    42
    -  return hs_pdep64(src, mask);
    
    45
    +  return (StgWord) ((StgWord8) hs_pdep64(src, mask));
    
    43 46
     }

  • libraries/ghc-internal/cbits/pext.c
    1 1
     #include "Rts.h"
    
    2 2
     #include "MachDeps.h"
    
    3 3
     
    
    4
    -StgWord64
    
    5
    -hs_pext64(StgWord64 src, StgWord64 mask)
    
    4
    +static StgWord64
    
    5
    +hs_pext(const unsigned char bit_width, const StgWord64 src, const StgWord64 mask)
    
    6 6
     {
    
    7 7
       uint64_t result = 0;
    
    8 8
       int offset = 0;
    
    9 9
     
    
    10
    -  for (int bit = 0; bit != sizeof(uint64_t) * 8; ++bit) {
    
    10
    +  for (int bit = 0; bit != bit_width; ++bit) {
    
    11 11
         const uint64_t src_bit = (src >> bit) & 1;
    
    12 12
         const uint64_t mask_bit = (mask >> bit) & 1;
    
    13 13
     
    
    ... ... @@ -20,20 +20,29 @@ hs_pext64(StgWord64 src, StgWord64 mask)
    20 20
       return result;
    
    21 21
     }
    
    22 22
     
    
    23
    +StgWord64
    
    24
    +hs_pext64(const StgWord64 src, const StgWord64 mask)
    
    25
    +{
    
    26
    +  return hs_pext(64, src, mask);
    
    27
    +}
    
    28
    +
    
    29
    +// When dealing with values of bit-width shorter than uint64_t, ensure to
    
    30
    +// cast the return value to correctly truncate the undefined upper bits.
    
    31
    +// This is *VERY* important when GHC is using the LLVM backend!
    
    23 32
     StgWord
    
    24
    -hs_pext32(StgWord src, StgWord mask)
    
    33
    +hs_pext32(const StgWord src, const StgWord mask)
    
    25 34
     {
    
    26
    -  return hs_pext64(src, mask);
    
    35
    +  return (StgWord) ((StgWord32) hs_pext(32, src, mask));
    
    27 36
     }
    
    28 37
     
    
    29 38
     StgWord
    
    30
    -hs_pext16(StgWord src, StgWord mask)
    
    39
    +hs_pext16(const StgWord src, const StgWord mask)
    
    31 40
     {
    
    32
    -  return hs_pext64(src, mask);
    
    41
    +  return (StgWord) ((StgWord16) hs_pext(16, src, mask));
    
    33 42
     }
    
    34 43
     
    
    35 44
     StgWord
    
    36
    -hs_pext8(StgWord src, StgWord mask)
    
    45
    +hs_pext8(const StgWord src, const StgWord mask)
    
    37 46
     {
    
    38
    -  return hs_pext64(src, mask);
    
    47
    +  return (StgWord) ((StgWord8) hs_pext(8, src, mask));
    
    39 48
     }

  • testsuite/tests/llvm/should_run/T20645.hs
    1
    +-- Minimal reproducer for https://gitlab.haskell.org/ghc/ghc/-/issues/20645
    
    2
    +{-# LANGUAGE MagicHash #-}
    
    3
    +{-# LANGUAGE ExtendedLiterals #-}
    
    4
    +import GHC.Exts
    
    5
    +import GHC.Word
    
    6
    +import Numeric (showHex)
    
    7
    +
    
    8
    +opaqueInt8# :: Int8# -> Int8#
    
    9
    +opaqueInt8# x = x
    
    10
    +{-# OPAQUE opaqueInt8# #-}
    
    11
    +
    
    12
    +main :: IO ()
    
    13
    +main = let !x = opaqueInt8# 109#Int8
    
    14
    +           !y = opaqueInt8#   1#Int8
    
    15
    +       in putStrLn $ flip showHex "" (W# ( pext8#
    
    16
    +              (word8ToWord# (int8ToWord8# (0#Int8 `subInt8#` x     )))
    
    17
    +              (word8ToWord# (int8ToWord8# (y      `subInt8#` 4#Int8)))
    
    18
    +          ))

  • testsuite/tests/llvm/should_run/T20645.stdout
    1
    +49

  • testsuite/tests/llvm/should_run/all.T
    ... ... @@ -17,3 +17,4 @@ test('T22487', [normal, normalise_errmsg_fun(ignore_llvm_and_vortex)], compile_a
    17 17
     test('T22033', [normal, normalise_errmsg_fun(ignore_llvm_and_vortex)], compile_and_run, [''])
    
    18 18
     test('T25730', [req_c, unless(arch('x86_64'), skip), normalise_errmsg_fun(ignore_llvm_and_vortex)], compile_and_run, ['T25730C.c'])
    
    19 19
       # T25730C.c contains Intel instrinsics, so only run this test on x86
    
    20
    +test('T20645', [normal, normalise_errmsg_fun(ignore_llvm_and_vortex), when(have_llvm(), extra_ways(["optllvm"]))], compile_and_run, [''])

  • testsuite/tests/numeric/should_compile/T26229.hs
    1
    +{-# LANGUAGE NegativeLiterals #-}
    
    2
    +
    
    3
    +module T26229 where
    
    4
    +
    
    5
    +sqrte2pqiq :: (Floating a, Ord a) => a -> a -> a
    
    6
    +sqrte2pqiq e qiq -- = sqrt (e*e + qiq)
    
    7
    +  | e < - 1.5097698010472593e153 = -(qiq/e) - e
    
    8
    +  | e < 5.582399551122541e57     = sqrt (e*e + qiq) -- test Infinity#
    
    9
    +  | e < -5.582399551122541e57    = -sqrt (e*e + qiq) -- test -Infinity#
    
    10
    +  | otherwise                    = (qiq/e) + e
    
    11
    +{-# SPECIALIZE sqrte2pqiq :: Double -> Double -> Double #-}
    
    12
    +{-# SPECIALIZE sqrte2pqiq :: Float -> Float -> Float #-}

  • testsuite/tests/numeric/should_compile/all.T
    ... ... @@ -22,3 +22,4 @@ test('T15547', normal, compile, ['-ddump-simpl -O -dsuppress-all -dno-typeable-b
    22 22
     test('T23019', normal, compile, ['-O'])
    
    23 23
     test('T23907', [ when(wordsize(32), expect_broken(23908))], compile, ['-ddump-simpl -O2 -dsuppress-all -dno-typeable-binds -dsuppress-uniques'])
    
    24 24
     test('T24331', normal, compile, ['-O -ddump-simpl -dsuppress-all -dsuppress-uniques -dno-typeable-binds'])
    
    25
    +test('T26229', normal, compile, ['-O2'])

  • testsuite/tests/numeric/should_run/foundation.hs
    ... ... @@ -24,6 +24,7 @@ module Main
    24 24
         ( main
    
    25 25
         ) where
    
    26 26
     
    
    27
    +import Data.Bits (Bits((.&.), bit))
    
    27 28
     import Data.Word
    
    28 29
     import Data.Int
    
    29 30
     import GHC.Natural
    
    ... ... @@ -408,6 +409,33 @@ instance TestPrimop (Word# -> Int# -> Word#) where
    408 409
       testPrimop s l r = Property s $ \(uWord -> a1) (uInt -> a2) -> (wWord (l a1 a2)) === wWord (r a1 a2)
    
    409 410
       -}
    
    410 411
     
    
    412
    +-- | A special data-type for representing functions where,
    
    413
    +-- since only some number of the lower bits are defined,
    
    414
    +-- testing for strict equality in the undefined upper bits is not appropriate!
    
    415
    +-- Without using this data-type, false-positive failures will be reported
    
    416
    +-- when the undefined bit regions do not match, even though the equality of bits
    
    417
    +-- in this undefined region has no bearing on correctness.
    
    418
    +data LowerBitsAreDefined =
    
    419
    +    LowerBitsAreDefined
    
    420
    +    { definedLowerWidth :: Word
    
    421
    +    -- ^ The (strictly-non-negative) number of least-significant bits
    
    422
    +    -- for which the attached function is defined.
    
    423
    +    , undefinedBehavior :: (Word# -> Word#)
    
    424
    +    -- ^ Function with undefined behavior for some of its most significant bits.
    
    425
    +    }
    
    426
    +
    
    427
    +instance TestPrimop LowerBitsAreDefined where
    
    428
    +  testPrimop s l r = Property s $ \ (uWord#-> x0) ->
    
    429
    +    let -- Create a mask to unset all bits in the undefined area,
    
    430
    +        -- leaving set bits only in the area of defined behavior.
    
    431
    +        -- Since the upper bits are undefined,
    
    432
    +        -- if the function defines behavior for the lower N bits,
    
    433
    +        -- then /only/ the lower N bits are preserved,
    
    434
    +        -- and the upper WORDSIZE - N bits are discarded.
    
    435
    +        mask = bit (fromEnum (definedLowerWidth r)) - 1
    
    436
    +        valL = wWord# (undefinedBehavior l x0) .&. mask
    
    437
    +        valR = wWord# (undefinedBehavior r x0) .&. mask
    
    438
    +    in  valL === valR
    
    411 439
     
    
    412 440
     twoNonZero :: (a -> a -> b) -> a -> NonZero a -> b
    
    413 441
     twoNonZero f x (NonZero y) = f x y
    
    ... ... @@ -655,13 +683,13 @@ testPrimops = Group "primop"
    655 683
       , testPrimop "ctz32#" Primop.ctz32# Wrapper.ctz32#
    
    656 684
       , testPrimop "ctz64#" Primop.ctz64# Wrapper.ctz64#
    
    657 685
       , testPrimop "ctz#" Primop.ctz# Wrapper.ctz#
    
    658
    -  , testPrimop "byteSwap16#" Primop.byteSwap16# Wrapper.byteSwap16#
    
    659
    -  , testPrimop "byteSwap32#" Primop.byteSwap32# Wrapper.byteSwap32#
    
    686
    +  , testPrimop "byteSwap16#" (16 `LowerBitsAreDefined` Primop.byteSwap16#) (16 `LowerBitsAreDefined` Wrapper.byteSwap16#)
    
    687
    +  , testPrimop "byteSwap32#" (32 `LowerBitsAreDefined` Primop.byteSwap32#) (32 `LowerBitsAreDefined` Wrapper.byteSwap32#)
    
    660 688
       , testPrimop "byteSwap64#" Primop.byteSwap64# Wrapper.byteSwap64#
    
    661 689
       , testPrimop "byteSwap#" Primop.byteSwap# Wrapper.byteSwap#
    
    662
    -  , testPrimop "bitReverse8#" Primop.bitReverse8# Wrapper.bitReverse8#
    
    663
    -  , testPrimop "bitReverse16#" Primop.bitReverse16# Wrapper.bitReverse16#
    
    664
    -  , testPrimop "bitReverse32#" Primop.bitReverse32# Wrapper.bitReverse32#
    
    690
    +  , testPrimop "bitReverse8#" (8 `LowerBitsAreDefined` Primop.bitReverse8#) (8 `LowerBitsAreDefined` Wrapper.bitReverse8#)
    
    691
    +  , testPrimop "bitReverse16#" (16 `LowerBitsAreDefined` Primop.bitReverse16#) (16 `LowerBitsAreDefined` Wrapper.bitReverse16#)
    
    692
    +  , testPrimop "bitReverse32#" (32 `LowerBitsAreDefined` Primop.bitReverse32#) (32 `LowerBitsAreDefined` Wrapper.bitReverse32#)
    
    665 693
       , testPrimop "bitReverse64#" Primop.bitReverse64# Wrapper.bitReverse64#
    
    666 694
       , testPrimop "bitReverse#" Primop.bitReverse# Wrapper.bitReverse#
    
    667 695
       , testPrimop "narrow8Int#" Primop.narrow8Int# Wrapper.narrow8Int#
    

  • testsuite/tests/partial-sigs/should_compile/T26256.hs
    1
    +{-# LANGUAGE GHC2021 #-}
    
    2
    +{-# LANGUAGE TypeFamilies #-}
    
    3
    +{-# LANGUAGE PartialTypeSignatures #-}
    
    4
    +
    
    5
    +module M (go) where
    
    6
    +
    
    7
    +import Data.Kind
    
    8
    +
    
    9
    +type Apply :: (Type -> Type) -> Type
    
    10
    +data Apply m
    
    11
    +
    
    12
    +type (:->) :: Type -> Type -> Type
    
    13
    +type family (:->) where (:->) = (->)
    
    14
    +
    
    15
    +f :: forall (k :: Type -> Type -> Type) (m :: Type -> Type).
    
    16
    +     k Int (m Char) -> k Bool (Apply m)
    
    17
    +f = f
    
    18
    +
    
    19
    +x :: Int :-> Maybe Char
    
    20
    +x = x
    
    21
    +
    
    22
    +go :: Bool -> _ _
    
    23
    +go = f x

  • testsuite/tests/partial-sigs/should_compile/T26256.stderr
    1
    +T26256.hs:22:15: warning: [GHC-88464] [-Wpartial-type-signatures (in -Wdefault)]
    
    2
    +    • Found type wildcard ‘_’ standing for ‘Apply :: (* -> *) -> *’
    
    3
    +    • In the type signature: go :: Bool -> _ _
    
    4
    +
    
    5
    +T26256.hs:22:17: warning: [GHC-88464] [-Wpartial-type-signatures (in -Wdefault)]
    
    6
    +    • Found type wildcard ‘_’ standing for ‘Maybe :: * -> *’
    
    7
    +    • In the first argument of ‘_’, namely ‘_’
    
    8
    +      In the type signature: go :: Bool -> _ _

  • testsuite/tests/partial-sigs/should_compile/all.T
    ... ... @@ -108,3 +108,4 @@ test('T21667', normal, compile, [''])
    108 108
     test('T22065', normal, compile, [''])
    
    109 109
     test('T16152', normal, compile, [''])
    
    110 110
     test('T20076', expect_broken(20076), compile, [''])
    
    111
    +test('T26256', normal, compile, [''])

  • testsuite/tests/typecheck/should_compile/T26256a.hs
    1
    +{-# LANGUAGE GHC2021 #-}
    
    2
    +{-# LANGUAGE TypeFamilies #-}
    
    3
    +
    
    4
    +module T26256 (go) where
    
    5
    +
    
    6
    +import Data.Kind
    
    7
    +
    
    8
    +class Cat k where (<<<) :: k a b -> k x a -> k x b
    
    9
    +instance Cat (->) where (<<<) = (.)
    
    10
    +class Pro k p where pro :: k a b s t -> p a b -> p s t
    
    11
    +data Hiding o a b s t = forall e. Hiding (s -> o e a)
    
    12
    +newtype Apply e a = Apply (e a)
    
    13
    +
    
    14
    +type (:->) :: Type -> Type -> Type
    
    15
    +type family (:->) where
    
    16
    +  (:->) = (->)
    
    17
    +
    
    18
    +go :: (Pro (Hiding Apply) p) => (s :-> e a) -> p a b -> p s t
    
    19
    +go sea = pro (Hiding (Apply <<< sea))

  • testsuite/tests/typecheck/should_compile/all.T
    ... ... @@ -940,3 +940,4 @@ test('T26020', normal, compile, [''])
    940 940
     test('T26020a', [extra_files(['T26020a_help.hs'])], multimod_compile, ['T26020a', '-v0'])
    
    941 941
     test('T25992', normal, compile, [''])
    
    942 942
     test('T14010', normal, compile, [''])
    
    943
    +test('T26256a', normal, compile, [''])

  • utils/genprimopcode/Lexer.x
    ... ... @@ -56,6 +56,7 @@ words :-
    56 56
         <0>         "CanFail"           { mkT TCanFail }
    
    57 57
         <0>         "ThrowsException"   { mkT TThrowsException }
    
    58 58
         <0>         "ReadWriteEffect"   { mkT TReadWriteEffect }
    
    59
    +    <0>         "defined_bits"      { mkT TDefinedBits }
    
    59 60
         <0>         "can_fail_warning"  { mkT TCanFailWarnFlag }
    
    60 61
         <0>         "DoNotWarnCanFail"  { mkT TDoNotWarnCanFail }
    
    61 62
         <0>         "WarnIfEffectIsCanFail" { mkT TWarnIfEffectIsCanFail }
    

  • utils/genprimopcode/Main.hs
    ... ... @@ -10,6 +10,7 @@ module Main where
    10 10
     import Parser
    
    11 11
     import Syntax
    
    12 12
     
    
    13
    +import Control.Applicative (asum)
    
    13 14
     import Data.Char
    
    14 15
     import Data.List (union, intersperse, intercalate, nub, sort)
    
    15 16
     import Data.Maybe ( catMaybes, mapMaybe )
    
    ... ... @@ -116,9 +117,15 @@ desugarVectorSpec i = case vecOptions i of
    116 117
     main :: IO ()
    
    117 118
     main = getArgs >>= \args ->
    
    118 119
            if length args /= 1 || head args `notElem` known_args
    
    119
    -       then error ("usage: genprimopcode command < primops.txt > ...\n"
    
    120
    +       then error ("Usage: genprimopcode command < primops.txt > ...\n"
    
    120 121
                        ++ "   where command is one of\n"
    
    121 122
                        ++ unlines (map ("            "++) known_args)
    
    123
    +                   ++ unlines
    
    124
    +                        [ ""
    
    125
    +                        , "Nota Bene:  Be sure to manually run primops.txt through the C Pre-Processor"
    
    126
    +                        , "            before sending the input stream to STDIN, i.e:"
    
    127
    +                        , ""
    
    128
    +                        , "                cpp -P -w primops.txt | genprimopcode command" ]
    
    122 129
                       )
    
    123 130
            else
    
    124 131
            do hSetEncoding stdin  utf8 -- The input file is in UTF-8. Set the encoding explicitly.
    
    ... ... @@ -312,6 +319,7 @@ gen_hs_source (Info defaults entries) =
    312 319
                opt (OptionVector _)    = ""
    
    313 320
                opt (OptionFixity mf) = "fixity = " ++ show mf
    
    314 321
                opt (OptionEffect eff) = "effect = " ++ show eff
    
    322
    +           opt (OptionDefinedBits bc) = "defined_bits = " ++ show bc
    
    315 323
                opt (OptionCanFailWarnFlag wf) = "can_fail_warning = " ++ show wf
    
    316 324
     
    
    317 325
                hdr s@(Section {})                                    = sec s
    
    ... ... @@ -638,6 +646,7 @@ gen_switch_from_attribs attrib_name fn_name (Info defaults entries)
    638 646
              getAltRhs (OptionVector _) = "True"
    
    639 647
              getAltRhs (OptionFixity mf) = show mf
    
    640 648
              getAltRhs (OptionEffect eff) = show eff
    
    649
    +         getAltRhs (OptionDefinedBits bc) = show bc
    
    641 650
              getAltRhs (OptionCanFailWarnFlag wf) = show wf
    
    642 651
     
    
    643 652
              mkAlt po
    
    ... ... @@ -753,7 +762,12 @@ gen_foundation_tests (Info _ entries)
    753 762
           = let testPrimOpHow = if is_divLikeOp po
    
    754 763
                   then "testPrimopDivLike"
    
    755 764
                   else "testPrimop"
    
    756
    -        in Just $ intercalate " " [testPrimOpHow, "\"" ++ poName ++ "\"", wrap "Primop" poName, wrap "Wrapper" poName]
    
    765
    +            qualOp qualification =
    
    766
    +              let qName = wrap qualification poName
    
    767
    +              in  case mb_defined_bits po of
    
    768
    +                    Nothing -> qName
    
    769
    +                    Just bs -> concat ["(", show bs, " `LowerBitsAreDefined` ", qName, ")"]
    
    770
    +        in Just $ intercalate " " [testPrimOpHow, "\"" ++ poName ++ "\"", qualOp "Primop", qualOp "Wrapper"]
    
    757 771
           | otherwise = Nothing
    
    758 772
     
    
    759 773
     
    
    ... ... @@ -771,6 +785,16 @@ gen_foundation_tests (Info _ entries)
    771 785
         divableTyCons = ["Int#", "Word#", "Word8#", "Word16#", "Word32#", "Word64#"
    
    772 786
                         ,"Int8#", "Int16#", "Int32#", "Int64#"]
    
    773 787
     
    
    788
    +    mb_defined_bits :: Entry -> Maybe Word
    
    789
    +    mb_defined_bits op@(PrimOpSpec{}) =
    
    790
    +      let opOpts = opts op
    
    791
    +          getDefBits :: Option -> Maybe Word
    
    792
    +          getDefBits (OptionDefinedBits x) = x
    
    793
    +          getDefBits _ = Nothing
    
    794
    +      in  asum $ getDefBits <$> opOpts
    
    795
    +    mb_defined_bits _ = Nothing
    
    796
    +
    
    797
    +
    
    774 798
     ------------------------------------------------------------------
    
    775 799
     -- Create PrimOpInfo text from PrimOpSpecs -----------------------
    
    776 800
     ------------------------------------------------------------------
    

  • utils/genprimopcode/Parser.y
    ... ... @@ -50,6 +50,7 @@ import AccessOps
    50 50
         CanFail         { TCanFail }
    
    51 51
         ThrowsException { TThrowsException }
    
    52 52
         ReadWriteEffect { TReadWriteEffect }
    
    53
    +    defined_bits     { TDefinedBits }
    
    53 54
         can_fail_warning { TCanFailWarnFlag }
    
    54 55
         DoNotWarnCanFail { TDoNotWarnCanFail }
    
    55 56
         WarnIfEffectIsCanFail { TWarnIfEffectIsCanFail }
    
    ... ... @@ -81,13 +82,14 @@ pOptions : pOption pOptions { $1 : $2 }
    81 82
              | {- empty -}      { [] }
    
    82 83
     
    
    83 84
     pOption :: { Option }
    
    84
    -pOption : lowerName '=' false               { OptionFalse  $1 }
    
    85
    -        | lowerName '=' true                { OptionTrue   $1 }
    
    86
    -        | lowerName '=' pStuffBetweenBraces { OptionString $1 $3 }
    
    87
    -        | lowerName '=' integer             { OptionInteger $1 $3 }
    
    88
    -        | vector    '=' pVectorTemplate     { OptionVector $3 }
    
    89
    -        | fixity    '=' pInfix              { OptionFixity $3 }
    
    90
    -        | effect    '=' pEffect             { OptionEffect $3 }
    
    85
    +pOption : lowerName        '=' false                  { OptionFalse   $1     }
    
    86
    +        | lowerName        '=' true                   { OptionTrue    $1     }
    
    87
    +        | lowerName        '=' pStuffBetweenBraces    { OptionString  $1  $3 }
    
    88
    +        | lowerName        '=' integer                { OptionInteger $1  $3 }
    
    89
    +        | vector           '=' pVectorTemplate        { OptionVector      $3 }
    
    90
    +        | fixity           '=' pInfix                 { OptionFixity      $3 }
    
    91
    +        | effect           '=' pEffect                { OptionEffect      $3 }
    
    92
    +        | defined_bits     '=' pGoodBits              { OptionDefinedBits $3 }
    
    91 93
             | can_fail_warning '=' pPrimOpCanFailWarnFlag { OptionCanFailWarnFlag $3 }
    
    92 94
     
    
    93 95
     pInfix :: { Maybe Fixity }
    
    ... ... @@ -102,6 +104,10 @@ pEffect : NoEffect { NoEffect }
    102 104
             | ThrowsException         { ThrowsException }
    
    103 105
             | ReadWriteEffect         { ReadWriteEffect }
    
    104 106
     
    
    107
    +pGoodBits :: { Maybe Word }
    
    108
    +pGoodBits : integer { Just $ toEnum $1 }
    
    109
    +          | nothing { Nothing }
    
    110
    +
    
    105 111
     pPrimOpCanFailWarnFlag :: { PrimOpCanFailWarnFlag }
    
    106 112
     pPrimOpCanFailWarnFlag : DoNotWarnCanFail { DoNotWarnCanFail }
    
    107 113
                               | WarnIfEffectIsCanFail { WarnIfEffectIsCanFail }
    

  • utils/genprimopcode/ParserM.hs
    ... ... @@ -116,6 +116,7 @@ data Token = TEOF
    116 116
                | TCanFail
    
    117 117
                | TThrowsException
    
    118 118
                | TReadWriteEffect
    
    119
    +           | TDefinedBits
    
    119 120
                | TCanFailWarnFlag
    
    120 121
                | TDoNotWarnCanFail
    
    121 122
                | TWarnIfEffectIsCanFail
    

  • utils/genprimopcode/Syntax.hs
    ... ... @@ -76,6 +76,7 @@ data Option
    76 76
        | OptionFixity (Maybe Fixity)  -- fixity = infix{,l,r} <int> | Nothing
    
    77 77
        | OptionEffect PrimOpEffect    -- effect = NoEffect | DoNotSpeculate | CanFail | ThrowsException | ReadWriteEffect | FallibleReadWriteEffect
    
    78 78
        | OptionCanFailWarnFlag PrimOpCanFailWarnFlag -- can_fail_warning = DoNotWarnCanFail | WarnIfEffectIsCanFail | YesWarnCanFail
    
    79
    +   | OptionDefinedBits (Maybe Word) -- defined_bits = Just 16 | Nothing
    
    79 80
          deriving Show
    
    80 81
     
    
    81 82
     -- categorises primops
    
    ... ... @@ -196,6 +197,7 @@ get_attrib_name (OptionVector _) = "vector"
    196 197
     get_attrib_name (OptionFixity _) = "fixity"
    
    197 198
     get_attrib_name (OptionEffect _) = "effect"
    
    198 199
     get_attrib_name (OptionCanFailWarnFlag _) = "can_fail_warning"
    
    200
    +get_attrib_name (OptionDefinedBits _) = "defined_bits"
    
    199 201
     
    
    200 202
     lookup_attrib :: String -> [Option] -> Maybe Option
    
    201 203
     lookup_attrib _ [] = Nothing