diff --git a/src/Expr.hs b/src/Expr.hs
index 3d0023556d8344a9f1e71e7b409285fa3aa88f8d..a1ad5379ed2e57882c8ff0f9c777d3216fc73c08 100644
--- a/src/Expr.hs
+++ b/src/Expr.hs
@@ -231,8 +231,8 @@ genExpr' _width = sized gen
         [ binOp EAdd
         , binOp ESub
         , binOp EMul
-        , divOp EQuot
-        , divOp ERem
+        , quotOp
+        , remOp
         , ENegate <$> arbitrary
         ]
 
@@ -267,7 +267,20 @@ genExpr' _width = sized gen
         ELit <$> chooseNumber (0, fromIntegral $ widthBits (knownWidth @width) - 1)
     subexpr2 = scale (`div` 2) genExpr
     binOp f = f <$> subexpr2 <*> subexpr2
-    divOp f = f <$> arbitrary <*> subexpr2 <*> nonzero subexpr2
+    quotOp = do
+        signedness <- arbitrary
+        num <- subexpr2
+        let num' = interpret num
+            -- divisions where the result overflows the expression width
+            -- (e.g. (-128::W8) / (-1::W8)) are undefined.
+            -- See test-primops#1.
+            okay_denom denom
+              | Signed <- signedness =
+                  num' /= maxBound || interpret denom /= maxBound
+              | otherwise = True
+        denom <- suchThat (nonzero subexpr2) okay_denom
+        return $ EQuot signedness num denom
+    remOp = ERem <$> arbitrary <*> subexpr2 <*> nonzero subexpr2
     nonzero = flip suchThat $ \x -> interpret x /= 0
 
 -- * SomeExpr
diff --git a/src/Number.hs b/src/Number.hs
index 0d58fe15fbbe6e1cbd7f5e0065aff3fa69668a8e..c236a967343a64c2fa306d85dacf4dd726f091be 100644
--- a/src/Number.hs
+++ b/src/Number.hs
@@ -143,6 +143,7 @@ instance (KnownWidth width) => Enum (Number width) where
       | n > maxBound = error "overflow"
       | otherwise    = n
 
+-- | Unsigned range.
 instance (KnownWidth width) => Bounded (Number width) where
     minBound = Number 0
     maxBound = Number ((1 `shiftL` widthBits (knownWidth @width)) - 1)