diff --git a/gcc/testsuite/gcc.dg/pr108691.c b/gcc/testsuite/gcc.dg/pr108691.c
new file mode 100644
index 0000000000000000000000000000000000000000..e412df10f22c2c196aa65ed6d8ec199a18a9d645
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr108691.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+extern int __attribute__((returns_twice)) setjmp(void*);
+
+void bbb(void) {
+  int (*fnptr)(void*) = setjmp;
+  fnptr(0);
+}
diff --git a/gcc/tree-ssa-dce.cc b/gcc/tree-ssa-dce.cc
index ceeb0ad5ab3351a77caea5fd6940ea58347d6aab..0ae998f86f9839ba5a95c5fc1a22cd2f12b5cdad 100644
--- a/gcc/tree-ssa-dce.cc
+++ b/gcc/tree-ssa-dce.cc
@@ -1512,10 +1512,12 @@ eliminate_unnecessary_stmts (bool aggressive)
 	remove_edge (to_remove_edges[i]);
       cfg_altered = true;
     }
-  /* When we cleared calls_setjmp we can purge all abnormal edges.  Do so.  */
-  if (cfun->calls_setjmp != had_setjmp)
+  /* When we cleared calls_setjmp we can purge all abnormal edges.  Do so.
+     ???  We'd like to assert that setjmp calls do not pop out of nothing
+     but we currently lack a per-stmt way of noting whether a call was
+     recognized as returns-twice (or rather receives-control).  */
+  if (!cfun->calls_setjmp && had_setjmp)
     {
-      gcc_assert (!cfun->calls_setjmp);
       /* Make sure we only remove the edges, not dominated blocks.  Using
 	 gimple_purge_dead_abnormal_call_edges would do that and we
 	 cannot free dominators yet.  */