aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2023-01-03 12:12:35 +0100
committerJakub Jelinek <jakub@redhat.com>2023-01-03 12:12:35 +0100
commit4fb639a7fee5df32a2d1e7afa40fdf31d280464b (patch)
treea9a9bfea30476fc781043db1c39b9b6c96b50783 /gcc
parent201c21b0e847679645df1af3dd13459274f41047 (diff)
downloadgcc-4fb639a7fee5df32a2d1e7afa40fdf31d280464b.zip
gcc-4fb639a7fee5df32a2d1e7afa40fdf31d280464b.tar.gz
gcc-4fb639a7fee5df32a2d1e7afa40fdf31d280464b.tar.bz2
cfgrtl: Don't try to redirect asm goto to EXIT [PR108263]
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cfgrtl.cc8
-rw-r--r--gcc/testsuite/gcc.dg/pr108263.c25
2 files changed, 31 insertions, 2 deletions
diff --git a/gcc/cfgrtl.cc b/gcc/cfgrtl.cc
index fcc2edb..1d84b29 100644
--- a/gcc/cfgrtl.cc
+++ b/gcc/cfgrtl.cc
@@ -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
index 0000000..688df32
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr108263.c
@@ -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:;
+}