------- 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