diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,10 @@
 # Revision history for wide-word
 
+## 0.1.1.1 -- 2020-03-22
+
+* Make `sizeOf` and `alignment` methods of `Word256` `Prim` and `Storable`
+  instances agree.
+
 ## 0.1.1.0 -- 2019-11-22
 
 * Add `Word256`.
diff --git a/src/Data/WideWord/Int128.hs b/src/Data/WideWord/Int128.hs
--- a/src/Data/WideWord/Int128.hs
+++ b/src/Data/WideWord/Int128.hs
@@ -36,6 +36,9 @@
 import Data.Bits (Bits (..), FiniteBits (..), shiftL)
 import Data.Data (Data, Typeable)
 import Data.Ix (Ix)
+#if ! MIN_VERSION_base(4,11,0)
+import Data.Semigroup ((<>))
+#endif
 
 import Data.WideWord.Word128
 
@@ -55,8 +58,8 @@
 import Data.Primitive.Types (Prim (..), defaultSetByteArray#, defaultSetOffAddr#)
 
 data Int128 = Int128
-  { int128Hi64 :: {-# UNPACK #-} !Word64
-  , int128Lo64 :: {-# UNPACK #-} !Word64
+  { int128Hi64 :: !Word64
+  , int128Lo64 :: !Word64
   }
   deriving (Eq, Data, Ix, Typeable)
 
@@ -138,15 +141,16 @@
   toInteger = toInteger128
 
 instance Storable Int128 where
-  sizeOf _ = 2 * sizeOf (0 :: Word64)
-  alignment _ = 2 * alignment (0 :: Word64)
+  sizeOf i = I# (sizeOf128# i)
+  alignment i = I# (alignment128# i)
   peek = peek128
   peekElemOff = peekElemOff128
   poke = poke128
   pokeElemOff = pokeElemOff128
 
 instance NFData Int128 where
-  rnf (Int128 a1 a0) = rnf a1 `seq` rnf a0
+  -- The fields are already strict and unpacked, so do nothing.
+  rnf !_ = ()
 
 instance Prim Int128 where
   sizeOf#         = sizeOf128#
@@ -188,10 +192,7 @@
 
 compare128 :: Int128 -> Int128 -> Ordering
 compare128 (Int128 a1 a0) (Int128 b1 b0) =
-  case compare (int64OfWord64 a1) (int64OfWord64 b1) of
-    EQ -> compare a0 b0
-    LT -> LT
-    GT -> GT
+  compare (int64OfWord64 a1) (int64OfWord64 b1) <> compare a0 b0
   where
     int64OfWord64 (W64# w) = I64# (word2Int# w)
 
diff --git a/src/Data/WideWord/Word128.hs b/src/Data/WideWord/Word128.hs
--- a/src/Data/WideWord/Word128.hs
+++ b/src/Data/WideWord/Word128.hs
@@ -35,6 +35,9 @@
 import Data.Bits (Bits (..), FiniteBits (..), shiftL)
 import Data.Data (Data, Typeable)
 import Data.Ix (Ix)
+#if ! MIN_VERSION_base(4,11,0)
+import Data.Semigroup ((<>))
+#endif
 
 import Foreign.Ptr (Ptr, castPtr)
 import Foreign.Storable (Storable (..))
@@ -52,8 +55,8 @@
 import Data.Primitive.Types (Prim (..), defaultSetByteArray#, defaultSetOffAddr#)
 
 data Word128 = Word128
-  { word128Hi64 :: {-# UNPACK #-} !Word64
-  , word128Lo64 :: {-# UNPACK #-} !Word64
+  { word128Hi64 :: !Word64
+  , word128Lo64 :: !Word64
   }
   deriving (Eq, Data, Ix, Typeable)
 
@@ -135,15 +138,16 @@
   toInteger = toInteger128
 
 instance Storable Word128 where
-  sizeOf _ = 2 * sizeOf (0 :: Word64)
-  alignment _ = 2 * alignment (0 :: Word64)
+  sizeOf w = I# (sizeOf128# w)
+  alignment w = I# (alignment128# w)
   peek = peek128
   peekElemOff = peekElemOff128
   poke = poke128
   pokeElemOff = pokeElemOff128
 
 instance NFData Word128 where
-  rnf (Word128 a1 a0) = rnf a1 `seq` rnf a0
+  -- The fields are already strict and unpacked, so do nothing.
+  rnf !_ = ()
 
 instance Prim Word128 where
   sizeOf#         = sizeOf128#
@@ -173,7 +177,7 @@
 {-# RULES
 "fromIntegral :: Word128 -> Word128" fromIntegral = id :: Word128 -> Word128
 
-"fromIntegral :: Int -> Word128"     fromIntegral = \(I# i#) -> Word128 (W64# 0##) (W64# (int2Word# i#))
+"fromIntegral :: Int -> Word128"     fromIntegral = Word128 0 . (fromIntegral :: Int -> Word64)
 "fromIntegral :: Word -> Word128"    fromIntegral = Word128 0 . (fromIntegral :: Word -> Word64)
 "fromIntegral :: Word32 -> Word128"  fromIntegral = Word128 0 . (fromIntegral :: Word32 -> Word64)
 "fromIntegral :: Word64 -> Word128"  fromIntegral = Word128 0
@@ -189,10 +193,7 @@
 
 compare128 :: Word128 -> Word128 -> Ordering
 compare128 (Word128 a1 a0) (Word128 b1 b0) =
-  case compare a1 b1 of
-    EQ -> compare a0 b0
-    LT -> LT
-    GT -> GT
+  compare a1 b1 <> compare a0 b0
 
 -- -----------------------------------------------------------------------------
 -- Functions for `Enum` instance.
@@ -469,11 +470,11 @@
 
 {-# INLINE sizeOf128# #-}
 sizeOf128# :: Word128 -> Int#
-sizeOf128# _ = 2# *# sizeOf# (undefined :: Word64)
+sizeOf128# _ = 2# *# sizeOf# (0 :: Word64)
 
 {-# INLINE alignment128# #-}
 alignment128# :: Word128 -> Int#
-alignment128# _ = 2# *# alignment# (undefined :: Word64)
+alignment128# _ = 2# *# alignment# (0 :: Word64)
 
 {-# INLINE indexByteArray128# #-}
 indexByteArray128# :: ByteArray# -> Int# -> Word128
diff --git a/src/Data/WideWord/Word256.hs b/src/Data/WideWord/Word256.hs
--- a/src/Data/WideWord/Word256.hs
+++ b/src/Data/WideWord/Word256.hs
@@ -34,11 +34,14 @@
 import Data.Bits (Bits (..), FiniteBits (..), shiftL)
 import Data.Data (Data, Typeable)
 import Data.Ix (Ix)
+#if ! MIN_VERSION_base(4,11,0)
+import Data.Semigroup ((<>))
+#endif
 
 import Foreign.Ptr (Ptr, castPtr)
 import Foreign.Storable (Storable (..))
 
-import GHC.Base (Int (..), and#, int2Word#, minusWord#, not#, or#, plusWord#, plusWord2#
+import GHC.Base (Int (..), and#, minusWord#, not#, or#, plusWord#, plusWord2#
                 , subWordC#, timesWord#, timesWord2#, xor#)
 import GHC.Enum (predError, succError)
 import GHC.Exts ((*#), (+#), Int#, State#, ByteArray#, MutableByteArray#, Addr#)
@@ -51,10 +54,10 @@
 import Data.Primitive.Types (Prim (..), defaultSetByteArray#, defaultSetOffAddr#)
 
 data Word256 = Word256
-  { word256hi :: {-# UNPACK #-} !Word64
-  , word256m1 :: {-# UNPACK #-} !Word64
-  , word256m0 :: {-# UNPACK #-} !Word64
-  , word256lo :: {-# UNPACK #-} !Word64
+  { word256hi :: !Word64
+  , word256m1 :: !Word64
+  , word256m0 :: !Word64
+  , word256lo :: !Word64
   }
   deriving (Eq, Data, Ix, Typeable)
 
@@ -143,16 +146,16 @@
   toInteger = toInteger256
 
 instance Storable Word256 where
-  sizeOf _ = 4 * sizeOf (0 :: Word64)
-  alignment _ = 4 * alignment (0 :: Word64)
+  sizeOf w = I# (sizeOf256# w)
+  alignment w = I# (alignment256# w)
   peek = peek256
   peekElemOff = peekElemOff256
   poke = poke256
   pokeElemOff = pokeElemOff256
 
 instance NFData Word256 where
-  rnf (Word256 a3 a2 a1 a0) =
-    rnf a3 `seq` rnf a2 `seq` rnf a1 `seq` rnf a0
+  -- The fields are already strict and unpacked, so do nothing.
+  rnf !_ = ()
 
 instance Prim Word256 where
   sizeOf#         = sizeOf256#
@@ -182,7 +185,7 @@
 {-# RULES
 "fromIntegral :: Word256 -> Word256" fromIntegral = id :: Word256 -> Word256
 
-"fromIntegral :: Int -> Word256"     fromIntegral = \(I# i#) -> Word256 (W64# 0##) (W64# 0##) (W64# 0##) (W64# (int2Word# i#))
+"fromIntegral :: Int -> Word256"     fromIntegral = Word256 0 0 0 . (fromIntegral :: Int -> Word64)
 "fromIntegral :: Word -> Word256"    fromIntegral = Word256 0 0 0 . (fromIntegral :: Word -> Word64)
 "fromIntegral :: Word32 -> Word256"  fromIntegral = Word256 0 0 0 . (fromIntegral :: Word32 -> Word64)
 "fromIntegral :: Word64 -> Word256"  fromIntegral = Word256 0 0 0
@@ -198,16 +201,7 @@
 
 compare256 :: Word256 -> Word256 -> Ordering
 compare256 (Word256 a3 a2 a1 a0) (Word256 b3 b2 b1 b0) =
-  case compare a3 b3 of
-    LT -> LT
-    GT -> GT
-    EQ -> case compare a2 b2 of
-      LT -> LT
-      GT -> GT
-      EQ -> case compare a1 b1 of
-        LT -> LT
-        GT -> GT
-        EQ -> compare a0 b0
+  compare a3 b3 <> compare a2 b2 <> compare a1 b1 <> compare a0 b0
 
 -- -----------------------------------------------------------------------------
 -- Functions for `Enum` instance.
@@ -543,11 +537,11 @@
 
 {-# INLINE sizeOf256# #-}
 sizeOf256# :: Word256 -> Int#
-sizeOf256# _ = 4# *# sizeOf# (undefined :: Word64)
+sizeOf256# _ = 4# *# sizeOf# (0 :: Word64)
 
 {-# INLINE alignment256# #-}
 alignment256# :: Word256 -> Int#
-alignment256# _ = alignment# (undefined :: Word64)
+alignment256# _ = 4# *# alignment# (0 :: Word64)
 
 {-# INLINE indexByteArray256# #-}
 indexByteArray256# :: ByteArray# -> Int# -> Word256
diff --git a/test/laws.hs b/test/laws.hs
--- a/test/laws.hs
+++ b/test/laws.hs
@@ -55,10 +55,14 @@
   ]
 
 instance Arbitrary Word128 where
-  arbitrary = Word128 <$> arbitrary <*> arbitrary
+  arbitrary =
+    Word128 <$> arbitraryBoundedIntegral <*> arbitraryBoundedIntegral
 
 instance Arbitrary Word256 where
-  arbitrary = Word256 <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
+  arbitrary =
+    Word256
+      <$> arbitraryBoundedIntegral <*> arbitraryBoundedIntegral
+      <*> arbitraryBoundedIntegral <*> arbitraryBoundedIntegral
   shrink x
     | x == 0 = []
     | x == 1 = [0]
diff --git a/wide-word.cabal b/wide-word.cabal
--- a/wide-word.cabal
+++ b/wide-word.cabal
@@ -2,7 +2,7 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                wide-word
-version:             0.1.1.0
+version:             0.1.1.1
 synopsis:            Data types for large but fixed width signed and unsigned integers
 description:
   A library to provide data types for large (ie > 64 bits) but fixed width signed
@@ -24,6 +24,8 @@
 extra-source-files:  ChangeLog.md
 stability:           provisional
 cabal-version:       >= 1.10
+tested-with:         GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.4,
+                     GHC == 8.6.5, GHC == 8.8.3
 
 library
   default-language:   Haskell2010
@@ -36,7 +38,7 @@
                        Data.WideWord.Word256
                        Data.WideWord.Int128
 
-  build-depends:       base                          >= 4.8         && < 4.14
+  build-depends:       base                          >= 4.9         && < 4.14
                      , deepseq                       >= 1.3         && < 1.5
                      , primitive                     >= 0.6.4.0     && < 0.8
 
@@ -67,7 +69,7 @@
   main-is:           laws.hs
   hs-source-dirs:    test
 
-  build-depends:       base                          >= 4.8         && < 5.0
+  build-depends:       base
                      , QuickCheck                    >= 2.9.2       && < 2.14
                      , quickcheck-classes            >= 0.6.3       && < 0.7.0
                      , primitive
