cfgcleanup: Handle a branch with just a return in both arms (PR71028)
authorSegher Boessenkool <segher@kernel.crashing.org>
Tue, 10 May 2016 23:31:27 +0000 (01:31 +0200)
committerSegher Boessenkool <segher@gcc.gnu.org>
Tue, 10 May 2016 23:31:27 +0000 (01:31 +0200)
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.

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.

From-SVN: r236106

gcc/ChangeLog
gcc/cfgcleanup.c

index 0f20a323c6bef894fa67992cc1b9dc7b2e849d42..e95fcad02a60c9f026308ec3a109c8ae71f13206 100644 (file)
@@ -1,3 +1,10 @@
+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 return as well.
+
 2016-05-10  Marc Glisse  <marc.glisse@inria.fr>
 
        * fold-const.c (fold_binary_loc) [(X ^ Y) & Y]: Remove and merge with...
index 726c068eceb98dadec160a13038b56cf27f56f48..023b9d239a8ee3c16de3a7da8f67caf4793ecdc6 100644 (file)
@@ -2870,6 +2870,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))
                {