diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-13.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-13.c
new file mode 100644
index 0000000..827e4dc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-13.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-sink" } */
+
+extern void bar ();
+
+float foo (int call)
+{
+  float a, b, c;
+
+  a = b + c;
+  if (!call)
+    ;
+  else
+    {
+      bar ();
+      b = c * 2;
+      a = b + c;
+    }
+
+  return a;
+}
+
+/* a = b + c, potentially trapping, should not be sunk to the if block.  */
+
+/* { dg-final { scan-tree-dump-times "Sinking" 0 "sink" } } */
+/* { dg-final { cleanup-tree-dump "sink" } } */
diff --git a/gcc/tree-ssa-sink.c b/gcc/tree-ssa-sink.c
index d7fd159..d28e854 100644
--- a/gcc/tree-ssa-sink.c
+++ b/gcc/tree-ssa-sink.c
@@ -290,6 +290,11 @@ statement_sink_location (gimple stmt, basic_block frombb,
 
      We can't sink statements that have volatile operands.
 
+     We can't sink !load-or-store statements that could trap out of the
+     dominating path to statements with side effects and we don't compute the
+     latter part.  Trapping load/stores are acceptable as they call for
+     arbitrary behavior anyway.
+
      We don't want to sink dead code, so anything with 0 immediate uses is not
      sunk.
 
@@ -302,6 +307,8 @@ statement_sink_location (gimple stmt, basic_block frombb,
   if (stmt_ends_bb_p (stmt)
       || gimple_has_side_effects (stmt)
       || gimple_has_volatile_ops (stmt)
+      || (!gimple_vdef (stmt) && !gimple_vuse (stmt)
+	  && gimple_could_trap_p (stmt))
       || (cfun->has_local_explicit_reg_vars
 	  && TYPE_MODE (TREE_TYPE (gimple_assign_lhs (stmt))) == BLKmode))
     return false;
