summaryrefslogtreecommitdiff
path: root/testsuite/tests/stranal/sigs/T19871.hs
diff options
context:
space:
mode:
Diffstat (limited to 'testsuite/tests/stranal/sigs/T19871.hs')
-rw-r--r--testsuite/tests/stranal/sigs/T19871.hs70
1 files changed, 70 insertions, 0 deletions
diff --git a/testsuite/tests/stranal/sigs/T19871.hs b/testsuite/tests/stranal/sigs/T19871.hs
new file mode 100644
index 0000000000..564a055df4
--- /dev/null
+++ b/testsuite/tests/stranal/sigs/T19871.hs
@@ -0,0 +1,70 @@
+{-# OPTIONS_GHC -O2 -fforce-recomp #-}
+
+-- | From Note [Boxity Analysis] and related Notes
+module T19871 where
+
+data Huge
+ = Huge
+ { f1 :: Bool
+ , f2 :: Bool
+ , f3 :: Bool
+ , f4 :: Bool
+ , f5 :: Bool
+ , f6 :: Bool
+ , f7 :: Bool
+ , f8 :: Bool
+ , f9 :: Bool
+ , f10 :: Bool
+ , f11 :: Bool
+ , f12 :: Bool }
+
+-- | Should not unbox Huge
+ann :: Huge -> (Bool, Huge)
+ann h@(Huge{f1=True}) = (False, h)
+ann h = (True, h)
+{-# NOINLINE ann #-}
+
+-- A few examples demonstrating the lubBoxity = unboxedWins tradeoff
+
+-- | Should unbox 'z'.
+-- We won't with `lubBoxity = boxedWins`.
+-- We will with `lubBoxity = unboxedWins`.
+sumIO :: Int -> Int -> IO Int
+sumIO 0 !z = return z
+sumIO n !z = sumIO (n-1) (z+n)
+{-# NOINLINE sumIO #-}
+
+-- | Should /not/ unbox 'h'.
+-- We won't with `lubBoxity = boxedWins`.
+-- We will with `lubBoxity = unboxedWins`.
+update :: Huge -> (Bool, Huge)
+update h@(Huge{f1=True}) = (False, h{f1=False})
+update h = (True, h)
+{-# NOINLINE update #-}
+
+-- | Should /not/ unbox 'h'.
+-- We won't with `lubBoxity = boxedWins`.
+-- We will with `lubBoxity = unboxedWins`.
+guarded :: (Huge -> Bool) -> Huge -> Bool
+guarded g h | f1 h = True
+ | otherwise = g h
+{-# NOINLINE guarded #-}
+
+-- | Should /not/ unbox 'h'.
+-- We won't with `lubBoxity = boxedWins`.
+-- We will with `lubBoxity = unboxedWins`.
+--
+-- This example also demonstrates the usefulness of carrying a Boxity in Poly.
+-- Most absent sub-demands here should be considered Boxed (and of course we
+-- also need Unboxed absent Poly). See Note [Boxity in Poly].
+absent :: Huge -> Int
+absent h = if f1 h || f2 h then g h else 2
+ where
+ g :: a -> Int
+ g a = a `seq` f a True
+ {-# NOINLINE g #-}
+ f :: a -> Bool -> Int
+ f _ True = 1
+ f a False = a `seq` 2
+ {-# NOINLINE f #-}
+{-# NOINLINE absent #-}