diff --git a/Control/Monad/Primitive.hs b/Control/Monad/Primitive.hs
--- a/Control/Monad/Primitive.hs
+++ b/Control/Monad/Primitive.hs
@@ -44,7 +44,9 @@
 primitive_ :: PrimMonad m
               => (State# (PrimState m) -> State# (PrimState m)) -> m ()
 {-# INLINE primitive_ #-}
-primitive_ f = primitive (\s# -> (# f s#, () #))
+primitive_ f = primitive (\s# ->
+    case f s# of
+        s'# -> (# s'#, () #))
 
 instance PrimMonad IO where
   type PrimState IO = RealWorld
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,11 @@
+## Changes in version 0.5.4.0
+
+ * Changed primitive_ to work around an oddity with GHC's code generation
+   on certain versions that led to side effects not happening when used
+   in conjunction with certain very unsafe IO performers.
+
+ * Allow primitive to build on GHC 7.9
+
 ## Changes in version 0.5.3.0
 
  * Implement `cloneArray` and `cloneMutableArray` primitives
diff --git a/primitive.cabal b/primitive.cabal
--- a/primitive.cabal
+++ b/primitive.cabal
@@ -1,10 +1,10 @@
 Name:           primitive
-Version:        0.5.3.0
+Version:        0.5.4.0
 License:        BSD3
 License-File:   LICENSE
 
 Author:         Roman Leshchinskiy <rl@cse.unsw.edu.au>
-Maintainer:     Roman Leshchinskiy <rl@cse.unsw.edu.au>
+Maintainer:     libraries@haskell.org
 Copyright:      (c) Roman Leshchinskiy 2009-2012
 Homepage:       https://github.com/haskell/primitive
 Bug-Reports:    https://github.com/haskell/primitive/issues
@@ -36,7 +36,7 @@
         Data.Primitive.Internal.Compat
         Data.Primitive.Internal.Operations
 
-  Build-Depends: base >= 4.3 && < 4.8, ghc-prim >= 0.2 && < 0.4
+  Build-Depends: base >= 4.3 && < 4.9, ghc-prim >= 0.2 && < 0.4
 
   Ghc-Options: -O2 -Wall
 
@@ -49,6 +49,16 @@
       cc-options: -ftree-vectorize
   if arch(i386) || arch(x86_64)
       cc-options: -msse2
+
+test-suite test
+  Default-Language: Haskell2010
+  hs-source-dirs: test
+  main-is: main.hs
+  type: exitcode-stdio-1.0
+  build-depends: base
+               , ghc-prim
+               , primitive
+  ghc-options: -O2
 
 source-repository head
   type:     git
diff --git a/test/main.hs b/test/main.hs
new file mode 100644
--- /dev/null
+++ b/test/main.hs
@@ -0,0 +1,24 @@
+{-# LANGUAGE MagicHash, UnboxedTuples #-}
+import Control.Monad.Primitive
+import Data.Primitive.Array
+import GHC.IO
+import GHC.Prim
+
+-- Since we only have a single test case right now, I'm going to avoid the
+-- issue of choosing a test framework for the moment. This also keeps the
+-- package as a whole light on dependencies.
+
+main :: IO ()
+main = do
+    arr <- newArray 1 'A'
+    let unit =
+            case writeArray arr 0 'B' of
+                IO f ->
+                    case f realWorld# of
+                        _ -> ()
+    c1 <- readArray arr 0
+    return $! unit
+    c2 <- readArray arr 0
+    if c1 == 'A' && c2 == 'B'
+        then return ()
+        else error $ "Expected AB, got: " ++ show (c1, c2)
