Hi!

As mentioned in the PR, shrink-wrapping disqualifies for prologue
placement basic blocks that have EDGE_CROSSING incoming edge.
I don't see why that is necessary, those edges seem to be redirected
just fine, both on x86_64 and powerpc64.  In the former case, they
are usually conditional jumps that patch_jump_insn can handle just fine,
after all, they were previously crossing and will be crossing after
the redirection too, just to a different label.  And in the powerpc64
case, it is a simple_jump instead that again seems to be handled by
patch_jump_insn just fine.
Sure, redirecting an edge that was previously not crossing to be crossing or
vice versa can fail, but that is not what shrink-wrapping needs.
Also tested in GCC 8 with this patch and don't see ICEs there either
(though, of course, I'm not suggesting we should backport this to release
branches).

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2020-12-16  Jakub Jelinek  <ja...@redhat.com>

        PR rtl-optimization/98289
        * shrink-wrap.c (can_get_prologue): Don't punt on EDGE_CROSSING
        incoming edges.

        * gcc.target/i386/pr98289.c: New test.
        * gcc.dg/torture/pr98289.c: New test.

--- gcc/shrink-wrap.c.jj        2020-07-28 15:39:09.983756571 +0200
+++ gcc/shrink-wrap.c   2020-12-15 19:15:00.213861334 +0100
@@ -494,7 +494,7 @@ can_get_prologue (basic_block pro, HARD_
   edge e;
   edge_iterator ei;
   FOR_EACH_EDGE (e, ei, pro->preds)
-    if (e->flags & (EDGE_COMPLEX | EDGE_CROSSING)
+    if (e->flags & EDGE_COMPLEX
        && !dominated_by_p (CDI_DOMINATORS, e->src, pro))
       return false;
 
--- gcc/testsuite/gcc.target/i386/pr98289.c.jj  2020-12-16 13:15:08.579847596 
+0100
+++ gcc/testsuite/gcc.target/i386/pr98289.c     2020-12-16 14:26:16.863157527 
+0100
@@ -0,0 +1,54 @@
+/* PR rtl-optimization/98289 */
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-require-effective-target freorder } */
+/* { dg-options "-O2 -freorder-blocks-and-partition 
-fdump-rtl-pro_and_epilogue-details" } */
+/* { dg-final { scan-rtl-dump-times "Performing shrink-wrapping" 4 
"pro_and_epilogue" } } */
+
+int bar (void) __attribute__((cold));
+
+void
+foo (int x)
+{
+  if (x)
+    __builtin_abort ();
+}
+
+void
+baz (int x)
+{
+  if (__builtin_expect (x, 0))
+    {
+      bar ();
+      bar ();
+      bar ();
+    }
+}
+
+void
+qux (int x, int y, int z, int w)
+{
+  if (x || y || z || w)
+    __builtin_abort ();
+}
+
+int
+corge (int x, int y, int z, int w, int u)
+{
+  if (__builtin_expect (x, 0))
+    goto lab;
+  u++;
+  if (__builtin_expect (y, 0))
+    goto lab;
+  u *= 2;
+  if (__builtin_expect (z, 0))
+    goto lab;
+  u |= 42;
+  if (__builtin_expect (w, 0))
+    {
+      lab:;
+      bar ();
+      bar ();
+      if (bar () > 32) goto lab;
+    }
+  return u;
+}
--- gcc/testsuite/gcc.dg/torture/pr98289.c.jj   2020-12-16 14:27:01.391659297 
+0100
+++ gcc/testsuite/gcc.dg/torture/pr98289.c      2020-12-16 14:27:29.442345443 
+0100
@@ -0,0 +1,52 @@
+/* PR rtl-optimization/98289 */
+/* { dg-do compile { target freorder } } */
+/* { dg-options "-O2 -freorder-blocks-and-partition" } */
+
+int bar (void) __attribute__((cold));
+
+void
+foo (int x)
+{
+  if (x)
+    __builtin_abort ();
+}
+
+void
+baz (int x)
+{
+  if (__builtin_expect (x, 0))
+    {
+      bar ();
+      bar ();
+      bar ();
+    }
+}
+
+void
+qux (int x, int y, int z, int w)
+{
+  if (x || y || z || w)
+    __builtin_abort ();
+}
+
+int
+corge (int x, int y, int z, int w, int u)
+{
+  if (__builtin_expect (x, 0))
+    goto lab;
+  u++;
+  if (__builtin_expect (y, 0))
+    goto lab;
+  u *= 2;
+  if (__builtin_expect (z, 0))
+    goto lab;
+  u |= 42;
+  if (__builtin_expect (w, 0))
+    {
+      lab:;
+      bar ();
+      bar ();
+      if (bar () > 32) goto lab;
+    }
+  return u;
+}

        Jakub

Reply via email to