diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -17,6 +17,8 @@
 instruction set, a very slow emulated version of these operations is
 provided instead.
 
+Note `ghc-8.4.1` is required to target the BMI2 CPU instructions.
+
 ## Compilation
 
 It is sufficient to build, test and benchmark the library as follows
@@ -255,3 +257,13 @@
 ## Reference
 
 * [Bit Manipulation Instruction Sets (Wikipedia)](https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets)
+* [GHC differential D4236](https://phabricator.haskell.org/D4236)
+
+## Acknowledgement
+
+A lot of people helped in the writing of this library and the underlying GHC patch:
+
+* Ben Gamari
+* Moritz Angermann
+* Alex Mason
+* Moritz Kiefer
diff --git a/bits-extra.cabal b/bits-extra.cabal
--- a/bits-extra.cabal
+++ b/bits-extra.cabal
@@ -2,10 +2,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 2b16093c79f84feabd7fb8a6c4c36ce7e5cfdcf7aa6a2c48d7d3d84d3166701b
+-- hash: 547b5605d3febfb841362a7a119ad0091b5184712d7fdb7698dc5ae94e7f4249
 
 name:           bits-extra
-version:        0.0.0.1
+version:        0.0.0.2
 description:    Please see the README on Github at <https://github.com/haskell-works/bits-extra#readme>
 homepage:       https://github.com/haskell-works/bits-extra#readme
 bug-reports:    https://github.com/haskell-works/bits-extra/issues
@@ -35,7 +35,7 @@
       src
   ghc-options: -Wall -O2
   build-depends:
-      base >=4.11 && <5
+      base >=4.7 && <5
     , ghc-prim
   if (flag(bmi2)) && (impl(ghc >=8.4.1))
     ghc-options: -mbmi2 -msse4.2
@@ -46,6 +46,8 @@
       Data.Bits.Pext
       Data.Bits.Pext.Slow
   other-modules:
+      Data.Bits.Pdep.Prim
+      Data.Bits.Pext.Prim
       Paths_bits_extra
   default-language: Haskell2010
 
diff --git a/src/Data/Bits/Pdep.hs b/src/Data/Bits/Pdep.hs
--- a/src/Data/Bits/Pdep.hs
+++ b/src/Data/Bits/Pdep.hs
@@ -6,49 +6,37 @@
   , fastPdepEnabled
   ) where
 
-import GHC.Prim
 import GHC.Word
 
+import qualified Data.Bits.Pdep.Prim as P
+
 -- | Bitwise parallel deposit.  Deposits bits from the source at the locations
 -- described by the mask.
 class Pdep a where
   pdep :: a -> a -> a
 
 instance Pdep Word where
-  pdep (W#   src#) (W#   mask#) = W#   (pdep#   src# mask#)
+  pdep = P.primPdep
   {-# INLINE pdep #-}
 
 instance Pdep Word8 where
-  pdep src mask = fromIntegral (pdep (fromIntegral src) (fromIntegral mask) :: Word32)
+  pdep = P.primPdep8
   {-# INLINE pdep #-}
 
 instance Pdep Word16 where
-  pdep src mask = fromIntegral (pdep (fromIntegral src) (fromIntegral mask) :: Word32)
+  pdep = P.primPdep16
   {-# INLINE pdep #-}
 
-#if MIN_VERSION_base(4,11,0)
 instance Pdep Word32 where
-  pdep (W32# src#) (W32# mask#) = W32# (pdep32# src# mask#)
+  pdep = P.primPdep32
   {-# INLINE pdep #-}
 
 instance Pdep Word64 where
-  pdep (W64# src#) (W64# mask#) = W64# (pdep64# src# mask#)
-  {-# INLINE pdep #-}
-#else
-instance Pdep Word32 where
-  pdep = slowPdep
+  pdep = P.primPdep64
   {-# INLINE pdep #-}
 
-instance Pdep Word64 where
-  pdep = slowPdep
-  {-# INLINE pdep #-}
-#endif
-
 -- | Runtime flag indicating whether the 'pdep' function is using the high-performance.
 -- BMI2 instruction set.  A value of `False` indicates that `pdep` is emulated.
 fastPdepEnabled :: Bool
-#if MIN_VERSION_base(4,11,0) && defined(BMI2_ENABLED)
-fastPdepEnabled = True
-#else
-fastPdepEnabled = False
-#endif
+fastPdepEnabled = P.fastPdepEnabled
+{-# INLINE fastPdepEnabled #-}
diff --git a/src/Data/Bits/Pdep/Prim.hs b/src/Data/Bits/Pdep/Prim.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Bits/Pdep/Prim.hs
@@ -0,0 +1,57 @@
+{-# LANGUAGE CPP       #-}
+{-# LANGUAGE MagicHash #-}
+
+module Data.Bits.Pdep.Prim
+  ( primPdep
+  , primPdep8
+  , primPdep16
+  , primPdep32
+  , primPdep64
+  , fastPdepEnabled
+  ) where
+
+import GHC.Word
+
+#if MIN_VERSION_base(4,11,0) && defined(BMI2_ENABLED)
+import GHC.Prim
+#else
+import Data.Bits.Pdep.Slow
+#endif
+
+primPdep :: Word -> Word -> Word
+primPdep src mask = fromIntegral (primPdep64 (fromIntegral src) (fromIntegral mask))
+{-# INLINE primPdep #-}
+
+primPdep64 :: Word64 -> Word64 -> Word64
+#if MIN_VERSION_base(4,11,0) && defined(BMI2_ENABLED)
+primPdep64 (W64# src#) (W64# mask#) = W64# (pdep64# src# mask#)
+#else
+primPdep64 = slowPdep
+#endif
+{-# INLINE primPdep64 #-}
+
+primPdep32 :: Word32 -> Word32 -> Word32
+#if MIN_VERSION_base(4,11,0) && defined(BMI2_ENABLED)
+primPdep32 (W32# src#) (W32# mask#) = W32# (pdep32# src# mask#)
+#else
+primPdep32 = slowPdep
+#endif
+{-# INLINE primPdep32 #-}
+
+primPdep16 :: Word16 -> Word16 -> Word16
+primPdep16 src mask = fromIntegral (primPdep32 (fromIntegral src) (fromIntegral mask))
+{-# INLINE primPdep16 #-}
+
+primPdep8 :: Word8 -> Word8 -> Word8
+primPdep8 src mask = fromIntegral (primPdep32 (fromIntegral src) (fromIntegral mask))
+{-# INLINE primPdep8 #-}
+
+-- | Runtime flag indicating whether the 'pdep' function is using the high-performance.
+-- BMI2 instruction set.  A value of `False` indicates that `pdep` is emulated.
+fastPdepEnabled :: Bool
+#if MIN_VERSION_base(4,11,0) && defined(BMI2_ENABLED)
+fastPdepEnabled = True
+#else
+fastPdepEnabled = False
+#endif
+{-# INLINE fastPdepEnabled #-}
diff --git a/src/Data/Bits/Pext.hs b/src/Data/Bits/Pext.hs
--- a/src/Data/Bits/Pext.hs
+++ b/src/Data/Bits/Pext.hs
@@ -6,49 +6,37 @@
   , fastPextEnabled
   ) where
 
-import GHC.Prim
 import GHC.Word
 
--- | Bitwise parallel extract.  Extract bits from the source at the locations
+import qualified Data.Bits.Pext.Prim as P
+
+-- | Bitwise parallel extosit.  extosits bits from the source at the locations
 -- described by the mask.
 class Pext a where
   pext :: a -> a -> a
 
 instance Pext Word where
-  pext (W#   src#) (W#   mask#) = W#   (pext#   src# mask#)
+  pext = P.primPext
   {-# INLINE pext #-}
 
 instance Pext Word8 where
-  pext src mask = fromIntegral (pext (fromIntegral src) (fromIntegral mask) :: Word32)
+  pext = P.primPext8
   {-# INLINE pext #-}
 
 instance Pext Word16 where
-  pext src mask = fromIntegral (pext (fromIntegral src) (fromIntegral mask) :: Word32)
+  pext = P.primPext16
   {-# INLINE pext #-}
 
-#if MIN_VERSION_base(4,11,0)
 instance Pext Word32 where
-  pext (W32# src#) (W32# mask#) = W32# (pext32# src# mask#)
+  pext = P.primPext32
   {-# INLINE pext #-}
 
 instance Pext Word64 where
-  pext (W64# src#) (W64# mask#) = W64# (pext64# src# mask#)
-  {-# INLINE pext #-}
-#else
-instance Pext Word32 where
-  pext = slowPext
+  pext = P.primPext64
   {-# INLINE pext #-}
 
-instance Pext Word64 where
-  pext = slowPext
-  {-# INLINE pext #-}
-#endif
-
 -- | Runtime flag indicating whether the 'pext' function is using the high-performance.
 -- BMI2 instruction set.  A value of `False` indicates that `pext` is emulated.
 fastPextEnabled :: Bool
-#if MIN_VERSION_base(4,11,0) && defined(BMI2_ENABLED)
-fastPextEnabled = True
-#else
-fastPextEnabled = False
-#endif
+fastPextEnabled = P.fastPextEnabled
+{-# INLINE fastPextEnabled #-}
diff --git a/src/Data/Bits/Pext/Prim.hs b/src/Data/Bits/Pext/Prim.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Bits/Pext/Prim.hs
@@ -0,0 +1,57 @@
+{-# LANGUAGE CPP       #-}
+{-# LANGUAGE MagicHash #-}
+
+module Data.Bits.Pext.Prim
+  ( primPext
+  , primPext8
+  , primPext16
+  , primPext32
+  , primPext64
+  , fastPextEnabled
+  ) where
+
+import GHC.Word
+
+#if MIN_VERSION_base(4,11,0) && defined(BMI2_ENABLED)
+import GHC.Prim
+#else
+import Data.Bits.Pext.Slow
+#endif
+
+primPext :: Word -> Word -> Word
+primPext src mask = fromIntegral (primPext64 (fromIntegral src) (fromIntegral mask))
+{-# INLINE primPext #-}
+
+primPext64 :: Word64 -> Word64 -> Word64
+#if MIN_VERSION_base(4,11,0) && defined(BMI2_ENABLED)
+primPext64 (W64# src#) (W64# mask#) = W64# (pext64# src# mask#)
+#else
+primPext64 = slowPext
+#endif
+{-# INLINE primPext64 #-}
+
+primPext32 :: Word32 -> Word32 -> Word32
+#if MIN_VERSION_base(4,11,0) && defined(BMI2_ENABLED)
+primPext32 (W32# src#) (W32# mask#) = W32# (pext32# src# mask#)
+#else
+primPext32 = slowPext
+#endif
+{-# INLINE primPext32 #-}
+
+primPext16 :: Word16 -> Word16 -> Word16
+primPext16 src mask = fromIntegral (primPext32 (fromIntegral src) (fromIntegral mask))
+{-# INLINE primPext16 #-}
+
+primPext8 :: Word8 -> Word8 -> Word8
+primPext8 src mask = fromIntegral (primPext32 (fromIntegral src) (fromIntegral mask))
+{-# INLINE primPext8 #-}
+
+-- | Runtime flag indicating whether the 'pext' function is using the high-performance.
+-- BMI2 instruction set.  A value of `False` indicates that `pext` is emulated.
+fastPextEnabled :: Bool
+#if MIN_VERSION_base(4,11,0) && defined(BMI2_ENABLED)
+fastPextEnabled = True
+#else
+fastPextEnabled = False
+#endif
+{-# INLINE fastPextEnabled #-}
