blob: e0347fd502ab543d1ac927e3c67ee94b449d6aa7 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
{-# LANGUAGE BangPatterns #-}
module T19398 where
data T a = MkT !a !a
f :: T a -> T a
f (MkT a b) = MkT b a
{-# NOINLINE f #-}
-- | Should *not* have the CPR property, even though the scrutinee is a
-- variable with the CPR property. It shows how Test (A) of
-- Historical Note [Optimistic field binder CPR] is unsound.
a :: Int -> Int
a n
| n == 0 = n
| even n = case q of MkT x y -> if x == y then x else y
| otherwise = case q of MkT x y -> if x == y then y else x
where
q = f $ f $ f $ f $ f $ f $ f $ MkT n n
-- | Should not have the CPR property, because 'x' will not be unboxed.
-- It shows how Test (C) of Historical Note [Optimistic field binder CPR] is
-- unsound.
c :: (Int, Int) -> Int
c (x,_) = x
-- | An interesting artifact is that the following function has the Nested CPR
-- property, and we could in theory exploit that:
g :: (Int, Int) -> (Int, Int)
g p@(!x, !y) | x == y = error "blah"
g p = p
|