------- Comment #4 from steven at gcc dot gnu dot org 2009-06-23 12:31 -------
This is the usual idiotic behavior of ifcvt.c for targets that have conditional
execution, but not for all insns.
Normally the find_if_case_1() transformation should handle this optimization.
But the dead_or_predicable_p function tries to apply cond_exec transformations
*or* non-cond_exec transformations, instead of trying both. In other words, if
conditional execution is supported but the transformation fails in
dead_or_predicable, the non-cond_exec transformation is not even attempted.
Or course, ARM has conditional execution, but IIUC not for thumb. So all the
find_if_case_[12] transformations fail.
With this gross hack:
Index: ifcvt.c
===================================================================
--- ifcvt.c (revision 148812)
+++ ifcvt.c (working copy)
@@ -3819,7 +3819,7 @@ dead_or_predicable (basic_block test_bb,
/* Disable handling dead code by conditional execution if the machine needs
to do anything funny with the tests, etc. */
#ifndef IFCVT_MODIFY_TESTS
- if (HAVE_conditional_execution)
+ if (0 && HAVE_conditional_execution)
{
/* In the conditional execution case, we have things easy. We know
the condition is reversible. We don't have to check life info
GCC gives me the following code for the test case, which is just as good as the
code suggested by Carrot in comment #2:
foo:
push {lr}
mov r3, #2
cmp r1, #1
beq .L2
mov r3, #0
.L2:
add r0, r3, r0
@ sp needed for prologue
pop {pc}
.size foo, .-foo
.ident "GCC: (GNU) 4.5.0 20090622 (experimental) [trunk revision
148812]"
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40525