summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Craven <5086-clyring@users.noreply.gitlab.haskell.org>2022-04-27 15:38:20 -0400
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-05-05 12:48:47 -0400
commit016f9ca683fc915d661b2c24321d3005a8929a47 (patch)
treea697f332139a6104d60d89f8f98d8c0f2e5f3161
parent610d028348ca0aa2721d515961f14cb72416c17c (diff)
downloadhaskell-016f9ca683fc915d661b2c24321d3005a8929a47.tar.gz
Fix broken rules for (^) with known small powers
-rw-r--r--libraries/base/GHC/Real.hs23
-rw-r--r--testsuite/tests/lib/base/all.T2
2 files changed, 12 insertions, 13 deletions
diff --git a/libraries/base/GHC/Real.hs b/libraries/base/GHC/Real.hs
index e6943b0d86..666034bdac 100644
--- a/libraries/base/GHC/Real.hs
+++ b/libraries/base/GHC/Real.hs
@@ -717,22 +717,21 @@ floated out before the rule has a chance to fire.
Also desirable would be rules for (^^), but I haven't managed
to get those to fire.
-Note: Trying to save multiplications by sharing the square for
-exponents 4 and 5 does not save time, indeed, for Double, it is
-up to twice slower, so the rules contain flat sequences of
-multiplications.
+Note: Since (*) is not associative for some types (e.g. Double), it is
+important that the RHS of these rules produce the same bracketing as
+would the actual implementation of (^). A mismatch here led to #19569.
-}
-- See Note [Powers with small exponent]
{-# RULES
-"^2/Int" forall x. x ^ (2 :: Int) = let u = x in u*u
-"^3/Int" forall x. x ^ (3 :: Int) = let u = x in u*u*u
-"^4/Int" forall x. x ^ (4 :: Int) = let u = x in u*u*u*u
-"^5/Int" forall x. x ^ (5 :: Int) = let u = x in u*u*u*u*u
-"^2/Integer" forall x. x ^ (2 :: Integer) = let u = x in u*u
-"^3/Integer" forall x. x ^ (3 :: Integer) = let u = x in u*u*u
-"^4/Integer" forall x. x ^ (4 :: Integer) = let u = x in u*u*u*u
-"^5/Integer" forall x. x ^ (5 :: Integer) = let u = x in u*u*u*u*u
+"^2/Int" forall x. x ^ (2 :: Int) = x*x
+"^3/Int" forall x. x ^ (3 :: Int) = x*x*x
+"^4/Int" forall x. x ^ (4 :: Int) = let u = x*x in u*u
+"^5/Int" forall x. x ^ (5 :: Int) = let u = x*x in u*u*x
+"^2/Integer" forall x. x ^ (2 :: Integer) = x*x
+"^3/Integer" forall x. x ^ (3 :: Integer) = x*x*x
+"^4/Integer" forall x. x ^ (4 :: Integer) = let u = x*x in u*u
+"^5/Integer" forall x. x ^ (5 :: Integer) = let u = x*x in u*u*x
#-}
-------------------------------------------------------
diff --git a/testsuite/tests/lib/base/all.T b/testsuite/tests/lib/base/all.T
index b45171c8e2..8d88097a17 100644
--- a/testsuite/tests/lib/base/all.T
+++ b/testsuite/tests/lib/base/all.T
@@ -6,4 +6,4 @@ test('T17310', normal, compile, [''])
test('T19691', normal, compile, [''])
test('executablePath', extra_run_opts(config.os), compile_and_run, [''])
test('T17472', normal, compile_and_run, [''])
-test('T19569', expect_broken(19569), compile_and_run, [''])
+test('T19569', normal, compile_and_run, [''])