Add missing parentheses in eqBigNatWord#
authorReid Barton <rwbarton@gmail.com>
Sun, 26 Jul 2015 03:01:49 +0000 (23:01 -0400)
committerReid Barton <rwbarton@gmail.com>
Sun, 26 Jul 2015 03:01:49 +0000 (23:01 -0400)
Summary:
I'm pretty sure that parentheses were intended here. But oddly, they
make very little difference.

The presumably intended expression
    (sizeofBigNat# bn ==# 1#) `andI#` (bigNatToWord bn `eqWord#` w#)
is 1# exactly when bn consists of a single limb equal to w#, clearly.

In the original expression
    sizeofBigNat# bn ==# 1# `andI#` (bigNatToWord bn `eqWord#` w#)
the right-hand side of ==# is always 0# or 1#. So it is 1# when bn
consists of a single limb equal to w#. It is also 1# when bn has
zero limbs and the word past the end of bn does not happen to be
equal to w#. So in practice the difference is that nullBigNat was
eqBigNatWord# to almost everything, but eqBigNatWord# is never
supposed to be called on nullBigNat anyways.

Note that even the corrected version might perform an out-of-bounds
memory access if passed nullBigNat, because `andI#` is not guaranteed
to short-circuit, though in fact GHC does convert isZeroBigNat to a
series of branches in my local build.

Test Plan: validate

Reviewers: hvr, bgamari, goldfire, austin

Reviewed By: hvr, bgamari

Subscribers: thomie

Differential Revision: https://phabricator.haskell.org/D1095

libraries/integer-gmp/src/GHC/Integer/Type.hs

index 88d1923..d941c4c 100644 (file)
@@ -835,7 +835,7 @@ eqBigNatWord bn w# = isTrue# (eqBigNatWord# bn w#)
 
 eqBigNatWord# :: BigNat -> GmpLimb# -> Int#
 eqBigNatWord# bn w#
-    = sizeofBigNat# bn ==# 1# `andI#` (bigNatToWord bn `eqWord#` w#)
+    = (sizeofBigNat# bn ==# 1#) `andI#` (bigNatToWord bn `eqWord#` w#)
 
 
 -- | Same as @'indexBigNat#' bn 0\#@