public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-4079] rtl: Try to remove EH edges after {pro, epi}logue generation [PR90259]
@ 2022-11-16  2:26 Kewen Lin
  0 siblings, 0 replies; only message in thread
From: Kewen Lin @ 2022-11-16  2:26 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:63e1b2e767a3f4695373c2406ff719c0a60c1858

commit r13-4079-g63e1b2e767a3f4695373c2406ff719c0a60c1858
Author: Kewen Lin <linkw@linux.ibm.com>
Date:   Tue Nov 15 20:26:07 2022 -0600

    rtl: Try to remove EH edges after {pro,epi}logue generation [PR90259]
    
    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.
    
    As PR90259 shows, some memory access becomes impossible to trap
    any more after prologue and epilogue generation, it can make
    subsequent optimization be able to remove it if safe, but it
    results in unexpected control flow status due to REG_EH_REGION
    note missing.
    
    This patch proposes to try to remove EH edges with function
    purge_all_dead_edges after prologue and epilogue generation,
    it simplifies CFG as early as we can and don't need any fixup
    in downstream passes.
    
    CFG simplification result with PR90259's case as example:
    
    *before*
    
       18: %1:TF=call [`__gcc_qdiv'] argc:0
          REG_EH_REGION 0x2
       77: NOTE_INSN_BASIC_BLOCK 3
       19: NOTE_INSN_DELETED
       20: NOTE_INSN_DELETED
      110: [%31:SI+0x20]=%1:DF
          REG_EH_REGION 0x2
      116: NOTE_INSN_BASIC_BLOCK 4
      111: [%31:SI+0x28]=%2:DF
          REG_EH_REGION 0x2
       22: NOTE_INSN_BASIC_BLOCK 5
      108: %0:DF=[%31:SI+0x20]
          REG_EH_REGION 0x2
      117: NOTE_INSN_BASIC_BLOCK 6
      109: %1:DF=[%31:SI+0x28]
          REG_EH_REGION 0x2
       79: NOTE_INSN_BASIC_BLOCK 7
       26: [%31:SI+0x18]=%0:DF
      104: pc=L69
      105: barrier
    
    *after*
    
       18: %1:TF=call [`__gcc_qdiv'] argc:0
          REG_EH_REGION 0x2
       77: NOTE_INSN_BASIC_BLOCK 3
       19: NOTE_INSN_DELETED
       20: NOTE_INSN_DELETED
      110: [%31:SI+0x20]=%1:DF
      111: [%31:SI+0x28]=%2:DF
      108: %0:DF=[%31:SI+0x20]
      109: %1:DF=[%31:SI+0x28]
       26: [%31:SI+0x18]=%0:DF
      104: pc=L69
      105: barrier
    
            PR rtl-optimization/90259
    
    gcc/ChangeLog:
    
            * function.cc (rest_of_handle_thread_prologue_and_epilogue): Add
            parameter fun, and call function purge_all_dead_edges.
            (pass_thread_prologue_and_epilogue::execute): Name unamed parameter
            as fun, and use it for rest_of_handle_thread_prologue_and_epilogue.
    
    gcc/testsuite/ChangeLog:
    
            * g++.target/powerpc/pr90259.C: New.

Diff:
---
 gcc/function.cc                            |  13 +++-
 gcc/testsuite/g++.target/powerpc/pr90259.C | 103 +++++++++++++++++++++++++++++
 2 files changed, 113 insertions(+), 3 deletions(-)

diff --git a/gcc/function.cc b/gcc/function.cc
index d3da20ede7f..361aa5f7ed1 100644
--- a/gcc/function.cc
+++ b/gcc/function.cc
@@ -6546,7 +6546,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.  */
@@ -6563,6 +6563,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);
@@ -6631,9 +6638,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;

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-11-16  2:26 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-16  2:26 [gcc r13-4079] rtl: Try to remove EH edges after {pro, epi}logue generation [PR90259] Kewen Lin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).