------- Comment #8 from rask at gcc dot gnu dot org 2007-11-27 18:04 ------- Created an attachment (id=14647) --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=14647&action=view) Patch to enhance cse.c
The attached patch can optimize this testcase: void foo (int); int bar2 (int a, int b) { int c = a - b; if (a < b) { foo (c); } return c; } Before: bar2: pushl %ebx # 33 *pushsi2 [length = 1] subl $8, %esp # 34 pro_epilogue_adjust_stack_1/1 [length = 3] movl 16(%esp), %edx # 2 *movsi_1/1 [length = 4] movl 20(%esp), %eax # 3 *movsi_1/1 [length = 4] movl %edx, %ebx # 32 *movsi_1/1 [length = 2] subl %eax, %ebx # 7 *subsi_1/1 [length = 2] cmpl %eax, %edx # 8 *cmpsi_1_insn/1 [length = 2] jge .L2 # 9 *jcc_1 [length = 2] movl %ebx, (%esp) # 11 *movsi_1/2 [length = 3] call foo # 12 *call_0 [length = 5] .L2: movl %ebx, %eax # 19 *movsi_1/1 [length = 2] addl $8, %esp # 37 pro_epilogue_adjust_stack_1/1 [length = 3] popl %ebx # 38 popsi1 [length = 1] ret # 39 return_internal [length = 1] After: bar2: pushl %ebx # 33 *pushsi2 [length = 1] subl $8, %esp # 34 pro_epilogue_adjust_stack_1/1 [length = 3] movl 16(%esp), %eax # 2 *movsi_1/1 [length = 4] movl %eax, %ebx # 32 *movsi_1/1 [length = 2] subl 20(%esp), %ebx # 8 *subsi_2/2 [length = 4] jns .L2 # 9 *jcc_1 [length = 2] movl %ebx, (%esp) # 11 *movsi_1/2 [length = 3] call foo # 12 *call_0 [length = 5] .L2: movl %ebx, %eax # 19 *movsi_1/1 [length = 2] addl $8, %esp # 37 pro_epilogue_adjust_stack_1/1 [length = 3] popl %ebx # 38 popsi1 [length = 1] ret # 39 return_internal [length = 1] One of the difficulties is that by the time the code gets to the cse1 pass, the statement "c = a - b" might have been moved below the "a < b" test, making it harder to optimize. The "bar2" testcase was crafted so this doesn't happen. But given the need to potentially replace both the sub/cmp insn and the jump insn, it would be better to move this optimization to combine. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=3507