summaryrefslogtreecommitdiff
path: root/testsuite/tests/simplCore/should_run
diff options
context:
space:
mode:
authorAlexis King <lexi.lambda@gmail.com>2020-04-17 16:43:49 -0500
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-04-22 23:11:12 -0400
commit6c9fae2342f19ab3e6ac688825a3817b23bf1fcc (patch)
treeb996d1bdca3e275c77b61de77e54ea107b771d19 /testsuite/tests/simplCore/should_run
parent401f7bb312aa6c570287d313f8b587aaebca72b2 (diff)
downloadhaskell-6c9fae2342f19ab3e6ac688825a3817b23bf1fcc.tar.gz
Mark DataCon wrappers CONLIKE
Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler
Diffstat (limited to 'testsuite/tests/simplCore/should_run')
-rw-r--r--testsuite/tests/simplCore/should_run/T18012.hs41
-rw-r--r--testsuite/tests/simplCore/should_run/T18012.stdout1
-rw-r--r--testsuite/tests/simplCore/should_run/all.T1
3 files changed, 43 insertions, 0 deletions
diff --git a/testsuite/tests/simplCore/should_run/T18012.hs b/testsuite/tests/simplCore/should_run/T18012.hs
new file mode 100644
index 0000000000..9118b75ff4
--- /dev/null
+++ b/testsuite/tests/simplCore/should_run/T18012.hs
@@ -0,0 +1,41 @@
+module Main (main) where
+
+{- This program is designed to check that case-of-known-constructor
+fires even if an application of a DataCon wrapper is floated out:
+
+ * The early FloatOut pass will float `D False` out of `g`, since
+ it’s a constant, non-trivial expression.
+
+ * But since `D` is strict, the floated-out expression will actually
+ be `$WD False`.
+
+ * In simplifier phase 2, `f` will be inlined into `g`, leading to a
+ case expression that scrutinizes the floated-out binding.
+
+ * If case-of-known-constructor fires, we’ll end up with `notRule
+ False`, the RULE will fire, and we get True.
+
+ * If it doesn’t fire at phase 2, it will fire later at phase 0 when
+ we inline the DataCon wrapper. But now the RULE is inactive, so
+ we’ll end up with False instead.
+
+We want case-of-known-constructor to fire early, so we want the output
+to be True. See #18012 for more details. -}
+
+main :: IO ()
+main = print (g ())
+
+data T = D !Bool
+
+notRule :: Bool -> Bool
+notRule x = x
+{-# INLINE [0] notRule #-}
+{-# RULES "notRule/False" [~0] notRule False = True #-}
+
+f :: T -> () -> Bool
+f (D a) () = notRule a
+{-# INLINE [100] f #-} -- so it isn’t inlined before FloatOut
+
+g :: () -> Bool
+g x = f (D False) x
+{-# NOINLINE g #-}
diff --git a/testsuite/tests/simplCore/should_run/T18012.stdout b/testsuite/tests/simplCore/should_run/T18012.stdout
new file mode 100644
index 0000000000..0ca95142bb
--- /dev/null
+++ b/testsuite/tests/simplCore/should_run/T18012.stdout
@@ -0,0 +1 @@
+True
diff --git a/testsuite/tests/simplCore/should_run/all.T b/testsuite/tests/simplCore/should_run/all.T
index d101bff84b..210949d9c6 100644
--- a/testsuite/tests/simplCore/should_run/all.T
+++ b/testsuite/tests/simplCore/should_run/all.T
@@ -93,3 +93,4 @@ test('T15840a', normal, compile_and_run, [''])
test('T16066', exit_code(1), compile_and_run, ['-O1'])
test('T17206', exit_code(1), compile_and_run, [''])
test('T17151', [], multimod_compile_and_run, ['T17151', ''])
+test('T18012', normal, compile_and_run, [''])