Consider the following simple function (I can reproduce the bug just saving this code as a .c file and compiling it with -S to see the asm output and using -O1):
extern void a( void ); extern void b( void ); extern void c( void ); int weird(int t) { if (t > 32768) t = 32768; a(); b(); c(); if (t < -32768) t = -32768; return t; } GCC-4.1.1 seems to duplicate the block between the two ifs no matter what code I put between them, here's the assembler output: weird: pushl %ebp movl %esp, %ebp pushl %ebx subl $4, %esp movl 8(%ebp), %ebx cmpl $32768, %ebx jg .L2 call a call b call c movl %ebx, %eax cmpl $-32768, %ebx jge .L5 movl $-32768, %eax jmp .L5 .L2: call a call b call c movl $32768, %eax .L5: addl $4, %esp popl %ebx popl %ebp ret As you can see the first conditional branch skips over the code standing for the second if - as it should since the conditions are mutually exclusive - but the calls in-between them have to be replicated on the other side of the branch. Now the problem is no matter how many calls I put in between the if()s they will be replicated on both sides instead of being factored. Considering that -O1 shouldn't turn on optimizations which cause trade-offs between size and speed this seems a bug to me. -- Summary: Poor optimization causes unbounded code duplication Product: gcc Version: 4.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: gabriele dot svelto at gmail dot com GCC build triplet: i686-pc-linux-gnu GCC host triplet: i686-pc-linux-gnu GCC target triplet: i686-pc-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29285