diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index 5654c66..c615efd 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -2388,6 +2388,16 @@ noce_mem_write_may_trap_or_fault_p (const_rtx mem)
   return false;
 }
 
+/* Return TRUE if INSN is a volatile insn or a non const call.  */
+
+static inline bool
+volatile_or_non_const_call (rtx insn)
+{
+  return (INSN_P (insn)
+	  && (volatile_insn_p (PATTERN (insn))
+	      || (CALL_P (insn) && (!RTL_CONST_CALL_P (insn)))));
+}
+
 /* Return whether we can use store speculation for MEM.  TOP_BB is the
    basic block above the conditional block where we are considering
    doing the speculative store.  We look for whether MEM is set
@@ -2410,13 +2420,47 @@ noce_can_store_speculate_p (basic_block top_bb, const_rtx mem)
 	     have to stop looking.  Even if the MEM is set later in
 	     the function, we still don't want to set it
 	     unconditionally before the barrier.  */
-	  if (INSN_P (insn)
-	      && (volatile_insn_p (PATTERN (insn))
-		  || (CALL_P (insn) && (!RTL_CONST_CALL_P (insn)))))
+	  if (volatile_or_non_const_call (insn))
 	    return false;
 
+	  /* We can speculate if the MEM will be set on every path out
+	     of TOP_BB, but we must be careful that there is no
+	     intervening call/volatile between TOP_BB and the set.
+
+	     For the intervening call/volatile case, We are looking
+	     for something akin to:
+
+	        location of considered if-conversion on mem
+		if (condition)
+		  call ();
+		mem = something;  */
 	  if (memory_must_be_modified_in_insn_p (mem, insn))
-	    return true;
+	    {
+	      if (!dom_info_available_p (CDI_DOMINATORS))
+		calculate_dominance_info (CDI_DOMINATORS);
+
+	      /* Get all blocks that are post-dominated by the SET.  */
+	      VEC (basic_block, heap) *bbs =
+		get_all_dominated_blocks (CDI_POST_DOMINATORS,
+					  BLOCK_FOR_INSN (insn));
+	      while (VEC_length (basic_block, bbs))
+		{
+		  rtx call;
+		  basic_block bb = VEC_pop (basic_block, bbs);
+
+		  /* If there is an intervening volatile/call between
+		     TOP_BB and the SET of MEM, bail.  */
+		  FOR_BB_INSNS (bb, call)
+		    if (volatile_or_non_const_call (call)
+			&& dominated_by_p (CDI_DOMINATORS,
+					   BLOCK_FOR_INSN (call),
+					   top_bb))
+		      return false;
+		}
+	      VEC_free (basic_block, heap, bbs);
+	      return true;
+	    }
+
 	  if (modified_in_p (XEXP (mem, 0), insn))
 	    return false;
 
