]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
cfgrtl: Don't try to redirect asm goto to EXIT [PR108263]
authorJakub Jelinek <jakub@redhat.com>
Tue, 3 Jan 2023 11:12:35 +0000 (12:12 +0100)
committerJakub Jelinek <jakub@redhat.com>
Tue, 3 Jan 2023 11:12:35 +0000 (12:12 +0100)
The following testcase distilled from Linux kernel on ppc64le ICEs,
because fixup_reorder_chain sees a bb with a single fallthru edge
falling into a bb with simple return and decides to redirect
that fallthru edge to EXIT.  That is possible if the bb ending
in the fallthru edge doesn't end with a jump or ends with a normal
unconditional jump, but not when the bb ends with asm goto which can despite
a single fallthru have multiple labels to the fallthrough basic block.

The following patch makes sure we never try to redirect such cases to EXIT.

2023-01-03  Jakub Jelinek  <jakub@redhat.com>

PR rtl-optimization/108263
* cfgrtl.cc (fixup_reorder_chain): Avoid trying to redirect
asm goto to EXIT.

* gcc.dg/pr108263.c: New test.

gcc/cfgrtl.cc
gcc/testsuite/gcc.dg/pr108263.c [new file with mode: 0644]

index fcc2edbef41c68d1b630143b70cf85265816dc3d..1d84b29ce61a4941b612b0bda7669cca77a14e58 100644 (file)
@@ -3910,6 +3910,7 @@ fixup_reorder_chain (void)
       rtx ret_label = NULL_RTX;
       basic_block nb;
       edge_iterator ei;
+      bool asm_goto = false;
 
       if (EDGE_COUNT (bb->succs) == 0)
        continue;
@@ -4016,7 +4017,9 @@ fixup_reorder_chain (void)
                  || e_fall->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
                continue;
 
-             /* Otherwise we'll have to use the fallthru fixup below.  */
+             /* Otherwise we'll have to use the fallthru fixup below.
+                But avoid redirecting asm goto to EXIT.  */
+             asm_goto = true;
            }
          else
            {
@@ -4048,7 +4051,8 @@ fixup_reorder_chain (void)
         return rather than a jump to the return block.  */
       rtx_insn *ret, *use;
       basic_block dest;
-      if (bb_is_just_return (e_fall->dest, &ret, &use)
+      if (!asm_goto
+         && bb_is_just_return (e_fall->dest, &ret, &use)
          && ((PATTERN (ret) == simple_return_rtx && targetm.have_simple_return ())
              || (PATTERN (ret) == ret_rtx && targetm.have_return ())))
        {
diff --git a/gcc/testsuite/gcc.dg/pr108263.c b/gcc/testsuite/gcc.dg/pr108263.c
new file mode 100644 (file)
index 0000000..688df32
--- /dev/null
@@ -0,0 +1,25 @@
+/* PR rtl-optimization/108263 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int v, *p;
+
+void
+foo (void)
+{
+  int i;
+  for (i = 0; ; i++)
+    {
+      if (v)
+       {
+         __label__ l1;
+         asm goto ("" : : : : l1);
+       l1:
+         return;
+       }
+      if (p[i])
+       break;
+    }
+  asm goto ("" : : "r" (i) : : l2);
+l2:;
+}