GCC with gcse enabled generates very poor code for this fragment: ------------------------------------------------------------------------------ int r0, r1, r2, r3, r4, r5;
void f (int n) { while (-- n) { r1 += r0; r2 += r1; r3 += r2; r4 += r3; r5 += r4; r0 += r5; } } ------------------------------------------------------------------------------ This is code from 3.4.4 with -O2 -fomit-frame-pointer: .L4: movl 16(%esp), %ebp movl 12(%esp), %esi movl 8(%esp), %ecx movl 4(%esp), %edx movl (%esp), %eax addl %edi, %ebp addl %ebp, %esi movl %ebp, 16(%esp) addl %esi, %ecx movl %esi, 12(%esp) addl %ecx, %edx movl %ecx, 8(%esp) addl %edx, %eax decl 20(%esp) movl %edx, 4(%esp) leal (%edi,%eax), %ebx movl %eax, (%esp) movl %ebx, %edi jne .L4 And this is with -O2 -fomit-frame-pointer -fno-gcse: .L4: addl %edi, %ebp addl %ebp, %ebx addl %ebx, %ecx addl %ecx, %edx addl %edx, %eax addl %eax, %edi decl %esi jne .L4 Same applies for 4.0.0, only one should use '-O2 -fomit-frame-pointer -fno-tree-loop-im -fno-gcse' to get decent code. This is a regression and was introduced by this change: 2001-07-16 Daniel Berlin <[EMAIL PROTECTED]> * gcse.c: Update comment at top. Update comment on mem handling. mem_last_set, mem_first_set, mem_set_in_block: gone. Declaration of reg_set_info: gone. (oprs_unchanged_p): Don't use mem_*set_* anymore. They are pointless with load_killed_in_block_p (they are *more* conservative then it, not less, and less accurate). (oprs_not_set_p): Ditto. (alloc_gcse_mem): Don't allocate mem_set_in_block (free_gcse_mem): Don't free it, either. (record_last_mem_set_info): Update comment in front, remove mem_*set_* stuff. Note the reason we don't handle stores directly here. (compute_hash_table): Update comments to reflect reality. Remove mem_*set_* references. (reset_opr_set_tables): Remove mem_*set_* references. (mark_call): Ditto. (mark_set): Ditto. Also remove double sets of bitmaps for REG's. (mark_clobber): Ditto (on both parts, we double set here too). (expr_killed_p): Remove mem_set_in_block test. (compute_transp): Remove mem_set_in_block test. -- Summary: [3.3/3.4/4.0 Regression] gcse causes poor register allocation Product: gcc Version: 4.0.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: normal Priority: P2 Component: rtl-optimization AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: belyshev at depni dot sinp dot msu dot ru CC: gcc-bugs at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19464