diff --git a/README.rst b/README.rst
--- a/README.rst
+++ b/README.rst
@@ -41,9 +41,6 @@
       If it is made faster, it should be used as the default bijection for ``CBRNG32/64``
       instead of ``philox4``.
 
-    * ``mulhilo`` function in 64-bit Philox is not optimal in terms of performance.
-      It can be made faster given the access to CPU intrinsics.
-
     * 32-bit Threefry shows suprisingly low performance (see ``Bijection`` benchmark group).
 
     * In general, there seems to be a lot of optimizations that can be done,
diff --git a/Random123.cabal b/Random123.cabal
--- a/Random123.cabal
+++ b/Random123.cabal
@@ -1,5 +1,5 @@
 Name:                Random123
-Version:             0.1.2
+Version:             0.2.0
 Synopsis:            Haskell port of Random123 library
 Description:
   This is a Haskell port of counter-based random number generators from the Random123 library
@@ -29,7 +29,7 @@
 Source-repository this
   type:     git
   location: http://github.com/Manticore/haskell-random123.git
-  tag:      0.1.2
+  tag:      0.2.0
 
 Library
   Exposed-modules:
@@ -41,8 +41,9 @@
     System.Random.Random123.RandomGen
 
   Build-Depends:
-    base >= 4.4.0.0 && < 5.0,
+    base >= 4.7.0.0 && < 5.0,
     array >= 0.4,
+    data-dword,
     random >= 1.0.0.0
 
 Test-Suite test
@@ -51,7 +52,7 @@
   Main-is: test.hs
   Other-modules: TestPhilox TestThreefry TestRandomGen TestTypeclasses
   Build-depends:
-    base >= 4.4 && < 5.0,
+    base >= 4.7 && < 5.0,
     random >= 1.0,
     test-framework >= 0.8,
     test-framework-hunit >= 0.3,
@@ -65,8 +66,8 @@
   Hs-source-dirs: test
   Main-is: test_perf.hs
   Build-depends:
-    base >= 4.4 && < 5.0,
+    base >= 4.7 && < 5.0,
     random >= 1.0,
-    criterion >= 0.6,
+    criterion >= 1.0,
     Random123
   Ghc-options: -O2
diff --git a/System/Random/Random123/Philox.hs b/System/Random/Random123/Philox.hs
--- a/System/Random/Random123/Philox.hs
+++ b/System/Random/Random123/Philox.hs
@@ -9,6 +9,8 @@
 import Data.Word
 import Data.Bits
 
+import Data.DoubleWord
+
 import System.Random.Random123.Misc
 import System.Random.Random123.Types
 
@@ -43,10 +45,10 @@
 
 instance PhiloxWord Word64 where
     mulhilo a b = (hi, lo) where
-        r :: Integer
-        r = fromIntegral a * fromIntegral b
-        hi = fromIntegral (r `shiftR` 64)
-        lo = fromIntegral r
+        r :: Word128
+        r = extendLo a * extendLo b
+        hi = hiWord r
+        lo = loWord r
 
     philoxW_0 = 0x9E3779B97F4A7C15 -- golden ratio
     philoxW_1 = 0xBB67AE8584CAA73B -- sqrt(3)-1
diff --git a/System/Random/Random123/RandomGen.hs b/System/Random/Random123/RandomGen.hs
--- a/System/Random/Random123/RandomGen.hs
+++ b/System/Random/Random123/RandomGen.hs
@@ -20,6 +20,7 @@
 
 import System.Random
 import Data.Word
+import Data.Bits
 
 import System.Random.Random123.Types
 import System.Random.Random123.Philox
@@ -55,7 +56,9 @@
         else (increment ctr, 0)
 
 genRange32 :: (Int, Int)
-genRange32 = (0, min maxBound (2^32 - 1))
+genRange32
+    | finiteBitSize (0 :: Int) > 32 = (0, 2^32 - 1)
+    | otherwise                     = (minBound, maxBound)
 
 next64 :: (Counter c, Word64Array c) => (c -> c) -> c -> Int -> (Int, c, Int)
 next64 bijection ctr wctr = (fromIntegral w64, ctr', wctr') where
@@ -66,7 +69,9 @@
         else (increment ctr, 0)
 
 genRange64 :: (Int, Int)
-genRange64 = (0, min maxBound (2^64 - 1))
+genRange64
+    | finiteBitSize (0 :: Int) > 64 = (0, 2^64 - 1)
+    | otherwise                     = (minBound, maxBound)
 
 
 instance (Counter c, Word32Array c) => RandomGen (CustomCBRNG32 k c) where
diff --git a/System/Random/Random123/Types.hs b/System/Random/Random123/Types.hs
--- a/System/Random/Random123/Types.hs
+++ b/System/Random/Random123/Types.hs
@@ -31,29 +31,29 @@
     liBitSize :: a -> Int
 
 
-array2FromInteger :: (Num a, Bits a) => Integer -> Array2 a
+array2FromInteger :: (Num a, FiniteBits a) => Integer -> Array2 a
 array2FromInteger i = (x0, x1) where
     x1 = fromInteger i
-    bits = bitSize x1 -- need this because cannot use 'a' type variable
+    bits = finiteBitSize x1 -- need this because cannot use 'a' type variable
     x0 = fromInteger (i `shiftR` bits)
 
-array4FromInteger :: (Num a, Bits a) => Integer -> Array4 a
+array4FromInteger :: (Num a, FiniteBits a) => Integer -> Array4 a
 array4FromInteger i = (x0, x1, x2, x3) where
     x3 = fromInteger i
-    bits = bitSize x3 -- need this because cannot use 'a' type variable
+    bits = finiteBitSize x3 -- need this because cannot use 'a' type variable
     x0 = fromInteger (i `shiftR` (bits * 3))
     x1 = fromInteger (i `shiftR` (bits * 2))
     x2 = fromInteger (i `shiftR` bits)
 
-array2ToInteger :: (Integral a, Bits a) => Array2 a -> Integer
+array2ToInteger :: (Integral a, FiniteBits a) => Array2 a -> Integer
 array2ToInteger (x0, x1) = x0' + x1' where
-    bits = bitSize x0
+    bits = finiteBitSize x0
     x0' = toInteger x0 `shiftL` bits
     x1' = toInteger x1
 
-array4ToInteger :: (Integral a, Bits a) => Array4 a -> Integer
+array4ToInteger :: (Integral a, FiniteBits a) => Array4 a -> Integer
 array4ToInteger (x0, x1, x2, x3) = x0' + x1' + x2' + x3' where
-    bits = bitSize x0
+    bits = finiteBitSize x0
     x0' = toInteger x0 `shiftL` (bits * 3)
     x1' = toInteger x1 `shiftL` (bits * 2)
     x2' = toInteger x2 `shiftL` bits
@@ -61,38 +61,38 @@
 
 -- Technically, Word32 and Word64 instances are identical,
 -- but I couldn't persuade GHC to compile them in generalized form
--- (like "instance (Num a, Bits a, Integral a) => LimitedInteger (Array2 a)").
+-- (like "instance (Num a, FiniteBits a, Integral a) => LimitedInteger (Array2 a)").
 
 instance LimitedInteger Word32 where
     liFromInteger = fromInteger
     liToInteger = toInteger
-    liBitSize = bitSize
+    liBitSize = finiteBitSize
 
 instance LimitedInteger (Array2 Word32) where
     liFromInteger = array2FromInteger
     liToInteger = array2ToInteger
-    liBitSize _ = bitSize (undefined :: Word32) * 2
+    liBitSize _ = finiteBitSize (undefined :: Word32) * 2
 
 instance LimitedInteger (Array4 Word32) where
     liFromInteger = array4FromInteger
     liToInteger = array4ToInteger
-    liBitSize _ = bitSize (undefined :: Word32) * 4
+    liBitSize _ = finiteBitSize (undefined :: Word32) * 4
 
 
 instance LimitedInteger Word64 where
     liFromInteger = fromInteger
     liToInteger = toInteger
-    liBitSize = bitSize
+    liBitSize = finiteBitSize
 
 instance LimitedInteger (Array2 Word64) where
     liFromInteger = array2FromInteger
     liToInteger = array2ToInteger
-    liBitSize _ = bitSize (undefined :: Word64) * 2
+    liBitSize _ = finiteBitSize (undefined :: Word64) * 2
 
 instance LimitedInteger (Array4 Word64) where
     liFromInteger = array4FromInteger
     liToInteger = array4ToInteger
-    liBitSize _ = bitSize (undefined :: Word64) * 4
+    liBitSize _ = finiteBitSize (undefined :: Word64) * 4
 
 
 -- | Class of CBRNG counters.
diff --git a/test/test_perf.hs b/test/test_perf.hs
--- a/test/test_perf.hs
+++ b/test/test_perf.hs
@@ -1,7 +1,7 @@
 import Data.Word
 
 import Criterion.Main
-import Criterion.Config
+import Criterion.Types
 
 import System.Random.Random123.Threefry
 import System.Random.Random123.Misc
@@ -59,10 +59,10 @@
 
 
 myConfig = defaultConfig {
-    cfgPerformGC = ljust True,
-    cfgReport = ljust "test_perf.html" }
+    forceGC = True,
+    reportFile = Just "test_perf.html" }
 
-main = defaultMainWith myConfig (return ()) [
+main = defaultMainWith myConfig [
     bgroup "Bijections" [
         bench "Philox-2x32" $ nf (test_bijection2x32 Philox2x32) 101,
         bench "Philox-4x32" $ nf (test_bijection4x32 Philox4x32) 102,
