
* Simon Marlow:
gcc started generating this rubbish around version 3.4, if I recall correctly. I've tried disabling various optimisations, but can't seem to convince gcc not to generate the extra jump. You don't get this from the native code generator, BTW.
But the comparison is present in the C code. What do you want GCC to do?
I didn't mean to sound overly critical of gcc.
It didn't come across that way. I just want to construct a test case, so it can be fixed on the GCC side, and see if I can suggest alternatives.
Actually if I add -O2, then I get better code, so perhaps this isn't a real problem. Although gcc still generates this:
movl $Fac_zdwfac_info, %eax jmp *%rax
and fails to combine the movs with the jmp instruction (we do this simplification ourselves when post-processing the assembly code).
I agree, GCC should optimize this case. A minimal test case is: extern void bar(); void foo() { void *p = bar; goto *p; } None of the GCC versions I have tried optimizes away the indirect call.
I'll compile up gcc 4 and see what happens with that.
The jump target is not propagated, either. Same with 4.1. However, beginning with GCC 3.4, you can use: extern void bar(); void foo() { void (*p)(void) = bar; p(); } And the indirect call is turned into a direct jump. Tail recursive calls and really indirect tail calls are also optimzed. Together with -fomit-frame-pointer, this could give you what you need, without post-processing the generated assembler code (which is desirable because the asm volatile statements inhibit further optimization). Is it correct that you use indirect gotos across functions? Such gotos aren't supported by GCC and work only by accident.