diff --git a/rts/HeapStackCheck.cmm b/rts/HeapStackCheck.cmm
index 983100a1ea74b1b2dd246666dfeaea501a52b4ac..49760b4f22be7378b7f77a6a3e883db1a632d6a3 100644
--- a/rts/HeapStackCheck.cmm
+++ b/rts/HeapStackCheck.cmm
@@ -99,9 +99,10 @@ import CLOSURE stg_stack_save_entries;
  * the stack is already too big.
  */
 
-#define PRE_RETURN(why,what_next)                       \
-  StgTSO_what_next(CurrentTSO) = what_next::I16;        \
-  StgRegTable_rRet(BaseReg) = why;                      \
+// N.B. the access to what_next may synchronize with throwToMsg
+#define PRE_RETURN(why,what_next)                           \
+  %relaxed StgTSO_what_next(CurrentTSO) = what_next::I16;   \
+  StgRegTable_rRet(BaseReg) = why;                          \
   R1 = BaseReg;
 
 /* Remember that the return address is *removed* when returning to a
diff --git a/rts/Schedule.c b/rts/Schedule.c
index d83a6adfe67fca2057afd9efc267dbdd68dfbc07..9535bbd2311e3e1722fd8fee9ae06fbe5c540218 100644
--- a/rts/Schedule.c
+++ b/rts/Schedule.c
@@ -2495,7 +2495,7 @@ suspendThread (StgRegTable *reg, bool interruptible)
   traceEventStopThread(cap, tso, THREAD_SUSPENDED_FOREIGN_CALL, 0);
 
   // XXX this might not be necessary --SDM
-  tso->what_next = ThreadRunGHC;
+  RELAXED_STORE(&tso->what_next, ThreadRunGHC);
 
   threadPaused(cap,tso);
 
diff --git a/rts/StgStartup.cmm b/rts/StgStartup.cmm
index f69c0dea8720fbe31e2bf3f0a4a79928fdd573e4..51ea545a8c8b7dd70669ff4b62d3dd3001493967 100644
--- a/rts/StgStartup.cmm
+++ b/rts/StgStartup.cmm
@@ -77,9 +77,9 @@ INFO_TABLE_RET(stg_stop_thread, STOP_FRAME,
 
     Sp = Sp + SIZEOF_StgStopFrame - SIZEOF_StgDeadThreadFrame;
     SET_HDR(Sp, stg_dead_thread_info, CCS_SYSTEM);
-    StgDeadThreadFrame_result(Sp) = R1;
+    %release StgDeadThreadFrame_result(Sp) = R1;
 
-    StgTSO_what_next(CurrentTSO) = ThreadComplete::I16;
+    %relaxed StgTSO_what_next(CurrentTSO) = ThreadComplete::I16;
 
     SAVE_THREAD_STATE();