diff --git a/ghc/compiler/prelude/PrimOp.lhs b/ghc/compiler/prelude/PrimOp.lhs
index 24bd867afd91289858efe9fbfaa3d90b1b8fb77c..5535f9759f311207e8c72cfbc90cc2daae1854d5 100644
--- a/ghc/compiler/prelude/PrimOp.lhs
+++ b/ghc/compiler/prelude/PrimOp.lhs
@@ -1967,36 +1967,56 @@ primOpOutOfLine op
 	_           		-> False
 \end{code}
 
+
+primOpOkForSpeculation
+~~~~~~~~~~~~~~~~~~~~~~
 Sometimes we may choose to execute a PrimOp even though it isn't
 certain that its result will be required; ie execute them
 ``speculatively''.  The same thing as ``cheap eagerness.'' Usually
 this is OK, because PrimOps are usually cheap, but it isn't OK for
 (a)~expensive PrimOps and (b)~PrimOps which can fail.
 
+PrimOps that have side effects also should not be executed speculatively.
+
+Ok-for-speculation also means that it's ok *not* to execute the
+primop. For example
+	case op a b of
+	  r -> 3
+Here the result is not used, so we can discard the primop.  Anything
+that has side effects mustn't be dicarded in this way, of course!
+
 See also @primOpIsCheap@ (below).
 
-PrimOps that have side effects also should not be executed speculatively
-or by data dependencies.
 
 \begin{code}
 primOpOkForSpeculation :: PrimOp -> Bool
+	-- See comments with CoreUtils.exprOkForSpeculation
 primOpOkForSpeculation op 
   = not (primOpCanFail op || primOpHasSideEffects op || primOpOutOfLine op)
 \end{code}
 
+
+primOpIsCheap
+~~~~~~~~~~~~~
 @primOpIsCheap@, as used in \tr{SimplUtils.lhs}.  For now (HACK
 WARNING), we just borrow some other predicates for a
 what-should-be-good-enough test.  "Cheap" means willing to call it more
 than once.  Evaluation order is unaffected.
 
 \begin{code}
+primOpIsCheap :: PrimOp -> Bool
+	-- See comments with CoreUtils.exprOkForSpeculation
 primOpIsCheap op = not (primOpHasSideEffects op || primOpOutOfLine op)
 \end{code}
 
+primOpIsDupable
+~~~~~~~~~~~~~~~
 primOpIsDupable means that the use of the primop is small enough to
 duplicate into different case branches.  See CoreUtils.exprIsDupable.
 
 \begin{code}
+primOpIsDupable :: PrimOp -> Bool
+	-- See comments with CoreUtils.exprIsDupable
 primOpIsDupable (CCallOp _ _ might_gc _) = not might_gc
 	-- If the ccall can't GC then the call is pretty cheap, and
 	-- we're happy to duplicate
@@ -2035,11 +2055,6 @@ duplicated.
 \begin{code}
 primOpHasSideEffects :: PrimOp -> Bool
 
-primOpHasSideEffects TakeMVarOp        = True
-primOpHasSideEffects DelayOp           = True
-primOpHasSideEffects WaitReadOp        = True
-primOpHasSideEffects WaitWriteOp       = True
-
 primOpHasSideEffects ParOp	       = True
 primOpHasSideEffects ForkOp	       = True
 primOpHasSideEffects KillThreadOp      = True
@@ -2056,6 +2071,27 @@ primOpHasSideEffects MakeStableNameOp  = True
 primOpHasSideEffects EqStablePtrOp     = True  -- SOF
 primOpHasSideEffects DeRefStablePtrOp  = True  -- ??? JSM & ADR
 
+-- In general, writes are considered a side effect, but 
+--	reads and variable allocations are not
+-- Why?  Because writes must not be omitted, but reads can be if their result is not used.
+-- (Sequencing of reads is maintained by data dependencies on the resulting
+-- world state.)
+primOpHasSideEffects WriteArrayOp	   = True
+primOpHasSideEffects (WriteByteArrayOp _)  = True
+primOpHasSideEffects (WriteOffAddrOp _)	   = True
+primOpHasSideEffects WriteMutVarOp	   = True
+
+primOpHasSideEffects UnsafeFreezeArrayOp	= True
+primOpHasSideEffects UnsafeFreezeByteArrayOp	= True
+primOpHasSideEffects UnsafeThawArrayOp		= True
+primOpHasSideEffects UnsafeThawByteArrayOp	= True
+
+primOpHasSideEffects TakeMVarOp        = True
+primOpHasSideEffects PutMVarOp         = True
+primOpHasSideEffects DelayOp           = True
+primOpHasSideEffects WaitReadOp        = True
+primOpHasSideEffects WaitWriteOp       = True
+
 primOpHasSideEffects ParGlobalOp	= True
 primOpHasSideEffects ParLocalOp		= True
 primOpHasSideEffects ParAtOp		= True