diff options
author | Sebastian Graf <sebastian.graf@kit.edu> | 2018-05-15 13:12:56 -0400 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2018-05-15 13:12:57 -0400 |
commit | bb338f2eb706a3137bf6675e3ddbf96d4fe4f4aa (patch) | |
tree | d45b57439ca4d1d8dc0a7e820acd8366b11135c7 /testsuite/tests/numeric | |
parent | 01b15b88639443bec12415b6b0d906261bd6c047 (diff) | |
download | haskell-bb338f2eb706a3137bf6675e3ddbf96d4fe4f4aa.tar.gz |
Algebraically simplify add/sub with carry/overflow
Previously, the `{add,sub}{Int,Word}C#` PrimOps weren't handled
in PrelRules (constant folding and algebraic simplification) at all.
This implements the necessary logic, so that using these primitives
isn't too punishing compared to their well-optimised, overflow-unaware
counterparts.
This is so that using these primitives in `enumFromThenTo @Int` can
be optimized by constant folding, reducing closure sizes.
Reviewers: bgamari, simonpj, hsyl20
Reviewed By: bgamari, simonpj
Subscribers: AndreasK, thomie, carter
GHC Trac Issues: #8763
Differential Revision: https://phabricator.haskell.org/D4605
Diffstat (limited to 'testsuite/tests/numeric')
-rw-r--r-- | testsuite/tests/numeric/should_run/T10962.hs | 26 | ||||
-rw-r--r-- | testsuite/tests/numeric/should_run/T10962.stdout-ws-32 | 8 | ||||
-rw-r--r-- | testsuite/tests/numeric/should_run/T10962.stdout-ws-64 | 8 | ||||
-rw-r--r-- | testsuite/tests/numeric/should_run/all.T | 2 |
4 files changed, 36 insertions, 8 deletions
diff --git a/testsuite/tests/numeric/should_run/T10962.hs b/testsuite/tests/numeric/should_run/T10962.hs index 896c9e987f..435f3637d7 100644 --- a/testsuite/tests/numeric/should_run/T10962.hs +++ b/testsuite/tests/numeric/should_run/T10962.hs @@ -1,16 +1,32 @@ {-# LANGUAGE MagicHash #-} {-# LANGUAGE UnboxedTuples #-} -module Main where +module Main (main) where import GHC.Base +unW# :: Word -> Word# +unW# (W# w) = w + +type WordOpC = Word# -> Word# -> (# Word#, Int# #) + +check :: WordOpC -> Word# -> Word# -> IO () +check op a b = do + let (# w, c #) = op a b + print (W# w, I# c) + +checkSubInlNoInl :: WordOpC -> Word# -> Word# -> IO () +checkSubInlNoInl op a b = do + inline check op a b -- constant folding + noinline check op a b -- lowering of PrimOp +{-# INLINE checkSubInlNoInl #-} + main :: IO () main = do -- Overflow. - let (# w1, i1 #) = subWordC# 1## 3## - print (W# w1, I# i1) + checkSubInlNoInl subWordC# 1## 3## + checkSubInlNoInl addWordC# (unW# (inline maxBound)) 3## -- No overflow. - let (# w2, i2 #) = subWordC# 3## 1## - print (W# w2, I# i2) + checkSubInlNoInl subWordC# 5## 2## + checkSubInlNoInl addWordC# (unW# (inline maxBound-1)) 1## diff --git a/testsuite/tests/numeric/should_run/T10962.stdout-ws-32 b/testsuite/tests/numeric/should_run/T10962.stdout-ws-32 index a1dec8410a..605265305d 100644 --- a/testsuite/tests/numeric/should_run/T10962.stdout-ws-32 +++ b/testsuite/tests/numeric/should_run/T10962.stdout-ws-32 @@ -1,2 +1,8 @@ (4294967294,1) -(2,0) +(4294967294,1) +(2,1) +(2,1) +(3,0) +(3,0) +(4294967295,0) +(4294967295,0) diff --git a/testsuite/tests/numeric/should_run/T10962.stdout-ws-64 b/testsuite/tests/numeric/should_run/T10962.stdout-ws-64 index 853bf94a61..d36f660eb1 100644 --- a/testsuite/tests/numeric/should_run/T10962.stdout-ws-64 +++ b/testsuite/tests/numeric/should_run/T10962.stdout-ws-64 @@ -1,2 +1,8 @@ (18446744073709551614,1) -(2,0) +(18446744073709551614,1) +(2,1) +(2,1) +(3,0) +(3,0) +(18446744073709551615,0) +(18446744073709551615,0) diff --git a/testsuite/tests/numeric/should_run/all.T b/testsuite/tests/numeric/should_run/all.T index 37fff44bde..691fc26f7a 100644 --- a/testsuite/tests/numeric/should_run/all.T +++ b/testsuite/tests/numeric/should_run/all.T @@ -62,6 +62,6 @@ test('CarryOverflow', omit_ways(['ghci']), compile_and_run, ['']) test('T9407', normal, compile_and_run, ['']) test('T9810', normal, compile_and_run, ['']) test('T10011', normal, compile_and_run, ['']) -test('T10962', omit_ways(['ghci']), compile_and_run, ['']) +test('T10962', omit_ways(['ghci']), compile_and_run, ['-O2']) test('T11702', extra_ways(['optasm']), compile_and_run, ['']) test('T12136', normal, compile_and_run, ['']) |