diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,9 @@
 # Revision history for wide-word
 
+## 0.1.7.0 -- 2025-03-07
+
+* Improvements to compare128 for Int128.
+
 ## 0.1.6.0 -- 2023-10-24
 
 * Fixes for shifting/rotating by negative values.
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
@@ -234,7 +234,14 @@
 -- Functions for `Ord` instance.
 
 compare128 :: Int128 -> Int128 -> Ordering
-compare128 a b = compare (toInteger128 a) (toInteger128 b)
+compare128 (Int128 a1 a0) (Int128 b1 b0)
+  | aIsNeg == bIsNeg = compare a1 b1 <> compare a0 b0
+  | bIsNeg = GT
+  | otherwise = LT
+  where
+    aIsNeg = isNeg a1
+    bIsNeg = isNeg b1
+    isNeg = (>= 0x8000000000000000)
 
 -- -----------------------------------------------------------------------------
 -- Functions for `Enum` instance.
diff --git a/test/Test/Data/WideWord/Int128.hs b/test/Test/Data/WideWord/Int128.hs
--- a/test/Test/Data/WideWord/Int128.hs
+++ b/test/Test/Data/WideWord/Int128.hs
@@ -78,20 +78,14 @@
 prop_succ :: Property
 prop_succ =
   propertyCount $ do
-    i128 <- H.forAll genInt128
-    res <- liftIO (fmap toInteger128 <$> tryEvaluate (succ i128))
-    res === if i128 == maxBound
-              then Left "Enum.succ{Int128}: tried to take `succ' of maxBound"
-              else Right (succ $ toInteger128 i128)
+    i128 <- H.forAll $ Gen.filter (< maxBound) genInt128
+    toInteger128 (succ i128) === succ (toInteger128 i128)
 
 prop_pred :: Property
 prop_pred =
   propertyCount $ do
-    i128 <- H.forAll genInt128
-    res <- liftIO (fmap toInteger128 <$> tryEvaluate (pred i128))
-    res === if i128 == minBound
-              then Left "Enum.pred{Int128}: tried to take `pred' of minBound"
-              else Right $ pred (toInteger128 i128)
+    i128 <- H.forAll $ Gen.filter (> minBound) genInt128
+    toInteger128 (pred i128) === pred (toInteger128 i128)
 
 tryEvaluate :: a -> IO (Either String a)
 tryEvaluate x = do
diff --git a/test/Test/Data/WideWord/Word128.hs b/test/Test/Data/WideWord/Word128.hs
--- a/test/Test/Data/WideWord/Word128.hs
+++ b/test/Test/Data/WideWord/Word128.hs
@@ -3,11 +3,9 @@
   ( tests
   ) where
 
-import           Control.Exception (ArithException, SomeException, evaluate, try)
 import           Control.Monad.IO.Class (liftIO)
 import           Control.Monad (unless)
 
-import           Data.Bifunctor (first)
 import qualified Data.Binary as Binary
 import           Data.Bits ((.&.), (.|.), bit, complement, countLeadingZeros, countTrailingZeros
                             , popCount, rotateL, rotateR, shiftL, shiftR, testBit, xor)
@@ -85,27 +83,14 @@
 prop_succ :: Property
 prop_succ =
   propertyCount $ do
-    w128 <- H.forAll genWord128
-    res <- liftIO (fmap toInteger128 <$> tryEvaluate (succ w128))
-    res === if w128 == maxBound
-              then Left "Enum.succ{Word128}: tried to take `succ' of maxBound"
-              else Right (succ $ toInteger128 w128)
+    w128 <- H.forAll $ Gen.filter (< maxBound) genWord128
+    toInteger128 (succ w128) === succ (toInteger128 w128)
 
 prop_pred :: Property
 prop_pred =
   propertyCount $ do
-    w128 <- H.forAll genWord128
-    res <- liftIO (fmap toInteger128 <$> tryEvaluate (pred w128))
-    res === if w128 == 0
-              then Left "Enum.pred{Word128}: tried to take `pred' of minBound"
-              else Right $ pred (toInteger128 w128)
-
-tryEvaluate :: a -> IO (Either String a)
-tryEvaluate x = do
-  first renderException <$> try (evaluate x)
-  where
-    renderException :: SomeException -> String
-    renderException = show
+    w128 <- H.forAll $ Gen.filter (> 0) genWord128
+    toInteger128 (pred w128) === pred (toInteger128 w128)
 
 prop_toEnum_fromEnum :: Property
 prop_toEnum_fromEnum =
@@ -382,9 +367,6 @@
 
 toInteger128 :: Word128 -> Integer
 toInteger128 = toInteger
-
-showArithException :: ArithException -> String
-showArithException = show
 
 -- -----------------------------------------------------------------------------
 
diff --git a/test/Test/Data/WideWord/Word64.hs b/test/Test/Data/WideWord/Word64.hs
--- a/test/Test/Data/WideWord/Word64.hs
+++ b/test/Test/Data/WideWord/Word64.hs
@@ -83,7 +83,7 @@
 prop_pred :: Property
 prop_pred =
   propertyCount $ do
-    w64 <- H.forAll genWord64
+    w64 <- H.forAll $ Gen.filter (> 0) genWord64
     res <- liftIO (fmap toInteger64 <$> tryEvaluate (pred w64))
     res === if w64 == 0
               then Left "Enum.pred{Word64}: tried to take `pred' of minBound"
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.6.0
+version:             0.1.7.0
 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
@@ -25,7 +25,8 @@
 stability:           provisional
 cabal-version:       >= 1.10
 tested-with:         GHC == 8.4.4, GHC == 8.6.5, GHC == 8.8.4, GHC == 8.10.7, GHC == 9.0.2,
-                     GHC == 9.2.4, GHC == 9.4.7, GHC == 9.6.2, GHC == 9.8.1
+                     GHC == 9.2.4, GHC == 9.4.7, GHC == 9.6.6, GHC == 9.8.4, GHC == 9.10.1,
+                     GHC == 9.12.1
 
 library
   default-language:   Haskell2010
@@ -41,14 +42,18 @@
 
   other-modules:       Data.WideWord.Compat
 
-  build-depends:       base                          >= 4.9         && < 4.20
+  build-depends:       base                          >= 4.9         && < 4.22
                      , binary                        >= 0.8.3.0     && < 0.9
                      , deepseq                       >= 1.4.2.0     && < 1.6
                      -- Required so that GHC.IntWord64 is available on 32 bit systems
                      , ghc-prim
                      , primitive                     >= 0.6.4.0     && < 0.10
-                     , hashable                      >= 1.2         && < 1.5
+                     , hashable                      >= 1.2         && < 1.6
 
+  -- This required to get around a cabal dependency solver bug.
+  if impl (ghc >= 9.12)
+    build-depends:     aeson                          >= 2
+
 test-suite test
   default-language:   Haskell2010
   ghc-options:        -Wall -fwarn-tabs -threaded -O2
@@ -64,9 +69,9 @@
 
   build-depends:       base
                      , binary
-                     , bytestring                    >= 0.10 && < 0.13
+                     , bytestring                    >= 0.10
                      , ghc-prim
-                     , hedgehog                      >= 1.0 && < 1.5
+                     , hedgehog                      >= 1.0 && < 1.6
                      , primitive
                      , wide-word
 
@@ -79,7 +84,7 @@
   hs-source-dirs:    test
 
   build-depends:       base
-                     , QuickCheck                    >= 2.9.2       && < 2.15
+                     , QuickCheck                    >= 2.9.2       && < 2.16
                      , quickcheck-classes            >= 0.6.3       && < 0.7.0
                      , primitive
                      , semirings                     >= 0.2         && < 0.8
