diff --git a/gcc/function.cc b/gcc/function.cc
index 6474a663b30..3757ded547d 100644
--- a/gcc/function.cc
+++ b/gcc/function.cc
@@ -6540,7 +6540,7 @@ make_pass_leaf_regs (gcc::context *ctxt)
 }

 static unsigned int
-rest_of_handle_thread_prologue_and_epilogue (void)
+rest_of_handle_thread_prologue_and_epilogue (function *fun)
 {
   /* prepare_shrink_wrap is sensitive to the block structure of the control
      flow graph, so clean it up first.  */
@@ -6557,6 +6557,13 @@ rest_of_handle_thread_prologue_and_epilogue (void)
      Fix that up.  */
   fixup_partitions ();

+  /* After prologue and epilogue generation, the judgement on whether
+     one memory access onto stack frame may trap or not could change,
+     since we get more exact stack information by now.  So try to
+     remove any EH edges here, see PR90259.  */
+  if (fun->can_throw_non_call_exceptions)
+    purge_all_dead_edges ();
+
   /* Shrink-wrapping can result in unreachable edges in the epilogue,
      see PR57320.  */
   cleanup_cfg (optimize ? CLEANUP_EXPENSIVE : 0);
@@ -6625,9 +6632,9 @@ public:
   {}

   /* opt_pass methods: */
-  unsigned int execute (function *) final override
+  unsigned int execute (function * fun) final override
     {
-      return rest_of_handle_thread_prologue_and_epilogue ();
+      return rest_of_handle_thread_prologue_and_epilogue (fun);
     }

 }; // class pass_thread_prologue_and_epilogue
diff --git a/gcc/testsuite/g++.target/powerpc/pr90259.C b/gcc/testsuite/g++.target/powerpc/pr90259.C
new file mode 100644
index 00000000000..db75ac7fe02
--- /dev/null
+++ b/gcc/testsuite/g++.target/powerpc/pr90259.C
@@ -0,0 +1,103 @@
+/* { dg-require-effective-target long_double_ibm128 } */
+/* { dg-options "-O2 -ffloat-store -fgcse -fnon-call-exceptions -fno-forward-propagate -fno-omit-frame-pointer -fstack-protector-all" } */
+/* { dg-add-options long_double_ibm128 } */
+
+/* Verify there is no ICE.  */
+
+template <int a> struct b
+{
+  static constexpr int c = a;
+};
+template <bool a> using d = b<a>;
+struct e
+{
+  int f;
+  int
+  g ()
+  {
+    return __builtin_ceil (f / (long double) h);
+  }
+  float h;
+};
+template <typename, typename> using k = d<!bool ()>;
+template <typename> class n
+{
+public:
+  e ae;
+  void af ();
+};
+template <typename l>
+void
+n<l>::af ()
+{
+  ae.g ();
+}
+template <bool> using m = int;
+template <typename ag, typename ah, typename ai = m<k<ag, ah>::c>>
+using aj = n<ai>;
+struct o
+{
+  void
+  af ()
+  {
+    al.af ();
+  }
+  aj<int, int> al;
+};
+template <typename> class am;
+template <typename i> class ao
+{
+protected:
+  static i *ap (int);
+};
+template <typename, typename> class p;
+template <typename ar, typename i, typename... j> class p<ar (j...), i> : ao<i>
+{
+public:
+  static ar
+  as (const int &p1, j...)
+  {
+    (*ao<i>::ap (p1)) (j ()...);
+  }
+};
+template <typename ar, typename... j> class am<ar (j...)>
+{
+  template <typename, typename> using av = int;
+
+public:
+  template <typename i, typename = av<d<!bool ()>, void>,
+	    typename = av<i, void>>
+  am (i);
+  using aw = ar (*) (const int &, j...);
+  aw ax;
+};
+template <typename ar, typename... j>
+template <typename i, typename, typename>
+am<ar (j...)>::am (i)
+{
+  ax = p<ar (j...), i>::as;
+}
+struct G
+{
+  void ba (am<void (o)>);
+};
+struct q
+{
+  q ()
+  {
+    G a;
+    a.ba (r ());
+  }
+  struct r
+  {
+    void
+    operator() (o p1)
+    try
+      {
+	p1.af ();
+      }
+    catch (int)
+      {
+      }
+  };
+} s;
