diff --git a/gcc/testsuite/gcc.dg/torture/pr93491.c b/gcc/testsuite/gcc.dg/torture/pr93491.c
new file mode 100644
index 0000000000000000000000000000000000000000..2cb4c0ca7afe5da7fc5a13bb592682ddd65effb1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr93491.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+
+extern void exit (int);
+
+__attribute__((noipa))
+void f(int i)
+{
+  exit(i);
+}
+
+__attribute__((const,noipa))
+int g(int i)
+{
+  return 1 / i;
+}
+
+int main()
+{
+  while (1)
+    {
+      f(0);
+      f(g(0));
+    }
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr88087.c b/gcc/testsuite/gcc.dg/tree-ssa/pr88087.c
index d0061b61aedb0e11792f90ac81424b478b298aff..c48dba5bf21c339197d337b616f5fd71a08cd45e 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr88087.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr88087.c
@@ -1,17 +1,17 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-pre-stats" } */
+/* { dg-options "-O2 -fno-code-hoisting -fdump-tree-pre-stats" } */
 
 int f();
 int d;
-void c()
+void c(int x)
 {
-  for (;;)
-    {
-      f();
-      int (*fp)() __attribute__((const)) = (void *)f;
-      d = fp();
-    }
+  int (*fp)() __attribute__((const)) = (void *)f;
+  if (x)
+    d = fp ();
+  int tem = fp ();
+  f();
+  d = tem;
 }
 
-/* We shouldn't ICE and hoist the const call of fp out of the loop.  */
+/* We shouldn't ICE and PRE the const call.  */
 /* { dg-final { scan-tree-dump "Eliminated: 1" "pre" } } */
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index ebe95cc6c73f0540db5986869f8d89816df470a4..769aadb2315ab39acab82d26397443e94a918d52 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -3957,6 +3957,7 @@ compute_avail (function *fun)
 
       /* Now compute value numbers and populate value sets with all
 	 the expressions computed in BLOCK.  */
+      bool set_bb_may_notreturn = false;
       for (gimple_stmt_iterator gsi = gsi_start_bb (block); !gsi_end_p (gsi);
 	   gsi_next (&gsi))
 	{
@@ -3965,6 +3966,12 @@ compute_avail (function *fun)
 
 	  stmt = gsi_stmt (gsi);
 
+	  if (set_bb_may_notreturn)
+	    {
+	      BB_MAY_NOTRETURN (block) = 1;
+	      set_bb_may_notreturn = false;
+	    }
+
 	  /* Cache whether the basic-block has any non-visible side-effect
 	     or control flow.
 	     If this isn't a call or it is the last stmt in the
@@ -3976,10 +3983,12 @@ compute_avail (function *fun)
 		 that forbids hoisting possibly trapping expressions
 		 before it.  */
 	      int flags = gimple_call_flags (stmt);
-	      if (!(flags & ECF_CONST)
+	      if (!(flags & (ECF_CONST|ECF_PURE))
 		  || (flags & ECF_LOOPING_CONST_OR_PURE)
 		  || stmt_can_throw_external (fun, stmt))
-		BB_MAY_NOTRETURN (block) = 1;
+		/* Defer setting of BB_MAY_NOTRETURN to avoid it
+		   influencing the processing of the call itself.  */
+		set_bb_may_notreturn = true;
 	    }
 
 	  FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF)
@@ -4030,11 +4039,16 @@ compute_avail (function *fun)
 		/* If the value of the call is not invalidated in
 		   this block until it is computed, add the expression
 		   to EXP_GEN.  */
-		if (!gimple_vuse (stmt)
-		    || gimple_code
-		         (SSA_NAME_DEF_STMT (gimple_vuse (stmt))) == GIMPLE_PHI
-		    || gimple_bb (SSA_NAME_DEF_STMT
-				    (gimple_vuse (stmt))) != block)
+		if ((!gimple_vuse (stmt)
+		     || gimple_code
+			  (SSA_NAME_DEF_STMT (gimple_vuse (stmt))) == GIMPLE_PHI
+		     || gimple_bb (SSA_NAME_DEF_STMT
+				   (gimple_vuse (stmt))) != block)
+		    /* If the REFERENCE traps and there was a preceding
+		       point in the block that might not return avoid
+		       adding the reference to EXP_GEN.  */
+		    && (!BB_MAY_NOTRETURN (block)
+			|| !vn_reference_may_trap (ref)))
 		  {
 		    result = get_or_alloc_expr_for_reference
 			       (ref, gimple_location (stmt));
@@ -4220,6 +4234,11 @@ compute_avail (function *fun)
 	      break;
 	    }
 	}
+      if (set_bb_may_notreturn)
+	{
+	  BB_MAY_NOTRETURN (block) = 1;
+	  set_bb_may_notreturn = false;
+	}
 
       if (dump_file && (dump_flags & TDF_DETAILS))
 	{
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index bf87cee38573064e552ec04e4fc1b3ec37f0cc02..2357bbdbf9022c4ee540f97e323ad81073a3ec3e 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -5851,6 +5851,7 @@ vn_reference_may_trap (vn_reference_t ref)
     case MODIFY_EXPR:
     case CALL_EXPR:
       /* We do not handle calls.  */
+      return true;
     case ADDR_EXPR:
       /* And toplevel address computations never trap.  */
       return false;