This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix bb-reorder ICEs (PR rtl-optimization/80747, PR rtl-optimization/83512)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Jeff Law <law at redhat dot com>, Eric Botcazou <ebotcazou at adacore dot com>, Jan Hubicka <jh at suse dot cz>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 21 Dec 2017 19:05:10 +0100
- Subject: [PATCH] Fix bb-reorder ICEs (PR rtl-optimization/80747, PR rtl-optimization/83512)
- Authentication-results: sourceware.org; auth=none
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
The following two testcases show multiple issues in
reorder_basic_blocks_simple. Both issues only occur if the greedy algorithm
decides to put some basic block before the ENTRY successor. In that case
reorder_basic_blocks_simple has code to split the ENTRY successor edge
and put the new bb before all the others. If pass_partition_blocks
was done earlier, one issue is that in this case (when the ENTRY successor
edge was ignored by the greedy algorithm) ENTRY_BLOCK_PTR_FOR_FN (cfun)->aux
is the ENTRY block itself, and only the non-fixed basic blocks are cold or
hot, not ENTRY/EXIT, so starting with current_partition set to BB_PARTITION
of the ENTRY block doesn't work - it will be BB_UNPARITIONED and so neither
of the passes of the following loop will do anything. IMHO we want to
use the partition of the ENTRY successor bb, whether it is hot or cold
(typically hot). The other issue is that when we force_nonfallthru
on the ENTRY successor edge, e->src is BB_UNPARTITIONED, e->dest if
bbpart was done is either hot or cold (but for these edges we of course
never set EDGE_CROSSING). force_nonfallthru_and_redirect creates a new
bb which will be BB_UNPARTITIONED and so the new edge is EDGE_CROSSING
and the new jump is CROSSING_JUMP_P. Then reorder_basic_blocks_simple
fixes up the partition of the new bb through BB_COPY_PARTITION, but it is
too late, it would need to undo EDGE_CROSSING flag on the edge and
CROSSING_JUMP_P too. IMHO it is better to get the partition right from the
beginning, then we don't have to undo anything.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2017-12-21 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/80747
PR rtl-optimization/83512
* cfgrtl.c (force_nonfallthru_and_redirect): When splitting
succ edge from ENTRY, copy partition from e->dest to the newly
created bb.
* bb-reorder.c (reorder_basic_blocks_simple): If last_tail is
ENTRY, use BB_PARTITION of its successor block as current_partition.
Don't copy partition when splitting succ edge from ENTRY.
* gcc.dg/pr80747.c: New test.
* gcc.dg/pr83512.c: New test.
--- gcc/cfgrtl.c.jj 2017-12-20 20:40:19.000000000 +0100
+++ gcc/cfgrtl.c 2017-12-21 16:25:24.172698221 +0100
@@ -1534,6 +1534,9 @@ force_nonfallthru_and_redirect (edge e,
ENTRY_BLOCK_PTR_FOR_FN (cfun));
bb->count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count;
+ /* Make sure new block ends up in correct hot/cold section. */
+ BB_COPY_PARTITION (bb, e->dest);
+
/* Change the existing edge's source to be the new block, and add
a new edge from the entry block to the new block. */
e->src = bb;
--- gcc/bb-reorder.c.jj 2017-11-22 23:34:45.000000000 +0100
+++ gcc/bb-reorder.c 2017-12-21 16:25:54.237319354 +0100
@@ -2405,7 +2405,10 @@ reorder_basic_blocks_simple (void)
basic_block last_tail = (basic_block) ENTRY_BLOCK_PTR_FOR_FN (cfun)->aux;
- int current_partition = BB_PARTITION (last_tail);
+ int current_partition
+ = BB_PARTITION (last_tail == ENTRY_BLOCK_PTR_FOR_FN (cfun)
+ ? EDGE_SUCC (ENTRY_BLOCK_PTR_FOR_FN (cfun), 0)->dest
+ : last_tail);
bool need_another_pass = true;
for (int pass = 0; pass < 2 && need_another_pass; pass++)
@@ -2446,7 +2449,6 @@ reorder_basic_blocks_simple (void)
{
force_nonfallthru (e);
e->src->aux = ENTRY_BLOCK_PTR_FOR_FN (cfun)->aux;
- BB_COPY_PARTITION (e->src, e->dest);
}
}
--- gcc/testsuite/gcc.dg/pr80747.c.jj 2017-12-21 16:27:18.234260846 +0100
+++ gcc/testsuite/gcc.dg/pr80747.c 2017-12-21 16:26:56.000000000 +0100
@@ -0,0 +1,18 @@
+/* PR rtl-optimization/80747 */
+/* { dg-do compile } */
+/* { dg-options "-fprofile-use -freorder-blocks-and-partition -O1 -foptimize-sibling-calls" } */
+
+int
+foo (int a)
+{
+ int r;
+ if (a & 1)
+ r = foo (a - 1);
+ else if (a)
+ r = foo (a - 2);
+ else
+ return 0;
+ if (r)
+ r = r;
+ return r;
+}
--- gcc/testsuite/gcc.dg/pr83512.c.jj 2017-12-21 16:41:11.487769515 +0100
+++ gcc/testsuite/gcc.dg/pr83512.c 2017-12-21 16:40:50.000000000 +0100
@@ -0,0 +1,16 @@
+/* PR rtl-optimization/83512 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -freorder-blocks-algorithm=simple" } */
+
+int a;
+
+void
+foo (int *x)
+{
+ for (;;)
+ {
+ for (*x = 0; *x < 1; *x++)
+ ;
+ ++a;
+ }
+}
Jakub