diff mbox

cfgcleanup: Handle a branch with just a return in both arms (PR71028)

Message ID 0aaffa29eefa48e435814390bdeea56107ab2404.1462866472.git.segher@kernel.crashing.org
State New
Headers show

Commit Message

Segher Boessenkool May 10, 2016, 7:55 a.m. UTC
If we have a conditional jump that has only a return in both the branch
path and the fallthrough path, and the return on the branch path can not
be made a conditional return, we will try to make a conditional return
from the fallthrough path, and that does not work because we then try
to redirect the (new) jump in the fallthrough block to the original
dest in the branch path, which is the exit block.

For the testcase on ARM we end up in this situation because before the
jump2 pass there are some other insns in the return blocks as well, but
the same insns in both, so those are moved above the conditional jump.
Only later (in the ce3 pass) are the conditional jump and two returns
melded into one return, so we need to handle this strange case here.

Bootstrapped and regression checked on powerpc64-linux; the testcase
(already in the testsuite) also tried on an arm-linux-gnueabi
cross-compiler.  Is this okay for trunk?


Segher


2016-05-10  Segher Boessenkool  <segher@kernel.crashing.org>

	PR rtl-optimization/71028
	* cfgcleanup.c (try_optimize_cfg): Do not flip a conditional
	jump with just a return in the fallthrough block if the branch
	block contains just a returns as well.

---
 gcc/cfgcleanup.c | 1 +
 1 file changed, 1 insertion(+)

Comments

Bernd Schmidt May 10, 2016, 11:05 a.m. UTC | #1
On 05/10/2016 09:55 AM, Segher Boessenkool wrote:
>
> 	PR rtl-optimization/71028
> 	* cfgcleanup.c (try_optimize_cfg): Do not flip a conditional
> 	jump with just a return in the fallthrough block if the branch
> 	block contains just a returns as well.

Looks good.


Bernd
diff mbox

Patch

diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index 2463f7c..b3a3989 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -2875,6 +2875,7 @@  try_optimize_cfg (int mode)
 		 a return so that it becomes a conditional return and a
 		 new jump to the original branch target.  */
 	      if (EDGE_COUNT (b->succs) == 2
+		  && BRANCH_EDGE (b)->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)
 		  && any_condjump_p (BB_END (b))
 		  && bb_is_just_return (FALLTHRU_EDGE (b)->dest, &ret, &use))
 		{