[Git][ghc/ghc][wip/fix-ubx-cast] Properly convert values before/after storing them in unboxed sums.

Andreas Klebinger (@AndreasK) gitlab at gitlab.haskell.org
Tue Sep 27 22:49:21 UTC 2022



Andreas Klebinger pushed to branch wip/fix-ubx-cast at Glasgow Haskell Compiler / GHC


Commits:
4b781b91 by Andreas Klebinger at 2022-09-28T00:48:03+02:00
Properly convert values before/after storing them in unboxed sums.

See Note [Casting slot arguments] for the details.

- - - - -


18 changed files:

- + compiler/GHC/Builtin/PrimOps/Casts.hs
- compiler/GHC/Cmm/CLabel.hs
- compiler/GHC/Core/TyCon.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Stg/Syntax.hs
- compiler/GHC/Stg/Unarise.hs
- compiler/GHC/Types/RepType.hs
- compiler/GHC/Utils/Outputable.hs
- compiler/ghc.cabal.in
- docs/users_guide/debugging.rst
- testsuite/driver/testlib.py
- + testsuite/tests/unboxedsums/GenManyUbxSums.hs
- + testsuite/tests/unboxedsums/ManyUbxSums_Addr.debug.dump-cmm
- + testsuite/tests/unboxedsums/ManyUbxSums_Addr.debug.dump-stg-final
- + testsuite/tests/unboxedsums/ManyUbxSums_Addr.hs
- + testsuite/tests/unboxedsums/T22208.hs
- testsuite/tests/unboxedsums/all.T


Changes:

=====================================
compiler/GHC/Builtin/PrimOps/Casts.hs
=====================================
@@ -0,0 +1,207 @@
+{-
+This module contains helpers to cast variables
+between different Int/WordReps in StgLand.
+-}
+
+module GHC.Builtin.PrimOps.Casts
+    ( getCasts )
+where
+
+import GHC.Prelude
+
+import GHC.Core.TyCon
+import GHC.Utils.Outputable
+import GHC.Utils.Panic
+import GHC.Utils.Trace
+import GHC.Utils.Panic.Plain
+import GHC.Types.RepType
+import GHC.Core.Type
+import GHC.Builtin.Types.Prim
+import GHC.Builtin.Types
+
+import GHC.Builtin.PrimOps
+import GHC.Plugins (HasDebugCallStack)
+
+{- Note [PrimRep based casting]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+This module contains a number of utility functions useful when
+converting between variables of differing PrimReps.
+
+The general pattern is that we have two primReps `from_rep` and `to_rep`.
+We want a list of PrimOps we can apply to a variable of rep `from_rep`
+in order to get to a variable of rep `to_rep`.
+
+E.g. we call `getCasts from_rep to_rep` and get back [(op1#,ty1),(op2#,ty2)].
+We can use this list of primOps to construct a function of type
+`StgExpr -> StgExpr` by construction an expression
+
+    case op1# <from> of (x' :: ty1) -> case op2# x' of x' -> <rhs_hole>
+-}
+
+-- | `getCasts from_rep to_rep` gives us a list of primops which when applied in order convert from_rep to to_rep.
+-- See Note [PrimRep based casting]
+getCasts :: PrimRep -> PrimRep -> [(PrimOp,Type)]
+getCasts f t =
+    let r = getCasts' f t
+    in pprTrace "getCasts" (ppr (f,t,r)) r
+
+
+getCasts' from_rep to_rep
+  -- No-op
+  | -- pprTrace "getCasts" (ppr (from_rep,to_rep)) $
+    to_rep == from_rep
+  = []
+  -- Float <-> Double
+  | to_rep == FloatRep =
+    assertPpr (from_rep == DoubleRep) (ppr from_rep <+> ppr to_rep) $
+    [(DoubleToFloatOp,floatPrimTy)]
+  | to_rep == DoubleRep =
+    assertPpr (from_rep == FloatRep) (ppr from_rep <+> ppr to_rep) $
+    [(FloatToDoubleOp,doublePrimTy)]
+  -- Addr <-> Word/Int
+  | to_rep == AddrRep = wordOrIntToAddrRep from_rep
+  | from_rep == AddrRep = addrToWordOrIntRep to_rep
+
+  -- Int* -> Int*
+  | primRepIsInt from_rep
+  , primRepIsInt to_rep
+  = sizedIntToSizedInt from_rep to_rep
+
+  -- Word* -> Word*
+  | primRepIsWord from_rep
+  , primRepIsWord to_rep
+  = sizedWordToSizedWord from_rep to_rep
+
+  -- Word* -> Int*
+  | primRepIsWord from_rep
+  , primRepIsInt to_rep
+  = let (op1,r1) = wordToIntRep from_rep
+    in (op1,primRepToType r1):sizedIntToSizedInt r1 to_rep
+
+  -- Int* -> Word*
+  | primRepIsInt from_rep
+  , primRepIsWord to_rep
+  = let (op1,r1) = intToWordRep from_rep
+    in (op1,primRepToType r1):sizedWordToSizedWord r1 to_rep
+
+  | otherwise = pprPanic "getCasts:Unexpect rep combination"
+                          (ppr (from_rep,to_rep))
+
+wordOrIntToAddrRep :: HasDebugCallStack => PrimRep -> [(PrimOp,Type)]
+wordOrIntToAddrRep AddrRep = []
+wordOrIntToAddrRep IntRep = [(IntToAddrOp, addrPrimTy)]
+wordOrIntToAddrRep WordRep = [(WordToIntOp,intPrimTy), (IntToAddrOp,addrPrimTy)]
+wordOrIntToAddrRep r
+    | primRepIsInt r = (intToMachineInt r,intPrimTy):[(IntToAddrOp,addrPrimTy)]
+    | primRepIsWord r =
+        let (op1,r1) = wordToIntRep r
+        in (op1, primRepToType r1):[(intToMachineInt r1,intPrimTy), (IntToAddrOp,addrPrimTy)]
+    | otherwise = pprPanic "Rep not word or int rep" (ppr r)
+
+addrToWordOrIntRep :: HasDebugCallStack => PrimRep -> [(PrimOp,Type)]
+-- Machine sizes
+addrToWordOrIntRep IntRep = [(AddrToIntOp, intPrimTy)]
+addrToWordOrIntRep WordRep = [(AddrToIntOp,intPrimTy), (IntToWordOp,wordPrimTy)]
+-- Explicitly sized reps
+addrToWordOrIntRep r
+    | primRepIsWord r = (AddrToIntOp,intPrimTy) : (IntToWordOp,wordPrimTy) : sizedWordToSizedWord WordRep r
+    | primRepIsInt r = (AddrToIntOp,intPrimTy) : sizedIntToSizedInt IntRep r
+    | otherwise = pprPanic "Target rep not word or int rep" (ppr r)
+
+
+-- WordX# -> IntX# (same size), argument is source rep
+wordToIntRep :: HasDebugCallStack => PrimRep -> (PrimOp,PrimRep)
+wordToIntRep rep
+    = case rep of
+        (WordRep) -> (WordToIntOp, IntRep)
+        (Word8Rep) -> (Word8ToInt8Op, Int8Rep)
+        (Word16Rep) -> (Word16ToInt16Op, Int16Rep)
+        (Word32Rep) -> (Word32ToInt32Op, Int32Rep)
+        (Word64Rep) -> (Word64ToInt64Op, Int64Rep)
+        _ -> pprPanic "Rep not a wordRep" (ppr rep)
+
+-- IntX# -> WordX#, argument is source rep
+intToWordRep :: HasDebugCallStack => PrimRep -> (PrimOp,PrimRep)
+intToWordRep rep
+    = case rep of
+        (IntRep) -> (IntToWordOp, WordRep)
+        (Int8Rep) -> (Int8ToWord8Op, Word8Rep)
+        (Int16Rep) -> (Int16ToWord16Op, Word16Rep)
+        (Int32Rep) -> (Int32ToWord32Op, Word32Rep)
+        (Int64Rep) -> (Int64ToWord64Op, Word64Rep)
+        _ -> pprPanic "Rep not a wordRep" (ppr rep)
+
+-- Casts between any size int to any other size of int
+sizedIntToSizedInt :: HasDebugCallStack => PrimRep -> PrimRep -> [(PrimOp,Type)]
+sizedIntToSizedInt r1 r2
+    | r1 == r2 = []
+-- Cast to Int#
+sizedIntToSizedInt r IntRep = [(intToMachineInt r,intTy)]
+-- Cast from Int#
+sizedIntToSizedInt IntRep r = [(intFromMachineInt r,primRepToType r)]
+-- Sized to differently sized must go over machine word.
+sizedIntToSizedInt r1 r2 = (intToMachineInt r1,intTy) : [(intFromMachineInt r2,primRepToType r2)]
+
+-- Casts between any size Word to any other size of Word
+sizedWordToSizedWord :: HasDebugCallStack => PrimRep -> PrimRep -> [(PrimOp,Type)]
+sizedWordToSizedWord r1 r2
+    | r1 == r2 = []
+-- Cast to Word#
+sizedWordToSizedWord r WordRep = [(wordToMachineWord r,wordPrimTy)]
+-- Cast from Word#
+sizedWordToSizedWord WordRep r = [(wordFromMachineWord r, primRepToType r)]
+-- Conversion between different non-machine sizes must go via machine word.
+sizedWordToSizedWord r1 r2 = (wordToMachineWord r1,wordPrimTy) : [(wordFromMachineWord r2, primRepToType r2)]
+
+
+-- Prefer the definitions above this line if possible
+----------------------
+
+
+-- Int*# to Int#
+{-# INLINE intToMachineInt #-}
+intToMachineInt :: HasDebugCallStack => PrimRep -> PrimOp
+intToMachineInt r =
+    assertPpr (primRepIsInt r) (ppr r) $
+    case r of
+        (Int8Rep) -> Int8ToIntOp
+        (Int16Rep) -> Int16ToIntOp
+        (Int32Rep) -> Int32ToIntOp
+        (Int64Rep) -> Int64ToIntOp
+        _ -> pprPanic "Source rep not int" $ ppr r
+
+-- Int# to Int*#
+{-# INLINE intFromMachineInt #-}
+intFromMachineInt :: HasDebugCallStack => PrimRep -> PrimOp
+intFromMachineInt r =
+    assertPpr (primRepIsInt r) (ppr r) $
+    case r of
+        Int8Rep -> IntToInt8Op
+        Int16Rep -> IntToInt16Op
+        Int32Rep -> IntToInt32Op
+        Int64Rep -> IntToInt64Op
+        _ -> pprPanic "Dest rep not sized int" $ ppr r
+
+-- Word# to Word*#
+{-# INLINE wordFromMachineWord #-}
+wordFromMachineWord :: HasDebugCallStack => PrimRep -> PrimOp
+wordFromMachineWord r =
+    assert (primRepIsWord r) $
+    case r of
+        Word8Rep -> WordToWord8Op
+        Word16Rep -> WordToWord16Op
+        Word32Rep -> WordToWord32Op
+        Word64Rep -> WordToWord64Op
+        _ -> pprPanic "Dest rep not sized word" $ ppr r
+
+-- Word*# to Word#
+{-# INLINE wordToMachineWord #-}
+wordToMachineWord :: HasDebugCallStack => PrimRep -> PrimOp
+wordToMachineWord r =
+    assertPpr (primRepIsWord r) (text "Not a word rep:" <> ppr r) $
+    case r of
+        Word8Rep -> Word8ToWordOp
+        Word16Rep -> Word16ToWordOp
+        Word32Rep -> Word32ToWordOp
+        Word64Rep -> Word64ToWordOp
+        _ -> pprPanic "Dest rep not sized word" $ ppr r
\ No newline at end of file


=====================================
compiler/GHC/Cmm/CLabel.hs
=====================================
@@ -1399,7 +1399,10 @@ instance OutputableP Platform CLabel where
   pdoc !platform lbl = getPprStyle $ \pp_sty ->
                         case pp_sty of
                           PprDump{} -> pprCLabel platform CStyle lbl
-                          _         -> pprPanic "Labels in code should be printed with pprCLabel" (pprCLabel platform CStyle lbl)
+                          -- Workaround for #22218
+                          _         -> (pprCLabel platform CStyle lbl)
+                          -- _         -> pprPanic "Labels in code should be printed with pprCLabel" (pprCLabel platform CStyle lbl)
+
 
 pprCLabel :: Platform -> LabelStyle -> CLabel -> SDoc
 pprCLabel !platform !sty lbl = -- see Note [Bangs in CLabel]


=====================================
compiler/GHC/Core/TyCon.hs
=====================================
@@ -129,6 +129,7 @@ module GHC.Core.TyCon(
         primRepIsFloat,
         primRepsCompatible,
         primRepCompatible,
+        primRepIsWord, primRepIsInt,
 
 ) where
 
@@ -1785,6 +1786,24 @@ primRepIsFloat  DoubleRep    = Just True
 primRepIsFloat  (VecRep _ _) = Nothing
 primRepIsFloat  _            = Just False
 
+-- Rep is one of the word reps.
+primRepIsWord :: PrimRep -> Bool
+primRepIsWord WordRep = True
+primRepIsWord (Word8Rep) = True
+primRepIsWord (Word16Rep) = True
+primRepIsWord (Word32Rep) = True
+primRepIsWord (Word64Rep) = True
+primRepIsWord _ = False
+
+-- Rep is one of the int reps.
+primRepIsInt :: PrimRep -> Bool
+primRepIsInt (IntRep) = True
+primRepIsInt (Int8Rep) = True
+primRepIsInt (Int16Rep) = True
+primRepIsInt (Int32Rep) = True
+primRepIsInt (Int64Rep) = True
+primRepIsInt _ = False
+
 {-
 ************************************************************************
 *                                                                      *


=====================================
compiler/GHC/Driver/Flags.hs
=====================================
@@ -422,6 +422,7 @@ data GeneralFlag
    -- variables that have otherwise identical names.
    | Opt_SuppressUniques
    | Opt_SuppressStgExts
+   | Opt_SuppressStgReps
    | Opt_SuppressTicks     -- Replaces Opt_PprShowTicks
    | Opt_SuppressTimestamps -- ^ Suppress timestamps in dumps
    | Opt_SuppressCoreSizes  -- ^ Suppress per binding Core size stats in dumps


=====================================
compiler/GHC/Driver/Session.hs
=====================================
@@ -2393,6 +2393,7 @@ dynamic_flags_deps = [
                   setGeneralFlag Opt_SuppressIdInfo
                   setGeneralFlag Opt_SuppressTicks
                   setGeneralFlag Opt_SuppressStgExts
+                  setGeneralFlag Opt_SuppressStgReps
                   setGeneralFlag Opt_SuppressTypeSignatures
                   setGeneralFlag Opt_SuppressCoreSizes
                   setGeneralFlag Opt_SuppressTimestamps)
@@ -3344,6 +3345,7 @@ dFlagsDeps = [
   depFlagSpec' "suppress-stg-free-vars" Opt_SuppressStgExts
      (useInstead "-d" "suppress-stg-exts"),
   flagSpec "suppress-stg-exts"          Opt_SuppressStgExts,
+  flagSpec "suppress-stg-reps"          Opt_SuppressStgReps,
   flagSpec "suppress-coercions"         Opt_SuppressCoercions,
   flagSpec "suppress-coercion-types"    Opt_SuppressCoercionTypes,
   flagSpec "suppress-idinfo"            Opt_SuppressIdInfo,
@@ -3796,7 +3798,8 @@ defaultFlags settings
       Opt_VersionMacros,
       Opt_RPath,
       Opt_DumpWithWays,
-      Opt_CompactUnwind
+      Opt_CompactUnwind,
+      Opt_SuppressStgReps
     ]
 
     ++ [f | (ns,f) <- optLevelFlags, 0 `elem` ns]
@@ -5020,6 +5023,7 @@ initSDocContext dflags style = SDC
   , sdocSuppressUniques             = gopt Opt_SuppressUniques dflags
   , sdocSuppressModulePrefixes      = gopt Opt_SuppressModulePrefixes dflags
   , sdocSuppressStgExts             = gopt Opt_SuppressStgExts dflags
+  , sdocSuppressStgReps             = gopt Opt_SuppressStgReps dflags
   , sdocErrorSpans                  = gopt Opt_ErrorSpans dflags
   , sdocStarIsType                  = xopt LangExt.StarIsType dflags
   , sdocLinearTypes                 = xopt LangExt.LinearTypes dflags


=====================================
compiler/GHC/Stg/Syntax.hs
=====================================
@@ -87,7 +87,7 @@ import GHC.Core.Ppr( {- instances -} )
 import GHC.Builtin.PrimOps ( PrimOp, PrimCall )
 import GHC.Core.TyCon    ( PrimRep(..), TyCon )
 import GHC.Core.Type     ( Type )
-import GHC.Types.RepType ( typePrimRep1 )
+import GHC.Types.RepType ( typePrimRep1, typePrimRep )
 import GHC.Utils.Panic.Plain
 
 {-
@@ -740,12 +740,23 @@ pprStgTopBinding = pprGenStgTopBinding
 pprStgTopBindings :: OutputablePass pass => StgPprOpts -> [GenStgTopBinding pass] -> SDoc
 pprStgTopBindings = pprGenStgTopBindings
 
+pprIdWithRep :: Id -> SDoc
+pprIdWithRep v = ppr v <> pprTypeRep (idType v)
+
+pprTypeRep :: Type -> SDoc
+pprTypeRep ty =
+    ppUnlessOption sdocSuppressStgReps $
+    char ':' <> case typePrimRep ty of
+                  [r] -> ppr r
+                  r -> ppr r
+
+
 instance Outputable StgArg where
   ppr = pprStgArg
 
 pprStgArg :: StgArg -> SDoc
-pprStgArg (StgVarArg var) = ppr var
-pprStgArg (StgLitArg con) = ppr con
+pprStgArg (StgVarArg var) = pprIdWithRep var
+pprStgArg (StgLitArg con) = ppr con <> pprTypeRep (literalType con)
 
 instance OutputablePass pass => Outputable  (GenStgExpr pass) where
   ppr = pprStgExpr panicStgPprOpts


=====================================
compiler/GHC/Stg/Unarise.hs
=====================================
@@ -186,6 +186,39 @@ So we pass type arguments of the DataCon's TyCon in StgConApp to decide what
 layout to use. Note that unlifted values can't be let-bound, so we don't need
 types in StgRhsCon.
 
+Note [Casting slot arguments]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider this function which selects between Float# and Double# from a unboxed sum.
+
+    foo ::  (# Float# | Double#  #) -> FD
+    foo x = case x of
+        (# x1 | #) -> F x1
+        (# | x2 #) -> D x2
+
+Naturally we would expect x1 to have a PrimRep of FloatRep and x2 of DoubleRep.
+However we used to generate this (bogus) code after Unarise giving rise to #22208:
+
+    M.foo :: (# GHC.Prim.Float# | GHC.Prim.Double# #) -> M.FD
+    [GblId, Arity=1, Unf=OtherCon []] =
+        {} \r [sum_tag sum_field]
+            case sum_tag of tag_gsc {
+              __DEFAULT -> M.F [sum_field];
+              2# -> M.D [sum_field];
+            };
+
+Where sum_field is used both as Float# and Double# depending on the branch.
+This usually works out since we put floats/doubles in the same sort of register.
+However this caused issues down the road where we would assign between variables
+of different reps causing lint errors or in the case of #22208 even compiler panics.
+For now our solution is to construct proper casts between the PrimRep of the slot and
+the variables we want to store in, or read out of these slots.
+
+This means when we have a sum (# Float# | Double# #) if we want to store a float
+we convert it to a double on construction of the tuple value, and convert it back
+to a float once when want to use the field.
+Conversion for values coming out of a strict field happen in mapSumIdBinders. While
+conversion during the construction of sums happen inside mkUbxSum.
+
 Note [UnariseEnv]
 ~~~~~~~~~~~~~~~~~~
 At any variable occurrence 'v',
@@ -258,8 +291,8 @@ import GHC.Prelude
 import GHC.Types.Basic
 import GHC.Core
 import GHC.Core.DataCon
-import GHC.Core.TyCon ( isVoidRep )
-import GHC.Data.FastString (FastString, mkFastString)
+import GHC.Core.TyCon
+import GHC.Data.FastString (FastString, mkFastString, fsLit, appendFS)
 import GHC.Types.Id
 import GHC.Types.Literal
 import GHC.Core.Make (aBSENT_SUM_FIELD_ERROR_ID)
@@ -281,6 +314,11 @@ import GHC.Types.Var.Env
 import Data.Bifunctor (second)
 import Data.Maybe (mapMaybe)
 import qualified Data.IntMap as IM
+import GHC.Utils.Trace
+import GHC.Builtin.PrimOps
+import GHC.Builtin.PrimOps.Casts
+import Data.List (mapAccumL)
+import GHC.Types.Name
 
 --------------------------------------------------------------------------------
 
@@ -306,8 +344,10 @@ import qualified Data.IntMap as IM
 -- INVARIANT: OutStgArgs in the range only have NvUnaryTypes
 --            (i.e. no unboxed tuples, sums or voids)
 --
-type UnariseEnv = VarEnv UnariseVal
+newtype UnariseEnv = UnariseEnv  { ue_rho :: (VarEnv UnariseVal) }
 
+initUnariseEnv :: VarEnv UnariseVal -> UnariseEnv
+initUnariseEnv = UnariseEnv
 data UnariseVal
   = MultiVal [OutStgArg] -- MultiVal to tuple. Can be empty list (void).
   | UnaryVal OutStgArg   -- See Note [Renaming during unarisation].
@@ -320,25 +360,27 @@ instance Outputable UnariseVal where
 -- The id is mapped to one or more things.
 -- See Note [UnariseEnv]
 extendRho :: UnariseEnv -> Id -> UnariseVal -> UnariseEnv
-extendRho rho x (MultiVal args)
+extendRho env x (MultiVal args)
   = assert (all (isNvUnaryType . stgArgType) args)
-    extendVarEnv rho x (MultiVal args)
-extendRho rho x (UnaryVal val)
+    env { ue_rho = extendVarEnv (ue_rho env) x (MultiVal args) }
+extendRho env x (UnaryVal val)
   = assert (isNvUnaryType (stgArgType val))
-    extendVarEnv rho x (UnaryVal val)
+    env { ue_rho = extendVarEnv (ue_rho env) x (UnaryVal val) }
 -- Properly shadow things from an outer scope.
 -- See Note [UnariseEnv]
 
 -- The id stands for itself so we don't record a mapping.
 -- See Note [UnariseEnv]
 extendRhoWithoutValue :: UnariseEnv -> Id -> UnariseEnv
-extendRhoWithoutValue rho x = delVarEnv rho x
+extendRhoWithoutValue env x = env { ue_rho = delVarEnv (ue_rho env) x }
 
+lookupRho :: UnariseEnv -> Id -> Maybe UnariseVal
+lookupRho env v = lookupVarEnv (ue_rho env) v
 
 --------------------------------------------------------------------------------
 
 unarise :: UniqSupply -> [StgTopBinding] -> [StgTopBinding]
-unarise us binds = initUs_ us (mapM (unariseTopBinding emptyVarEnv) binds)
+unarise us binds = initUs_ us (mapM (unariseTopBinding (initUnariseEnv emptyVarEnv)) binds)
 
 unariseTopBinding :: UnariseEnv -> StgTopBinding -> UniqSM StgTopBinding
 unariseTopBinding rho (StgTopLifted bind)
@@ -366,7 +408,7 @@ unariseRhs rho (StgRhsCon ccs con mu ts args)
 unariseExpr :: UnariseEnv -> StgExpr -> UniqSM StgExpr
 
 unariseExpr rho e@(StgApp f [])
-  = case lookupVarEnv rho f of
+  = case lookupRho rho f of
       Just (MultiVal args)  -- Including empty tuples
         -> return (mkTuple args)
       Just (UnaryVal (StgVarArg f'))
@@ -379,7 +421,7 @@ unariseExpr rho e@(StgApp f [])
 unariseExpr rho e@(StgApp f args)
   = return (StgApp f' (unariseFunArgs rho args))
   where
-    f' = case lookupVarEnv rho f of
+    f' = case lookupRho rho f of
            Just (UnaryVal (StgVarArg f')) -> f'
            Nothing -> f
            err -> pprPanic "unariseExpr - app2" (pprStgExpr panicStgPprOpts e $$ ppr err)
@@ -390,12 +432,17 @@ unariseExpr _ (StgLit l)
   = return (StgLit l)
 
 unariseExpr rho (StgConApp dc n args ty_args)
-  | Just args' <- unariseMulti_maybe rho dc args ty_args
-  = return (mkTuple args')
-
-  | otherwise
-  , let args' = unariseConArgs rho args
-  = return (StgConApp dc n args' (map stgArgType args'))
+  | isUnboxedSumDataCon dc || isUnboxedTupleDataCon dc
+  = do
+      us <- getUniqueSupplyM
+      case unariseUbxSumTupleArgs rho us dc args ty_args of
+        (args', Just cast_wrapper)
+          -> return $ cast_wrapper (mkTuple args')
+        (args', Nothing)
+          -> return $ (mkTuple args')
+  | otherwise =
+      let args' = unariseConArgs rho args in
+      return $ (StgConApp dc n args' (map stgArgType args'))
 
 unariseExpr rho (StgOpApp op args ty)
   = return (StgOpApp op (unariseFunArgs rho args) ty)
@@ -403,15 +450,19 @@ unariseExpr rho (StgOpApp op args ty)
 unariseExpr rho (StgCase scrut bndr alt_ty alts)
   -- tuple/sum binders in the scrutinee can always be eliminated
   | StgApp v [] <- scrut
-  , Just (MultiVal xs) <- lookupVarEnv rho v
+  , Just (MultiVal xs) <- lookupRho rho v
   = elimCase rho xs bndr alt_ty alts
 
   -- Handle strict lets for tuples and sums:
   --   case (# a,b #) of r -> rhs
   -- and analogously for sums
   | StgConApp dc _n args ty_args <- scrut
-  , Just args' <- unariseMulti_maybe rho dc args ty_args
-  = elimCase rho args' bndr alt_ty alts
+  , isUnboxedSumDataCon dc || isUnboxedTupleDataCon dc
+  = do
+    us <- getUniqueSupplyM
+    case unariseUbxSumTupleArgs rho us dc args ty_args of
+      (args',Just wrapper) -> wrapper <$> elimCase rho args' bndr alt_ty alts
+      (args',Nothing) -> elimCase rho args' bndr alt_ty alts
 
   -- See (3) of Note [Rubbish literals] in GHC.Types.Literal
   | StgLit lit <- scrut
@@ -436,17 +487,21 @@ unariseExpr rho (StgTick tick e)
   = StgTick tick <$> unariseExpr rho e
 
 -- Doesn't return void args.
-unariseMulti_maybe :: UnariseEnv -> DataCon -> [InStgArg] -> [Type] -> Maybe [OutStgArg]
-unariseMulti_maybe rho dc args ty_args
+unariseUbxSumTupleArgs :: UnariseEnv -> UniqSupply -> DataCon -> [InStgArg] -> [Type]
+                   -> ( [OutStgArg]           -- Arguments representing the unboxed sum
+                      , Maybe (StgExpr -> StgExpr)) -- Transformation to apply to the arguments, to bring them
+                                                    -- into the right Rep
+unariseUbxSumTupleArgs rho us dc args ty_args
   | isUnboxedTupleDataCon dc
-  = Just (unariseConArgs rho args)
+  = (unariseConArgs rho args, Nothing)
 
   | isUnboxedSumDataCon dc
   , let args1 = assert (isSingleton args) (unariseConArgs rho args)
-  = Just (mkUbxSum dc ty_args args1)
+  = let (args2, cast_wrapper) = mkUbxSum dc ty_args args1 us
+    in (args2, Just cast_wrapper)
 
   | otherwise
-  = Nothing
+  = panic "unariseUbxSumTupleArgs: Constructor not a unboxed sum or tuple"
 
 -- Doesn't return void args.
 unariseRubbish_maybe :: Literal -> Maybe [OutStgArg]
@@ -473,15 +528,15 @@ elimCase rho args bndr (MultiValAlt _) [GenStgAlt{ alt_con   = _
                                                  , alt_bndrs = bndrs
                                                  , alt_rhs   = rhs}]
   = do let rho1 = extendRho rho bndr (MultiVal args)
-           rho2
+           (rho2, rhs')
              | isUnboxedTupleBndr bndr
-             = mapTupleIdBinders bndrs args rho1
+             = (mapTupleIdBinders bndrs args rho1, rhs)
              | otherwise
              = assert (isUnboxedSumBndr bndr) $
-               if null bndrs then rho1
-                             else mapSumIdBinders bndrs args rho1
+               if null bndrs then (rho1, rhs)
+                             else mapSumIdBinders bndrs args rhs rho1
 
-       unariseExpr rho2 rhs
+       unariseExpr rho2 rhs'
 
 elimCase rho args bndr (MultiValAlt _) alts
   | isUnboxedSumBndr bndr
@@ -576,12 +631,12 @@ unariseSumAlt rho args GenStgAlt{ alt_con   = DataAlt sumCon
                                 , alt_bndrs = bs
                                 , alt_rhs   = e
                                 }
-  = do let rho'     = mapSumIdBinders bs args rho
-           lit_case = LitAlt (LitNumber LitNumInt (fromIntegral (dataConTag sumCon)))
-       GenStgAlt lit_case mempty <$> unariseExpr rho' e
+  = do let (rho',e')  = mapSumIdBinders bs args e rho
+           lit_case   = LitAlt (LitNumber LitNumInt (fromIntegral (dataConTag sumCon)))
+       GenStgAlt lit_case mempty <$> unariseExpr rho' e'
 
 unariseSumAlt _ scrt alt
-  = pprPanic "unariseSumAlt" (ppr scrt $$ pprPanicAlt alt)
+  = pprPanic "unariseSumAlt3" (ppr scrt $$ pprPanicAlt alt)
 
 --------------------------------------------------------------------------------
 
@@ -623,24 +678,80 @@ mapSumIdBinders
                  -- only have one binder, so this list should be a singleton)
   -> [OutStgArg] -- Arguments that form the sum (NOT including the tag).
                  -- Can't have void args.
+  -> InStgExpr
   -> UnariseEnv
-  -> UnariseEnv
+  -> (UnariseEnv, OutStgExpr)
 
-mapSumIdBinders [id] args rho0
+mapSumIdBinders [id] args rhs rho0
   = assert (not (any (isZeroBitTy . stgArgType) args)) $
     let
+      -- Slots representing the whole sum
       arg_slots = map primRepSlot $ concatMap (typePrimRep . stgArgType) args
+      -- The slots representing the field of the sum we bind.
       id_slots  = map primRepSlot $ typePrimRep (idType id)
       layout1   = layoutUbxSum arg_slots id_slots
+
+      -- Arg id's which make up the field.
+      id_arg_exprs   = [ args !! i | i <- layout1 ]
+      id_vars   = [v | StgVarArg v <- id_arg_exprs]
+
+      update_id_type v ty
+        | (typePrimRep $ idType v) == (typePrimRep ty) = v
+        | otherwise = setIdType v ty
+
+      -- rep-based types for the field binders
+      id_tys    = map primRepToType $ typePrimRep (idType id)
+      -- Arg id's with the typ set to one matching the fields rep.
+      typed_id_args = zipWithEqual "typed_id_args" (\var t -> StgVarArg (update_id_type var t)) id_vars id_tys
+      -- See Note [Casting slot arguments]
+      -- We can shadow the original argument id here since the binder for the field will only be used
+      -- at one specific type in this branch.
+      (rhs_with_casts) = foldr castArgShadow rhs $ zip id_vars id_tys
     in
+      pprTrace "mapSumIdBinders"
+                (text "id_tys" <+> ppr id_tys $$
+                text "id_args" <+> ppr id_arg_exprs $$
+                text "rhs" <+> ppr rhs $$
+                text "rhs_with_casts" <+> ppr rhs_with_casts
+                ) $
       if isMultiValBndr id
-        then extendRho rho0 id (MultiVal [ args !! i | i <- layout1 ])
-        else assert (layout1 `lengthIs` 1)
-             extendRho rho0 id (UnaryVal (args !! head layout1))
+        then (extendRho rho0 id (MultiVal typed_id_args), rhs_with_casts)
+        else assert (typed_id_args `lengthIs` 1)
+             (extendRho rho0 id (UnaryVal (head typed_id_args)), rhs_with_casts)
 
-mapSumIdBinders ids sum_args _
+mapSumIdBinders ids sum_args _rhs  _
   = pprPanic "mapSumIdBinders" (ppr ids $$ ppr sum_args)
 
+-- Convert the argument to the given type, and wrap the conversion
+-- around the given expression.
+castArgShadow :: (Id,Type) -> StgExpr -> StgExpr
+castArgShadow (arg, target_ty) (in_rhs) =
+  let ops = getCasts (typePrimRep1 $ idType arg) (typePrimRep1 target_ty)
+  in foldr (mkCast (StgVarArg arg) arg) (in_rhs) ops
+
+-- Convert the argument to the given type, and wrap the conversion
+-- around the given expression. Use the given Id as a name for the
+-- converted value.
+castArgRename :: StgArg -> Id -> StgExpr -> StgExpr
+castArgRename in_arg out_id in_rhs =
+  case ops of
+    [] -> in_rhs
+    op1:rest_ops ->
+      mkCast in_arg out_id op1 $
+        foldr (mkCast (StgVarArg out_id) out_id) in_rhs rest_ops
+  -- pprTrace "castArgRename" (ppr (in_arg,out_id)) $
+  where ops = getCasts (typePrimRep1 $ stgArgType in_arg) $ typePrimRep1 (idType out_id)
+  -- in foldr (mkCast in_arg out_id) (in_rhs) ops
+
+-- Variable to cast, (type to cast to, result_ty), rhs
+mkCast :: StgArg -> OutId -> (PrimOp,Type) -> (StgExpr) -> (StgExpr)
+mkCast arg_in out_id (cast_op,ty2) (in_rhs) =
+  let r2 = typePrimRep1 ty2
+      scrut = StgOpApp (StgPrimOp cast_op) [arg_in] ty2
+      alt = GenStgAlt { alt_con = DEFAULT, alt_bndrs = [], alt_rhs = in_rhs}
+      alt_ty = PrimAlt r2
+  in (StgCase scrut (setIdType out_id ty2) alt_ty [alt])
+
 -- | Build a unboxed sum term from arguments of an alternative.
 --
 -- Example, for (# x | #) :: (# (# #) | Int #) we call
@@ -655,8 +766,11 @@ mkUbxSum
   :: DataCon      -- Sum data con
   -> [Type]       -- Type arguments of the sum data con
   -> [OutStgArg]  -- Actual arguments of the alternative.
-  -> [OutStgArg]  -- Final tuple arguments
-mkUbxSum dc ty_args args0
+  -> UniqSupply
+  -> ([OutStgArg] -- Final tuple arguments
+     ,(StgExpr->StgExpr) -- We might need to cast the args first
+     )
+mkUbxSum dc ty_args args0 us
   = let
       (_ : sum_slots) = ubxSumRepType (map typePrimRep ty_args)
         -- drop tag slot
@@ -667,16 +781,51 @@ mkUbxSum dc ty_args args0
       tag_arg  = StgLitArg (LitNumber LitNumInt (fromIntegral tag))
       arg_idxs = IM.fromList (zipEqual "mkUbxSum" layout' args0)
 
-      mkTupArgs :: Int -> [SlotTy] -> IM.IntMap StgArg -> [StgArg]
-      mkTupArgs _ [] _
-        = []
-      mkTupArgs arg_idx (slot : slots_left) arg_map
-        | Just stg_arg <- IM.lookup arg_idx arg_map
-        = stg_arg : mkTupArgs (arg_idx + 1) slots_left arg_map
-        | otherwise
-        = ubxSumRubbishArg slot : mkTupArgs (arg_idx + 1) slots_left arg_map
+      ((_idx,_idx_map,_us,wrapper),slot_args)
+        = assert (length arg_idxs <= length sum_slots ) $
+          mapAccumL mkTupArg (0,arg_idxs,us,id) sum_slots
+
+      mkTupArg  :: (Int, IM.IntMap StgArg,UniqSupply,StgExpr->StgExpr)
+                -> SlotTy
+                -> ((Int,IM.IntMap StgArg,UniqSupply,StgExpr->StgExpr), StgArg)
+      mkTupArg (arg_idx, arg_map, us, wrapper) slot
+         | Just stg_arg <- IM.lookup arg_idx arg_map
+         =  case castArg us slot stg_arg of
+              Just (casted_arg,us',wrapper') ->
+                ( (arg_idx+1, arg_map, us', wrapper')
+                , casted_arg)
+              Nothing ->
+                ( (arg_idx+1, arg_map, us, wrapper)
+                , stg_arg)
+         | otherwise
+         =  ( (arg_idx+1, arg_map, us, wrapper)
+            , ubxSumRubbishArg slot)
+
+      castArg :: UniqSupply -> SlotTy -> StgArg -> Maybe (StgArg,UniqSupply,StgExpr -> StgExpr)
+      castArg us slot_ty arg
+        -- Cast the argument to the type of the slot if required
+        | slotPrimRep slot_ty /= typePrimRep1 (stgArgType arg)
+        = let (u1,us') = takeUniqFromSupply us
+              -- cast_ops = getCasts (typePrimRep1 $ idType arg_id) (slotPrimRep slot_ty)
+              out_ty =  primRepToType $ slotPrimRep slot_ty
+              out_name_fs
+                | (StgVarArg v_arg) <- arg
+                = getOccFS v_arg `appendFS` fsLit "_cst"
+                | otherwise = fsLit "cst_lit"
+              out_id = mkSysLocal out_name_fs u1 Many out_ty :: Id
+              casts = castArgRename arg out_id :: StgExpr -> StgExpr
+          in Just (arg,us',casts)
+        -- No need for casting
+        | otherwise = Nothing
+
+      tup_args = tag_arg : slot_args
     in
-      tag_arg : mkTupArgs 0 sum_slots arg_idxs
+      pprTrace "mkUbxSum" (
+        text "ty_args (slots)" <+> ppr ty_args $$
+        text "args0" <+> ppr args0 $$
+        text "wrapper" <+>
+            (ppr $ wrapper $ StgLit $ LitChar '_'))
+      (tup_args, wrapper)
 
 
 -- | Return a rubbish value for the given slot type.
@@ -787,7 +936,7 @@ unariseArgBinder is_con_arg rho x =
 -- | MultiVal a function argument. Never returns an empty list.
 unariseFunArg :: UnariseEnv -> StgArg -> [StgArg]
 unariseFunArg rho (StgVarArg x) =
-  case lookupVarEnv rho x of
+  case lookupRho rho x of
     Just (MultiVal [])  -> [voidArg]   -- NB: do not remove void args
     Just (MultiVal as)  -> as
     Just (UnaryVal arg) -> [arg]
@@ -809,7 +958,7 @@ unariseFunArgBinder = unariseArgBinder False
 -- | MultiVal a DataCon argument. Returns an empty list when argument is void.
 unariseConArg :: UnariseEnv -> InStgArg -> [OutStgArg]
 unariseConArg rho (StgVarArg x) =
-  case lookupVarEnv rho x of
+  case lookupRho rho x of
     Just (UnaryVal arg) -> [arg]
     Just (MultiVal as) -> as      -- 'as' can be empty
     Nothing


=====================================
compiler/GHC/Types/RepType.hs
=====================================
@@ -245,7 +245,8 @@ ubxSumRepType constrs0
     in
       sumRep
 
-layoutUbxSum :: SortedSlotTys -- Layout of sum. Does not include tag.
+layoutUbxSum :: HasDebugCallStack
+             => SortedSlotTys -- Layout of sum. Does not include tag.
                               -- We assume that they are in increasing order
              -> [SlotTy]      -- Slot types of things we want to map to locations in the
                               -- sum layout
@@ -268,7 +269,8 @@ layoutUbxSum sum_slots0 arg_slots0 =
       | otherwise
       = findSlot arg (slot_idx + 1) slots useds
     findSlot _ _ [] _
-      = pprPanic "findSlot" (text "Can't find slot" $$ ppr sum_slots0 $$ ppr arg_slots0)
+      = pprPanic "findSlot" (text "Can't find slot" $$ text "sum_slots:" <> ppr sum_slots0
+                                                    $$ text "arg_slots:" <> ppr arg_slots0 )
 
 --------------------------------------------------------------------------------
 


=====================================
compiler/GHC/Utils/Outputable.hs
=====================================
@@ -387,6 +387,7 @@ data SDocContext = SDC
   , sdocSuppressUniques             :: !Bool
   , sdocSuppressModulePrefixes      :: !Bool
   , sdocSuppressStgExts             :: !Bool
+  , sdocSuppressStgReps             :: !Bool
   , sdocErrorSpans                  :: !Bool
   , sdocStarIsType                  :: !Bool
   , sdocLinearTypes                 :: !Bool
@@ -447,6 +448,7 @@ defaultSDocContext = SDC
   , sdocSuppressUniques             = False
   , sdocSuppressModulePrefixes      = False
   , sdocSuppressStgExts             = False
+  , sdocSuppressStgReps             = True
   , sdocErrorSpans                  = False
   , sdocStarIsType                  = False
   , sdocLinearTypes                 = False


=====================================
compiler/ghc.cabal.in
=====================================
@@ -168,6 +168,7 @@ Library
         GHC.Builtin.Names
         GHC.Builtin.Names.TH
         GHC.Builtin.PrimOps
+        GHC.Builtin.PrimOps.Casts
         GHC.Builtin.PrimOps.Ids
         GHC.Builtin.Types
         GHC.Builtin.Types.Literals


=====================================
docs/users_guide/debugging.rst
=====================================
@@ -946,6 +946,16 @@ parts that you are not interested in.
 
     Suppress the printing of core size stats per binding
 
+.. ghc-flag:: -dsuppress-stg-reps
+    :shortdesc: Suppress rep annotations on STG args.
+    :type: dynamic
+
+    :since: 9.6.1
+
+    default: enabled
+
+    Disabling this will annoate certain stg arguments with their prim rep.
+
 
 .. _checking-consistency:
 


=====================================
testsuite/driver/testlib.py
=====================================
@@ -1447,7 +1447,8 @@ def compile_cmp_asm(name: TestName,
                     ext: str,
                     extra_hc_opts: str
                     ) -> PassFail:
-    print('Compile only, extra args = ', extra_hc_opts)
+    if extra_hc_opts:
+        print('Compile only, extra args = ', extra_hc_opts)
     result = simple_build(name + '.' + ext, way, '-keep-s-files -O ' + extra_hc_opts, False, None, [], False, False)
 
     if badResult(result):
@@ -1474,7 +1475,8 @@ def compile_grep_asm(name: TestName,
                      is_substring: bool,
                      extra_hc_opts: str
                      ) -> PassFail:
-    print('Compile only, extra args = ', extra_hc_opts)
+    if extra_hc_opts:
+        print('Compile and grep asm, extra args = ', extra_hc_opts)
     result = simple_build(name + '.' + ext, way, '-keep-s-files -O ' + extra_hc_opts, False, None, [], False, False)
 
     if badResult(result):
@@ -1495,7 +1497,8 @@ def compile_grep_core(name: TestName,
                       way: WayName,
                       extra_hc_opts: str
                       ) -> PassFail:
-    print('Compile only, extra args = ', extra_hc_opts)
+    if extra_hc_opts:
+        print('Compile only, extra args = ', extra_hc_opts)
     result = simple_build(name + '.hs', way, '-ddump-to-file -dsuppress-all -ddump-simpl -O ' + extra_hc_opts, False, None, [], False, False)
 
     if badResult(result):


=====================================
testsuite/tests/unboxedsums/GenManyUbxSums.hs
=====================================
@@ -0,0 +1,102 @@
+#!/usr/bin/env runghc
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnboxedTuples #-}
+{-# LANGUAGE UnboxedSums #-}
+
+-- This little piece of code constructs a large set of functions
+-- constructing and deconstructing unboxed tuples of various types.
+module Main where
+
+import GHC.Exts
+import System.IO
+
+inputs = ["Int", "Word"]
+sizes = ["","8","16","32","64"]
+
+-- ["Addr#","Int#","Int8#","Int16#","Int32#","Int64#","Word#","Word8#","Word16#","Word32#","Word64#"]
+types = "Addr#" : do
+    r <- inputs
+    s <- sizes
+    return $ r++s++"#"
+
+-- We eventually build two sums, one (# t1 | t2 #) and one (# t1 | t3).
+-- So build all the combinations here.
+combos = do
+    t1 <- types
+    t2 <- types
+    t3 <- types
+    return (t1,t2,t3)
+
+mkCon ty = case ty of
+    "Addr#" -> "Addr"
+    "Int#" -> "I#"
+    "Int8#" -> "I8#"
+    "Int16#" -> "I16#"
+    "Int32#" -> "I32#"
+    "Int64#" -> "I64#"
+    "Word#" -> "W#"
+    "Word8#" -> "W8#"
+    "Word16#" -> "W16#"
+    "Word32#" -> "W32#"
+    "Word64#" -> "W64#"
+
+-- Construct a function like the one below:
+-- {-# NOINLINE fun0 #-}
+-- fun0 :: (# Addr# | Addr# #) -> (# Addr# | Addr# #)
+-- fun0 x = case x of
+--   (# x1 | #) -> (# x1 | #) :: (# Addr# | Addr# #)
+mkFun n (t1,t2,t3) =
+    "{-# NOINLINE fun" ++ show n ++ " #-}\n" ++
+    "fun" ++ show n ++ " :: (# " ++ t1 ++" | " ++ t2 ++ " #) -> (# " ++ t1 ++" | " ++ t3 ++ " #)\n" ++
+    "fun" ++ show n ++ " x = case x of\n" ++
+    "  (# x1 | #) -> (# x1 | #) :: (# " ++ t1 ++ " | " ++ t3 ++ " #)"
+
+-- Generate functions for all the tuple combinations.
+mkFuns _ [] = ""
+mkFuns n (combo:combos) =
+    mkFun n combo ++ "\n" ++ mkFuns (n+1) combos
+
+-- generate a test that will put a value into a unboxed sum and then retrieve it later on.
+-- It generates code like the one below:
+-- test0 =
+--     let in_val = 0
+--         out_val = case in_val of I# x -> case fun0 (# x | #) of (# y | #) -> I# y
+--     in in_val == out_val
+mkTest n (t1,_,_)=
+    "test" ++ show n ++ " =\n" ++
+    "  let in_val = (maxBound)\n" ++
+    "      out_val = case in_val of " ++ mkCon t1 ++ " x -> case fun" ++ show n ++ " (# x | #) of (# y | #) -> " ++ mkCon t1 ++ " y\n" ++
+    "  in in_val == out_val"
+
+-- Test all the tuples
+mkTests n [] = ""
+mkTests n (combo:combos) =
+    mkTest n combo ++ "\n" ++ mkTests (n+1) combos
+
+
+header =
+    "{-# LANGUAGE MagicHash #-}\n\
+    \{-# LANGUAGE UnboxedTuples #-}\n\
+    \{-# LANGUAGE UnboxedSums #-}\n\
+    \module Main where\n\
+    \import GHC.Exts\n\
+    \import GHC.Word\n\
+    \import GHC.Int\n\
+    \import ManyUbxSums_Addr\n"
+main = do
+    out <- openFile "ManyUbxSums.hs" WriteMode
+    hPutStrLn out header
+
+    let combo:_ = combos
+    -- putStrLn $ mkFun 1 combo
+    hPutStrLn out $ mkFuns 0 combos
+
+    hPutStrLn out $ mkTests 0 combos
+    hPutStrLn out "main = do"
+
+    -- Actually invoke all the tests
+    let runTest n =
+            hPutStrLn out $ "  putStrLn $ \"test" ++ show n ++ " \" ++ (show test" ++ show n ++ ")"
+    mapM runTest [0 .. length combos - 1]
+
+    hClose out


=====================================
testsuite/tests/unboxedsums/ManyUbxSums_Addr.debug.dump-cmm
=====================================
@@ -0,0 +1,862 @@
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.810321346 UTC
+
+[section ""cstring" . $tc'Addr1_rYK_bytes" {
+     $tc'Addr1_rYK_bytes:
+         I8[] "'Addr"
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.810616005 UTC
+
+[section ""cstring" . $tcAddr1_rYG_bytes" {
+     $tcAddr1_rYG_bytes:
+         I8[] "Addr"
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.810861345 UTC
+
+[section ""cstring" . $trModule3_rYD_bytes" {
+     $trModule3_rYD_bytes:
+         I8[] "ManyUbxSums_Addr"
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.811117863 UTC
+
+[section ""cstring" . $trModule1_rYB_bytes" {
+     $trModule1_rYB_bytes:
+         I8[] "main"
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.812887827 UTC
+
+[section ""cstring" . c125_str" {
+     c125_str:
+         I8[] "testsuite/tests/unboxedsums/ManyUbxSums_Addr.hs:(15,28)-(17,17)|case"
+ },
+ $c==_rYq_entry() { //  [R3, R2]
+         { info_tbls: [(c11N,
+                        label: block_c11N_info
+                        rep: StackRep [False]
+                        srt: Just Control.Exception.Base.patError_closure),
+                       (c11Q,
+                        label: $c==_rYq_info
+                        rep: HeapRep static { Fun {arity: 2 fun_type: ArgSpec 15} }
+                        srt: Just Control.Exception.Base.patError_closure),
+                       (c11T,
+                        label: block_c11T_info
+                        rep: StackRep [True]
+                        srt: Just Control.Exception.Base.patError_closure)]
+           stack_info: arg_space: 8
+         }
+     {offset
+       c11Q: // global
+           _s11k::P64 = R3;   // CmmAssign
+           _s11j::P64 = R2;   // CmmAssign
+           if ((Sp + 8) - 24 < SpLim) (likely: False) goto c11U; else goto c11V;   // CmmCondBranch
+       c11U: // global
+           R3 = _s11k::P64;   // CmmAssign
+           R2 = _s11j::P64;   // CmmAssign
+           R1 = $c==_rYq_closure;   // CmmAssign
+           call (stg_gc_fun)(R3, R2, R1) args: 8, res: 0, upd: 8;   // CmmCall
+       c11V: // global
+           I64[Sp - 16] = c11N;   // CmmStore
+           R1 = _s11j::P64;   // CmmAssign
+           P64[Sp - 8] = _s11k::P64;   // CmmStore
+           Sp = Sp - 16;   // CmmAssign
+           if (R1 & 7 != 0) goto c11N; else goto c11O;   // CmmCondBranch
+       c11O: // global
+           call (I64[R1])(R1) returns to c11N, args: 8, res: 8, upd: 8;   // CmmCall
+       c11N: // global
+           _s11k::P64 = P64[Sp + 8];   // CmmAssign
+           _s11l::P64 = R1;   // CmmAssign
+           _s11m::I64 = I64[_s11l::P64 + 7];   // CmmAssign
+           I64[Sp] = c11T;   // CmmStore
+           R1 = _s11k::P64;   // CmmAssign
+           I64[Sp + 8] = _s11m::I64;   // CmmStore
+           if (R1 & 7 != 0) goto c11T; else goto c11X;   // CmmCondBranch
+       c11X: // global
+           call (I64[R1])(R1) returns to c11T, args: 8, res: 8, upd: 8;   // CmmCall
+       c11T: // global
+           _s11m::I64 = I64[Sp + 8];   // CmmAssign
+           _s11n::P64 = R1;   // CmmAssign
+           _s11o::I64 = I64[_s11n::P64 + 7];   // CmmAssign
+           _c122::I64 = _s11m::I64 == _s11o::I64;   // CmmAssign
+           _s11p::I64 = _c122::I64;   // CmmAssign
+           if (_s11p::I64 != 0) goto u12a; else goto c128;   // CmmCondBranch
+       u12a: // global
+           if (_s11p::I64 != 1) goto c127; else goto c129;   // CmmCondBranch
+       c127: // global
+           R2 = c125_str;   // CmmAssign
+           Sp = Sp + 16;   // CmmAssign
+           call Control.Exception.Base.patError_info(R2) args: 8, res: 0, upd: 8;   // CmmCall
+       c129: // global
+           R1 = GHC.Types.True_closure+2;   // CmmAssign
+           Sp = Sp + 16;   // CmmAssign
+           call (P64[Sp])(R1) args: 8, res: 0, upd: 8;   // CmmCall
+       c128: // global
+           R1 = GHC.Types.False_closure+1;   // CmmAssign
+           Sp = Sp + 16;   // CmmAssign
+           call (P64[Sp])(R1) args: 8, res: 0, upd: 8;   // CmmCall
+     }
+ },
+ section ""data" . $c==_rYq_closure" {
+     $c==_rYq_closure:
+         const $c==_rYq_info;
+         const 0;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.817425012 UTC
+
+[$c/=_rYr_entry() { //  [R3, R2]
+         { info_tbls: [(c12l,
+                        label: block_c12l_info
+                        rep: StackRep []
+                        srt: Nothing),
+                       (c12r,
+                        label: $c/=_rYr_info
+                        rep: HeapRep static { Fun {arity: 2 fun_type: ArgSpec 15} }
+                        srt: Just $c==_rYq_closure)]
+           stack_info: arg_space: 8
+         }
+     {offset
+       c12r: // global
+           _s11r::P64 = R3;   // CmmAssign
+           _s11q::P64 = R2;   // CmmAssign
+           if ((Sp + 8) - 16 < SpLim) (likely: False) goto c12s; else goto c12t;   // CmmCondBranch
+       c12s: // global
+           R3 = _s11r::P64;   // CmmAssign
+           R2 = _s11q::P64;   // CmmAssign
+           R1 = $c/=_rYr_closure;   // CmmAssign
+           call (stg_gc_fun)(R3, R2, R1) args: 8, res: 0, upd: 8;   // CmmCall
+       c12t: // global
+           I64[Sp - 8] = c12l;   // CmmStore
+           R3 = _s11r::P64;   // CmmAssign
+           R2 = _s11q::P64;   // CmmAssign
+           Sp = Sp - 8;   // CmmAssign
+           call $c==_rYq_info(R3,
+                              R2) returns to c12l, args: 8, res: 8, upd: 8;   // CmmCall
+       c12l: // global
+           _s11s::P64 = R1;   // CmmAssign
+           _c12q::P64 = _s11s::P64 & 7;   // CmmAssign
+           if (_c12q::P64 != 1) goto c12p; else goto c12o;   // CmmCondBranch
+       c12p: // global
+           R1 = GHC.Types.False_closure+1;   // CmmAssign
+           Sp = Sp + 8;   // CmmAssign
+           call (P64[Sp])(R1) args: 8, res: 0, upd: 8;   // CmmCall
+       c12o: // global
+           R1 = GHC.Types.True_closure+2;   // CmmAssign
+           Sp = Sp + 8;   // CmmAssign
+           call (P64[Sp])(R1) args: 8, res: 0, upd: 8;   // CmmCall
+     }
+ },
+ section ""data" . $c/=_rYr_closure" {
+     $c/=_rYr_closure:
+         const $c/=_rYr_info;
+         const 0;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.819847978 UTC
+
+[section ""data" . ManyUbxSums_Addr.$fEqAddr_closure" {
+     ManyUbxSums_Addr.$fEqAddr_closure:
+         const GHC.Classes.C:Eq_con_info;
+         const $c==_rYq_closure+2;
+         const $c/=_rYr_closure+2;
+         const 0;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.820914267 UTC
+
+[$cfromInteger_rYs_entry() { //  [R2]
+         { info_tbls: [(c12K,
+                        label: block_c12K_info
+                        rep: StackRep []
+                        srt: Nothing),
+                       (c12M,
+                        label: $cfromInteger_rYs_info
+                        rep: HeapRep static { Fun {arity: 1 fun_type: ArgSpec 5} }
+                        srt: Nothing)]
+           stack_info: arg_space: 8
+         }
+     {offset
+       c12M: // global
+           _s11t::P64 = R2;   // CmmAssign
+           if ((Sp + 8) - 16 < SpLim) (likely: False) goto c12T; else goto c12U;   // CmmCondBranch
+       c12T: // global
+           R2 = _s11t::P64;   // CmmAssign
+           R1 = $cfromInteger_rYs_closure;   // CmmAssign
+           call (stg_gc_fun)(R2, R1) args: 8, res: 0, upd: 8;   // CmmCall
+       c12U: // global
+           // slowCall
+           I64[Sp - 8] = c12K;   // CmmStore
+           R4 = _s11t::P64;   // CmmAssign
+           R3 = GHC.Num.$fNumInt_closure;   // CmmAssign
+           R2 = GHC.Real.$fIntegralInteger_closure;   // CmmAssign
+           R1 = GHC.Real.fromIntegral_closure;   // CmmAssign
+           Sp = Sp - 8;   // CmmAssign
+           call stg_ap_ppp_fast(R4,
+                                R3,
+                                R2,
+                                R1) returns to c12K, args: 8, res: 8, upd: 8;   // CmmCall
+       c12K: // global
+           _s11u::P64 = R1;   // CmmAssign
+           // slow_call for fromIntegral_closure with pat stg_ap_ppp
+           Hp = Hp + 16;   // CmmAssign
+           if (Hp > HpLim) (likely: False) goto c12X; else goto c12W;   // CmmCondBranch
+       c12X: // global
+           HpAlloc = 16;   // CmmAssign
+           R1 = _s11u::P64;   // CmmAssign
+           call stg_gc_unpt_r1(R1) returns to c12K, args: 8, res: 8, upd: 8;   // CmmCall
+       c12W: // global
+           _s11v::I64 = I64[_s11u::P64 + 7];   // CmmAssign
+           _c12P::I64 = _s11v::I64;   // CmmAssign
+           _s11w::I64 = _c12P::I64;   // CmmAssign
+           // allocHeapClosure
+           I64[Hp - 8] = ManyUbxSums_Addr.Addr_con_info;   // CmmStore
+           I64[Hp] = _s11w::I64;   // CmmStore
+           _c12S::P64 = Hp - 7;   // CmmAssign
+           R1 = _c12S::P64;   // CmmAssign
+           Sp = Sp + 8;   // CmmAssign
+           call (P64[Sp])(R1) args: 8, res: 0, upd: 8;   // CmmCall
+     }
+ },
+ section ""data" . $cfromInteger_rYs_closure" {
+     $cfromInteger_rYs_closure:
+         const $cfromInteger_rYs_info;
+         const GHC.Real.fromIntegral_closure;
+         const GHC.Num.$fNumInt_closure;
+         const GHC.Real.$fIntegralInteger_closure;
+         const 0;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.824020462 UTC
+
+[section ""cstring" . c138_str" {
+     c138_str:
+         I8[] "testsuite/tests/unboxedsums/ManyUbxSums_Addr.hs:19:10-17|signum"
+ },
+ $csignum_rYt_entry() { //  [R1]
+         { info_tbls: [(c139,
+                        label: $csignum_rYt_info
+                        rep: HeapRep static { Thunk }
+                        srt: Just Control.Exception.Base.noMethodBindingError_closure)]
+           stack_info: arg_space: 8
+         }
+     {offset
+       c139: // global
+           _rYt::P64 = R1;   // CmmAssign
+           if ((Sp + 8) - 24 < SpLim) (likely: False) goto c13a; else goto c13b;   // CmmCondBranch
+       c13a: // global
+           R1 = _rYt::P64;   // CmmAssign
+           call (stg_gc_enter_1)(R1) args: 8, res: 0, upd: 8;   // CmmCall
+       c13b: // global
+           (_c135::I64) = call "ccall" arg hints:  [PtrHint,
+                                                    PtrHint]  result hints:  [PtrHint] newCAF(BaseReg, _rYt::P64);   // CmmUnsafeForeignCall
+           if (_c135::I64 == 0) goto c137; else goto c136;   // CmmCondBranch
+       c137: // global
+           call (I64[_rYt::P64])() args: 8, res: 0, upd: 8;   // CmmCall
+       c136: // global
+           I64[Sp - 16] = stg_bh_upd_frame_info;   // CmmStore
+           I64[Sp - 8] = _c135::I64;   // CmmStore
+           R2 = c138_str;   // CmmAssign
+           Sp = Sp - 16;   // CmmAssign
+           call Control.Exception.Base.noMethodBindingError_info(R2) args: 24, res: 0, upd: 24;   // CmmCall
+     }
+ },
+ section ""data" . $csignum_rYt_closure" {
+     $csignum_rYt_closure:
+         const $csignum_rYt_info;
+         const 0;
+         const 0;
+         const 0;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.826774229 UTC
+
+[section ""cstring" . c13o_str" {
+     c13o_str:
+         I8[] "testsuite/tests/unboxedsums/ManyUbxSums_Addr.hs:19:10-17|abs"
+ },
+ $cabs_rYu_entry() { //  [R1]
+         { info_tbls: [(c13p,
+                        label: $cabs_rYu_info
+                        rep: HeapRep static { Thunk }
+                        srt: Just Control.Exception.Base.noMethodBindingError_closure)]
+           stack_info: arg_space: 8
+         }
+     {offset
+       c13p: // global
+           _rYu::P64 = R1;   // CmmAssign
+           if ((Sp + 8) - 24 < SpLim) (likely: False) goto c13q; else goto c13r;   // CmmCondBranch
+       c13q: // global
+           R1 = _rYu::P64;   // CmmAssign
+           call (stg_gc_enter_1)(R1) args: 8, res: 0, upd: 8;   // CmmCall
+       c13r: // global
+           (_c13l::I64) = call "ccall" arg hints:  [PtrHint,
+                                                    PtrHint]  result hints:  [PtrHint] newCAF(BaseReg, _rYu::P64);   // CmmUnsafeForeignCall
+           if (_c13l::I64 == 0) goto c13n; else goto c13m;   // CmmCondBranch
+       c13n: // global
+           call (I64[_rYu::P64])() args: 8, res: 0, upd: 8;   // CmmCall
+       c13m: // global
+           I64[Sp - 16] = stg_bh_upd_frame_info;   // CmmStore
+           I64[Sp - 8] = _c13l::I64;   // CmmStore
+           R2 = c13o_str;   // CmmAssign
+           Sp = Sp - 16;   // CmmAssign
+           call Control.Exception.Base.noMethodBindingError_info(R2) args: 24, res: 0, upd: 24;   // CmmCall
+     }
+ },
+ section ""data" . $cabs_rYu_closure" {
+     $cabs_rYu_closure:
+         const $cabs_rYu_info;
+         const 0;
+         const 0;
+         const 0;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.829072883 UTC
+
+[section ""cstring" . c13E_str" {
+     c13E_str:
+         I8[] "testsuite/tests/unboxedsums/ManyUbxSums_Addr.hs:19:10-17|*"
+ },
+ $c*_rYv_entry() { //  [R1]
+         { info_tbls: [(c13F,
+                        label: $c*_rYv_info
+                        rep: HeapRep static { Thunk }
+                        srt: Just Control.Exception.Base.noMethodBindingError_closure)]
+           stack_info: arg_space: 8
+         }
+     {offset
+       c13F: // global
+           _rYv::P64 = R1;   // CmmAssign
+           if ((Sp + 8) - 24 < SpLim) (likely: False) goto c13G; else goto c13H;   // CmmCondBranch
+       c13G: // global
+           R1 = _rYv::P64;   // CmmAssign
+           call (stg_gc_enter_1)(R1) args: 8, res: 0, upd: 8;   // CmmCall
+       c13H: // global
+           (_c13B::I64) = call "ccall" arg hints:  [PtrHint,
+                                                    PtrHint]  result hints:  [PtrHint] newCAF(BaseReg, _rYv::P64);   // CmmUnsafeForeignCall
+           if (_c13B::I64 == 0) goto c13D; else goto c13C;   // CmmCondBranch
+       c13D: // global
+           call (I64[_rYv::P64])() args: 8, res: 0, upd: 8;   // CmmCall
+       c13C: // global
+           I64[Sp - 16] = stg_bh_upd_frame_info;   // CmmStore
+           I64[Sp - 8] = _c13B::I64;   // CmmStore
+           R2 = c13E_str;   // CmmAssign
+           Sp = Sp - 16;   // CmmAssign
+           call Control.Exception.Base.noMethodBindingError_info(R2) args: 24, res: 0, upd: 24;   // CmmCall
+     }
+ },
+ section ""data" . $c*_rYv_closure" {
+     $c*_rYv_closure:
+         const $c*_rYv_info;
+         const 0;
+         const 0;
+         const 0;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.831813755 UTC
+
+[section ""cstring" . c13U_str" {
+     c13U_str:
+         I8[] "testsuite/tests/unboxedsums/ManyUbxSums_Addr.hs:19:10-17|+"
+ },
+ $c+_rYw_entry() { //  [R1]
+         { info_tbls: [(c13V,
+                        label: $c+_rYw_info
+                        rep: HeapRep static { Thunk }
+                        srt: Just Control.Exception.Base.noMethodBindingError_closure)]
+           stack_info: arg_space: 8
+         }
+     {offset
+       c13V: // global
+           _rYw::P64 = R1;   // CmmAssign
+           if ((Sp + 8) - 24 < SpLim) (likely: False) goto c13W; else goto c13X;   // CmmCondBranch
+       c13W: // global
+           R1 = _rYw::P64;   // CmmAssign
+           call (stg_gc_enter_1)(R1) args: 8, res: 0, upd: 8;   // CmmCall
+       c13X: // global
+           (_c13R::I64) = call "ccall" arg hints:  [PtrHint,
+                                                    PtrHint]  result hints:  [PtrHint] newCAF(BaseReg, _rYw::P64);   // CmmUnsafeForeignCall
+           if (_c13R::I64 == 0) goto c13T; else goto c13S;   // CmmCondBranch
+       c13T: // global
+           call (I64[_rYw::P64])() args: 8, res: 0, upd: 8;   // CmmCall
+       c13S: // global
+           I64[Sp - 16] = stg_bh_upd_frame_info;   // CmmStore
+           I64[Sp - 8] = _c13R::I64;   // CmmStore
+           R2 = c13U_str;   // CmmAssign
+           Sp = Sp - 16;   // CmmAssign
+           call Control.Exception.Base.noMethodBindingError_info(R2) args: 24, res: 0, upd: 24;   // CmmCall
+     }
+ },
+ section ""data" . $c+_rYw_closure" {
+     $c+_rYw_closure:
+         const $c+_rYw_info;
+         const 0;
+         const 0;
+         const 0;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.834378646 UTC
+
+[$c-_rYx_entry() { //  [R3, R2]
+         { info_tbls: [(c148,
+                        label: $c-_rYx_info
+                        rep: HeapRep static { Fun {arity: 2 fun_type: ArgSpec 15} }
+                        srt: Just $c+_rYw_closure)]
+           stack_info: arg_space: 8
+         }
+     {offset
+       c148: // global
+           _s11y::P64 = R3;   // CmmAssign
+           _s11x::P64 = R2;   // CmmAssign
+           goto c14a;   // CmmBranch
+       c14a: // global
+           // slowCall
+           R1 = $c+_rYw_closure;   // CmmAssign
+           call stg_ap_0_fast(R1) args: 8, res: 0, upd: 8;   // CmmCall
+     }
+ },
+ section ""data" . $c-_rYx_closure" {
+     $c-_rYx_closure:
+         const $c-_rYx_info;
+         const 0;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.835499478 UTC
+
+[$cnegate_rYy_entry() { //  [R2]
+         { info_tbls: [(c14i,
+                        label: $cnegate_rYy_info
+                        rep: HeapRep static { Fun {arity: 1 fun_type: ArgSpec 5} }
+                        srt: Just $c+_rYw_closure)]
+           stack_info: arg_space: 8
+         }
+     {offset
+       c14i: // global
+           _s11z::P64 = R2;   // CmmAssign
+           goto c14k;   // CmmBranch
+       c14k: // global
+           // slowCall
+           R1 = $c+_rYw_closure;   // CmmAssign
+           call stg_ap_0_fast(R1) args: 8, res: 0, upd: 8;   // CmmCall
+     }
+ },
+ section ""data" . $cnegate_rYy_closure" {
+     $cnegate_rYy_closure:
+         const $cnegate_rYy_info;
+         const 0;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.836410662 UTC
+
+[section ""data" . ManyUbxSums_Addr.$fNumAddr_closure" {
+     ManyUbxSums_Addr.$fNumAddr_closure:
+         const GHC.Num.C:Num_con_info;
+         const $c+_rYw_closure;
+         const $c-_rYx_closure+2;
+         const $c*_rYv_closure;
+         const $cnegate_rYy_closure+1;
+         const $cabs_rYu_closure;
+         const $csignum_rYt_closure;
+         const $cfromInteger_rYs_closure+1;
+         const 0;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.83761474 UTC
+
+[sat_s11A_entry() { //  [R1]
+         { info_tbls: [(c14v,
+                        label: sat_s11A_info
+                        rep: HeapRep static { Thunk }
+                        srt: Just GHC.Enum.$fBoundedWord_closure)]
+           stack_info: arg_space: 8
+         }
+     {offset
+       c14v: // global
+           _s11A::P64 = R1;   // CmmAssign
+           if ((Sp + 8) - 24 < SpLim) (likely: False) goto c14w; else goto c14x;   // CmmCondBranch
+       c14w: // global
+           R1 = _s11A::P64;   // CmmAssign
+           call (stg_gc_enter_1)(R1) args: 8, res: 0, upd: 8;   // CmmCall
+       c14x: // global
+           (_c14s::I64) = call "ccall" arg hints:  [PtrHint,
+                                                    PtrHint]  result hints:  [PtrHint] newCAF(BaseReg, _s11A::P64);   // CmmUnsafeForeignCall
+           if (_c14s::I64 == 0) goto c14u; else goto c14t;   // CmmCondBranch
+       c14u: // global
+           call (I64[_s11A::P64])() args: 8, res: 0, upd: 8;   // CmmCall
+       c14t: // global
+           I64[Sp - 16] = stg_bh_upd_frame_info;   // CmmStore
+           I64[Sp - 8] = _c14s::I64;   // CmmStore
+           R2 = GHC.Enum.$fBoundedWord_closure;   // CmmAssign
+           Sp = Sp - 16;   // CmmAssign
+           call GHC.Enum.maxBound_info(R2) args: 24, res: 0, upd: 24;   // CmmCall
+     }
+ },
+ section ""data" . sat_s11A_closure" {
+     sat_s11A_closure:
+         const sat_s11A_info;
+         const 0;
+         const 0;
+         const 0;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.839820084 UTC
+
+[section ""data" . _u14M_srt" {
+     _u14M_srt:
+         const stg_SRT_4_info;
+         const GHC.Real.fromIntegral_closure;
+         const ManyUbxSums_Addr.$fNumAddr_closure;
+         const GHC.Real.$fIntegralWord_closure;
+         const sat_s11A_closure;
+         const 0;
+ },
+ $cmaxBound_rYz_entry() { //  [R1]
+         { info_tbls: [(c14J,
+                        label: $cmaxBound_rYz_info
+                        rep: HeapRep static { Thunk }
+                        srt: Just _u14M_srt)]
+           stack_info: arg_space: 8
+         }
+     {offset
+       c14J: // global
+           _rYz::P64 = R1;   // CmmAssign
+           if ((Sp + 8) - 24 < SpLim) (likely: False) goto c14K; else goto c14L;   // CmmCondBranch
+       c14K: // global
+           R1 = _rYz::P64;   // CmmAssign
+           call (stg_gc_enter_1)(R1) args: 8, res: 0, upd: 8;   // CmmCall
+       c14L: // global
+           (_c14G::I64) = call "ccall" arg hints:  [PtrHint,
+                                                    PtrHint]  result hints:  [PtrHint] newCAF(BaseReg, _rYz::P64);   // CmmUnsafeForeignCall
+           if (_c14G::I64 == 0) goto c14I; else goto c14H;   // CmmCondBranch
+       c14I: // global
+           call (I64[_rYz::P64])() args: 8, res: 0, upd: 8;   // CmmCall
+       c14H: // global
+           I64[Sp - 16] = stg_bh_upd_frame_info;   // CmmStore
+           I64[Sp - 8] = _c14G::I64;   // CmmStore
+           // slowCall
+           R4 = sat_s11A_closure;   // CmmAssign
+           R3 = ManyUbxSums_Addr.$fNumAddr_closure+1;   // CmmAssign
+           R2 = GHC.Real.$fIntegralWord_closure;   // CmmAssign
+           R1 = GHC.Real.fromIntegral_closure;   // CmmAssign
+           Sp = Sp - 16;   // CmmAssign
+           call stg_ap_ppp_fast(R4,
+                                R3,
+                                R2,
+                                R1) args: 24, res: 0, upd: 24;   // CmmCall
+     }
+ },
+ section ""data" . $cmaxBound_rYz_closure" {
+     $cmaxBound_rYz_closure:
+         const $cmaxBound_rYz_info;
+         const 0;
+         const 0;
+         const 0;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.842334183 UTC
+
+[section ""data" . sat_s11B_closure" {
+     sat_s11B_closure:
+         const GHC.Num.Integer.IS_con_info;
+         const 0;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.843430423 UTC
+
+[$cminBound_rYA_entry() { //  [R1]
+         { info_tbls: [(c150,
+                        label: block_c150_info
+                        rep: StackRep []
+                        srt: Nothing),
+                       (c152,
+                        label: $cminBound_rYA_info
+                        rep: HeapRep static { Thunk }
+                        srt: Just $cfromInteger_rYs_closure)]
+           stack_info: arg_space: 8
+         }
+     {offset
+       c152: // global
+           _rYA::P64 = R1;   // CmmAssign
+           if ((Sp + 8) - 32 < SpLim) (likely: False) goto c159; else goto c15a;   // CmmCondBranch
+       c159: // global
+           R1 = _rYA::P64;   // CmmAssign
+           call (stg_gc_enter_1)(R1) args: 8, res: 0, upd: 8;   // CmmCall
+       c15a: // global
+           (_c14X::I64) = call "ccall" arg hints:  [PtrHint,
+                                                    PtrHint]  result hints:  [PtrHint] newCAF(BaseReg, _rYA::P64);   // CmmUnsafeForeignCall
+           if (_c14X::I64 == 0) goto c14Z; else goto c14Y;   // CmmCondBranch
+       c14Z: // global
+           call (I64[_rYA::P64])() args: 8, res: 0, upd: 8;   // CmmCall
+       c14Y: // global
+           I64[Sp - 16] = stg_bh_upd_frame_info;   // CmmStore
+           I64[Sp - 8] = _c14X::I64;   // CmmStore
+           // slowCall
+           I64[Sp - 24] = c150;   // CmmStore
+           R4 = sat_s11B_closure+1;   // CmmAssign
+           R3 = GHC.Num.$fNumInt_closure;   // CmmAssign
+           R2 = GHC.Real.$fIntegralInteger_closure;   // CmmAssign
+           R1 = GHC.Real.fromIntegral_closure;   // CmmAssign
+           Sp = Sp - 24;   // CmmAssign
+           call stg_ap_ppp_fast(R4,
+                                R3,
+                                R2,
+                                R1) returns to c150, args: 8, res: 8, upd: 24;   // CmmCall
+       c150: // global
+           _s11C::P64 = R1;   // CmmAssign
+           // slow_call for fromIntegral_closure with pat stg_ap_ppp
+           Hp = Hp + 16;   // CmmAssign
+           if (Hp > HpLim) (likely: False) goto c15d; else goto c15c;   // CmmCondBranch
+       c15d: // global
+           HpAlloc = 16;   // CmmAssign
+           R1 = _s11C::P64;   // CmmAssign
+           call stg_gc_unpt_r1(R1) returns to c150, args: 8, res: 8, upd: 24;   // CmmCall
+       c15c: // global
+           _s11D::I64 = I64[_s11C::P64 + 7];   // CmmAssign
+           _c155::I64 = _s11D::I64;   // CmmAssign
+           _s11E::I64 = _c155::I64;   // CmmAssign
+           // allocHeapClosure
+           I64[Hp - 8] = ManyUbxSums_Addr.Addr_con_info;   // CmmStore
+           I64[Hp] = _s11E::I64;   // CmmStore
+           _c158::P64 = Hp - 7;   // CmmAssign
+           R1 = _c158::P64;   // CmmAssign
+           Sp = Sp + 8;   // CmmAssign
+           call (P64[Sp])(R1) args: 24, res: 0, upd: 24;   // CmmCall
+     }
+ },
+ section ""data" . $cminBound_rYA_closure" {
+     $cminBound_rYA_closure:
+         const $cminBound_rYA_info;
+         const 0;
+         const 0;
+         const 0;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.846850897 UTC
+
+[section ""data" . ManyUbxSums_Addr.$fBoundedAddr_closure" {
+     ManyUbxSums_Addr.$fBoundedAddr_closure:
+         const GHC.Enum.C:Bounded_con_info;
+         const $cminBound_rYA_closure;
+         const $cmaxBound_rYz_closure;
+         const 0;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.847227811 UTC
+
+[section ""data" . $trModule2_rYC_closure" {
+     $trModule2_rYC_closure:
+         const GHC.Types.TrNameS_con_info;
+         const $trModule1_rYB_bytes;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.847546537 UTC
+
+[section ""data" . $trModule4_rYE_closure" {
+     $trModule4_rYE_closure:
+         const GHC.Types.TrNameS_con_info;
+         const $trModule3_rYD_bytes;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.847875476 UTC
+
+[section ""data" . ManyUbxSums_Addr.$trModule_closure" {
+     ManyUbxSums_Addr.$trModule_closure:
+         const GHC.Types.Module_con_info;
+         const $trModule2_rYC_closure+1;
+         const $trModule4_rYE_closure+1;
+         const 3;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.848609602 UTC
+
+[section ""data" . $krep_rYF_closure" {
+     $krep_rYF_closure:
+         const GHC.Types.KindRepTyConApp_con_info;
+         const GHC.Types.$tcAddr#_closure;
+         const GHC.Types.[]_closure+1;
+         const 0;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.8489625 UTC
+
+[section ""data" . $tcAddr2_rYH_closure" {
+     $tcAddr2_rYH_closure:
+         const GHC.Types.TrNameS_con_info;
+         const $tcAddr1_rYG_bytes;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.849319124 UTC
+
+[section ""data" . ManyUbxSums_Addr.$tcAddr_closure" {
+     ManyUbxSums_Addr.$tcAddr_closure:
+         const GHC.Types.TyCon_con_info;
+         const ManyUbxSums_Addr.$trModule_closure+1;
+         const $tcAddr2_rYH_closure+1;
+         const GHC.Types.krep$*_closure;
+         const 4790135393693416043;
+         const 4509054882010932911;
+         const 0;
+         const 0;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.849776569 UTC
+
+[section ""data" . $krep1_rYI_closure" {
+     $krep1_rYI_closure:
+         const GHC.Types.KindRepTyConApp_con_info;
+         const ManyUbxSums_Addr.$tcAddr_closure+1;
+         const GHC.Types.[]_closure+1;
+         const 0;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.850145038 UTC
+
+[section ""data" . $krep2_rYJ_closure" {
+     $krep2_rYJ_closure:
+         const GHC.Types.KindRepFun_con_info;
+         const $krep_rYF_closure+1;
+         const $krep1_rYI_closure+1;
+         const 0;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.850499273 UTC
+
+[section ""data" . $tc'Addr2_rYL_closure" {
+     $tc'Addr2_rYL_closure:
+         const GHC.Types.TrNameS_con_info;
+         const $tc'Addr1_rYK_bytes;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.850843839 UTC
+
+[section ""data" . ManyUbxSums_Addr.$tc'Addr_closure" {
+     ManyUbxSums_Addr.$tc'Addr_closure:
+         const GHC.Types.TyCon_con_info;
+         const ManyUbxSums_Addr.$trModule_closure+1;
+         const $tc'Addr2_rYL_closure+1;
+         const $krep2_rYJ_closure+4;
+         const 15766329447734056695;
+         const 3176921173291726962;
+         const 0;
+         const 0;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.851681093 UTC
+
+[ManyUbxSums_Addr.Addr_entry() { //  [R2]
+         { info_tbls: [(c15z,
+                        label: ManyUbxSums_Addr.Addr_info
+                        rep: HeapRep static { Fun {arity: 1 fun_type: ArgSpec 4} }
+                        srt: Nothing)]
+           stack_info: arg_space: 8
+         }
+     {offset
+       c15z: // global
+           _B0::I64 = R2;   // CmmAssign
+           goto c15B;   // CmmBranch
+       c15B: // global
+           Hp = Hp + 16;   // CmmAssign
+           if (Hp > HpLim) (likely: False) goto c15D; else goto c15C;   // CmmCondBranch
+       c15D: // global
+           HpAlloc = 16;   // CmmAssign
+           goto c15A;   // CmmBranch
+       c15A: // global
+           R2 = _B0::I64;   // CmmAssign
+           R1 = ManyUbxSums_Addr.Addr_closure;   // CmmAssign
+           call (stg_gc_fun)(R2, R1) args: 8, res: 0, upd: 8;   // CmmCall
+       c15C: // global
+           // allocHeapClosure
+           I64[Hp - 8] = ManyUbxSums_Addr.Addr_con_info;   // CmmStore
+           I64[Hp] = _B0::I64;   // CmmStore
+           _c15y::P64 = Hp - 7;   // CmmAssign
+           R1 = _c15y::P64;   // CmmAssign
+           call (P64[Sp])(R1) args: 8, res: 0, upd: 8;   // CmmCall
+     }
+ },
+ section ""data" . ManyUbxSums_Addr.Addr_closure" {
+     ManyUbxSums_Addr.Addr_closure:
+         const ManyUbxSums_Addr.Addr_info;
+ }]
+
+
+==================== Output Cmm ====================
+2022-09-27 22:20:23.853732429 UTC
+
+[ManyUbxSums_Addr.Addr_con_entry() { //  []
+         { info_tbls: [(c15H,
+                        label: ManyUbxSums_Addr.Addr_con_info
+                        rep: HeapRep 1 nonptrs {
+                               Con {tag: 0 descr:"main:ManyUbxSums_Addr.Addr"} }
+                        srt: Nothing)]
+           stack_info: arg_space: 8
+         }
+     {offset
+       c15H: // global
+           R1 = R1 + 1;   // CmmAssign
+           call (P64[Sp])(R1) args: 8, res: 0, upd: 8;   // CmmCall
+     }
+ }]
+


=====================================
testsuite/tests/unboxedsums/ManyUbxSums_Addr.debug.dump-stg-final
=====================================
@@ -0,0 +1,214 @@
+
+==================== Final STG: ====================
+2022-09-27 22:20:23.80547185 UTC
+
+$tc'Addr1_rYK :: GHC.Prim.Addr#
+[GblId, Unf=OtherCon []] =
+    "'Addr"#;
+
+$tcAddr1_rYG :: GHC.Prim.Addr#
+[GblId, Unf=OtherCon []] =
+    "Addr"#;
+
+$trModule3_rYD :: GHC.Prim.Addr#
+[GblId, Unf=OtherCon []] =
+    "ManyUbxSums_Addr"#;
+
+$trModule1_rYB :: GHC.Prim.Addr#
+[GblId, Unf=OtherCon []] =
+    "main"#;
+
+$c==_rYq
+  :: ManyUbxSums_Addr.Addr -> ManyUbxSums_Addr.Addr -> GHC.Types.Bool
+[GblId, Arity=2, Unf=OtherCon []] =
+    {} \r [ds_s11j ds1_s11k]
+        case ds_s11j of {
+        ManyUbxSums_Addr.Addr x_s11m [Occ=Once1] ->
+        case ds1_s11k of {
+        ManyUbxSums_Addr.Addr y_s11o [Occ=Once1] ->
+        case eqAddr# [x_s11m:AddrRep y_s11o:AddrRep] of {
+          __DEFAULT ->
+              Control.Exception.Base.patError
+                  "testsuite/tests/unboxedsums/ManyUbxSums_Addr.hs:(15,28)-(17,17)|case"#:AddrRep;
+          0# -> GHC.Types.False [];
+          1# -> GHC.Types.True [];
+        };
+        };
+        };
+
+$c/=_rYr
+  :: ManyUbxSums_Addr.Addr -> ManyUbxSums_Addr.Addr -> GHC.Types.Bool
+[GblId, Arity=2, Unf=OtherCon []] =
+    {} \r [x_s11q y_s11r]
+        case $c==_rYq x_s11q:LiftedRep y_s11r:LiftedRep of {
+          GHC.Types.False -> GHC.Types.True [];
+          GHC.Types.True -> GHC.Types.False [];
+        };
+
+ManyUbxSums_Addr.$fEqAddr [InlPrag=CONLIKE]
+  :: GHC.Classes.Eq ManyUbxSums_Addr.Addr
+[GblId[DFunId], Unf=OtherCon []] =
+    GHC.Classes.C:Eq! [$c==_rYq:LiftedRep $c/=_rYr:LiftedRep];
+
+$cfromInteger_rYs
+  :: GHC.Num.Integer.Integer -> ManyUbxSums_Addr.Addr
+[GblId, Arity=1, Unf=OtherCon []] =
+    {} \r [x_s11t]
+        case
+            GHC.Real.fromIntegral
+                GHC.Real.$fIntegralInteger:LiftedRep
+                GHC.Num.$fNumInt:LiftedRep
+                x_s11t:LiftedRep
+        of
+        {
+        GHC.Types.I# x1_s11v [Occ=Once1] ->
+        case int2Addr# [x1_s11v:IntRep] of sat_s11w [Occ=Once1] {
+        __DEFAULT -> ManyUbxSums_Addr.Addr [sat_s11w:AddrRep];
+        };
+        };
+
+$csignum_rYt :: ManyUbxSums_Addr.Addr -> ManyUbxSums_Addr.Addr
+[GblId, Str=b, Cpr=b] =
+    {} \u []
+        Control.Exception.Base.noMethodBindingError
+            "testsuite/tests/unboxedsums/ManyUbxSums_Addr.hs:19:10-17|signum"#:AddrRep;
+
+$cabs_rYu :: ManyUbxSums_Addr.Addr -> ManyUbxSums_Addr.Addr
+[GblId, Str=b, Cpr=b] =
+    {} \u []
+        Control.Exception.Base.noMethodBindingError
+            "testsuite/tests/unboxedsums/ManyUbxSums_Addr.hs:19:10-17|abs"#:AddrRep;
+
+$c*_rYv
+  :: ManyUbxSums_Addr.Addr
+     -> ManyUbxSums_Addr.Addr -> ManyUbxSums_Addr.Addr
+[GblId, Str=b, Cpr=b] =
+    {} \u []
+        Control.Exception.Base.noMethodBindingError
+            "testsuite/tests/unboxedsums/ManyUbxSums_Addr.hs:19:10-17|*"#:AddrRep;
+
+$c+_rYw
+  :: ManyUbxSums_Addr.Addr
+     -> ManyUbxSums_Addr.Addr -> ManyUbxSums_Addr.Addr
+[GblId, Str=b, Cpr=b] =
+    {} \u []
+        Control.Exception.Base.noMethodBindingError
+            "testsuite/tests/unboxedsums/ManyUbxSums_Addr.hs:19:10-17|+"#:AddrRep;
+
+$c-_rYx
+  :: ManyUbxSums_Addr.Addr
+     -> ManyUbxSums_Addr.Addr -> ManyUbxSums_Addr.Addr
+[GblId, Arity=2, Str=<L><L>b, Cpr=b, Unf=OtherCon []] =
+    {} \r [x_s11x y_s11y] $c+_rYw;
+
+$cnegate_rYy :: ManyUbxSums_Addr.Addr -> ManyUbxSums_Addr.Addr
+[GblId, Arity=1, Str=<L>b, Cpr=b, Unf=OtherCon []] =
+    {} \r [x_s11z] $c+_rYw;
+
+ManyUbxSums_Addr.$fNumAddr [InlPrag=CONLIKE]
+  :: GHC.Num.Num ManyUbxSums_Addr.Addr
+[GblId[DFunId], Unf=OtherCon []] =
+    GHC.Num.C:Num! [$c+_rYw:LiftedRep
+                    $c-_rYx:LiftedRep
+                    $c*_rYv:LiftedRep
+                    $cnegate_rYy:LiftedRep
+                    $cabs_rYu:LiftedRep
+                    $csignum_rYt:LiftedRep
+                    $cfromInteger_rYs:LiftedRep];
+
+sat_s11A :: GHC.Types.Word
+[LclId] =
+    {} \u [] GHC.Enum.maxBound GHC.Enum.$fBoundedWord:LiftedRep;
+
+$cmaxBound_rYz :: ManyUbxSums_Addr.Addr
+[GblId] =
+    {} \u []
+        GHC.Real.fromIntegral
+            GHC.Real.$fIntegralWord:LiftedRep
+            ManyUbxSums_Addr.$fNumAddr:LiftedRep
+            sat_s11A:LiftedRep;
+
+sat_s11B :: GHC.Num.Integer.Integer
+[LclId] =
+    GHC.Num.Integer.IS! [0#:IntRep];
+
+$cminBound_rYA :: ManyUbxSums_Addr.Addr
+[GblId] =
+    {} \u []
+        case
+            GHC.Real.fromIntegral
+                GHC.Real.$fIntegralInteger:LiftedRep
+                GHC.Num.$fNumInt:LiftedRep
+                sat_s11B:LiftedRep
+        of
+        {
+        GHC.Types.I# x1_s11D [Occ=Once1] ->
+        case int2Addr# [x1_s11D:IntRep] of sat_s11E [Occ=Once1] {
+        __DEFAULT -> ManyUbxSums_Addr.Addr [sat_s11E:AddrRep];
+        };
+        };
+
+ManyUbxSums_Addr.$fBoundedAddr [InlPrag=CONLIKE]
+  :: GHC.Enum.Bounded ManyUbxSums_Addr.Addr
+[GblId[DFunId], Unf=OtherCon []] =
+    GHC.Enum.C:Bounded! [$cminBound_rYA:LiftedRep
+                         $cmaxBound_rYz:LiftedRep];
+
+$trModule2_rYC :: GHC.Types.TrName
+[GblId, Unf=OtherCon []] =
+    GHC.Types.TrNameS! [$trModule1_rYB:AddrRep];
+
+$trModule4_rYE :: GHC.Types.TrName
+[GblId, Unf=OtherCon []] =
+    GHC.Types.TrNameS! [$trModule3_rYD:AddrRep];
+
+ManyUbxSums_Addr.$trModule :: GHC.Types.Module
+[GblId, Unf=OtherCon []] =
+    GHC.Types.Module! [$trModule2_rYC:LiftedRep
+                       $trModule4_rYE:LiftedRep];
+
+$krep_rYF :: GHC.Types.KindRep
+[GblId, Unf=OtherCon []] =
+    GHC.Types.KindRepTyConApp! [GHC.Types.$tcAddr#:LiftedRep
+                                GHC.Types.[]:LiftedRep];
+
+$tcAddr2_rYH :: GHC.Types.TrName
+[GblId, Unf=OtherCon []] =
+    GHC.Types.TrNameS! [$tcAddr1_rYG:AddrRep];
+
+ManyUbxSums_Addr.$tcAddr :: GHC.Types.TyCon
+[GblId, Unf=OtherCon []] =
+    GHC.Types.TyCon! [4790135393693416043##64:Word64Rep
+                      4509054882010932911##64:Word64Rep
+                      ManyUbxSums_Addr.$trModule:LiftedRep
+                      $tcAddr2_rYH:LiftedRep
+                      0#:IntRep
+                      GHC.Types.krep$*:LiftedRep];
+
+$krep1_rYI :: GHC.Types.KindRep
+[GblId, Unf=OtherCon []] =
+    GHC.Types.KindRepTyConApp! [ManyUbxSums_Addr.$tcAddr:LiftedRep
+                                GHC.Types.[]:LiftedRep];
+
+$krep2_rYJ :: GHC.Types.KindRep
+[GblId, Unf=OtherCon []] =
+    GHC.Types.KindRepFun! [$krep_rYF:LiftedRep $krep1_rYI:LiftedRep];
+
+$tc'Addr2_rYL :: GHC.Types.TrName
+[GblId, Unf=OtherCon []] =
+    GHC.Types.TrNameS! [$tc'Addr1_rYK:AddrRep];
+
+ManyUbxSums_Addr.$tc'Addr :: GHC.Types.TyCon
+[GblId, Unf=OtherCon []] =
+    GHC.Types.TyCon! [15766329447734056695##64:Word64Rep
+                      3176921173291726962##64:Word64Rep
+                      ManyUbxSums_Addr.$trModule:LiftedRep
+                      $tc'Addr2_rYL:LiftedRep
+                      0#:IntRep
+                      $krep2_rYJ:LiftedRep];
+
+ManyUbxSums_Addr.Addr [InlPrag=CONLIKE]
+  :: GHC.Prim.Addr# %1 -> ManyUbxSums_Addr.Addr
+[GblId[DataCon], Arity=1, Caf=NoCafRefs, Unf=OtherCon []] =
+    {} \r [eta_B0] ManyUbxSums_Addr.Addr [eta_B0:AddrRep];
+


=====================================
testsuite/tests/unboxedsums/ManyUbxSums_Addr.hs
=====================================
@@ -0,0 +1,26 @@
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnboxedTuples #-}
+{-# LANGUAGE UnboxedSums #-}
+
+{-# OPTIONS_GHC -Wno-missing-methods #-}
+
+module ManyUbxSums_Addr where
+
+import GHC.Exts
+-- import GHC.Word
+-- import GHC.Int
+--import GHC.Utils.Misc
+
+data Addr = Addr Addr#
+
+instance Eq Addr where
+    (Addr x) == (Addr y) = case (eqAddr# x y) of
+      1# -> True
+      0# -> False
+
+instance Num Addr where
+  fromInteger x = case fromIntegral x of I# x1 -> Addr (int2Addr# x1)
+
+instance Bounded Addr where
+  maxBound = fromIntegral (maxBound :: Word)
+  minBound = 0
\ No newline at end of file


=====================================
testsuite/tests/unboxedsums/T22208.hs
=====================================
@@ -0,0 +1,41 @@
+{-# LANGUAGE MagicHash                 #-}
+{-# LANGUAGE UnboxedSums               #-}
+{-# LANGUAGE UnboxedTuples             #-}
+module M where
+
+import GHC.Base
+
+-- Reproducer from #22208
+foo :: (# Float# | Double# #) -> (# Float# | Float #)
+foo (# x | #) = (# x | #)
+bar :: (# Word# | Int64# #) -> (# Double# | Word# #)
+bar (# y | #) = let x = y in (# | x #)
+baz :: (# Word# | Word64# #) -> (# Word# | (##) #)
+baz (# x | #) = (# x | #)
+
+foo1 :: (# Float# | Double# #) -> (# Float# | Float #)
+foo1 (# x | #) = (# x | #)
+bar1 :: (# Word# | Int64# #) -> (# Double# | Word# #)
+bar1 (# y | #) = let x = y in (# | x #)
+baz1 :: (# Word# | Word64# #) -> (# Word# | (##) #)
+baz1 (# x | #) = (# x | #)
+
+-- i8 value from w64 slot
+baz2 :: (# Int8# | Word64# #) -> (# Int8# | (##) #)
+baz2 (# x | #) = (# x | #)
+
+-- w8 value from w64 slot
+baz3 :: (# Word8# | Word64# #) -> (# Word8# | (##) #)
+baz3 (# x | #) = (# x | #)
+
+-- w8 from w slot
+baz4 :: (# Word8# | Word# #) -> (# Word8# | (##) #)
+baz4 (# x | #) = (# x | #)
+
+-- w from w slot
+baz5 :: (# Word8# | Word# #) -> (# Word# | (##) #)
+baz5 (# | x #) = (# x | #)
+
+-- addr from w slot
+baz6 :: (# Addr# | Word# #) -> (# Addr# | (##) #)
+baz6 (# x | #) = (# x | #)
\ No newline at end of file


=====================================
testsuite/tests/unboxedsums/all.T
=====================================
@@ -35,3 +35,12 @@ test('T20858b', [extra_files(['T20858.hs'])
                 ,extra_hc_opts("-fprint-explicit-runtime-reps -fprint-explicit-kinds")]
               , ghci_script, ['T20858b.script'])
 test('T20859', normal, compile, [''])
+test('T22208', normal, compile, ['-dstg-lint -dcmm-lint'])
+test('ManyUbxSums',
+     [ pre_cmd('./GenManyUbxSums.hs'),
+       extra_files(['GenManyUbxSums.hs', 'ManyUbxSums_Addr.hs']),
+     ],
+     multi_compile_and_run,
+     ['ManyUbxSums',
+        [('ManyUbxSums_Addr.hs','')]
+        , '-v0 -dstg-lint -dcmm-lint'])



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4b781b91bb38872b2dc38afc4ca38a6f458e606a

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4b781b91bb38872b2dc38afc4ca38a6f458e606a
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20220927/93c4b189/attachment-0001.html>


More information about the ghc-commits mailing list