------- Comment #4 from wilson at gcc dot gnu dot org 2010-05-16 02:07 ------- The testcase fails with -O2 -funroll-loops. It works with -O2.
The problem occurs in main at line 89, which is the second doit call. We get a segfault when dereferencing a null pointer. The code is wrong because of an instruction-scheduling/if-conversion/alias-analysis issue. In the broken assembly output, we have (over simplified) addl r33 = @ltoffx(__s_bar_mod_MOD_vtab$s_bar#), r1 ld8.mov r29 = [r33], __s_bar_mod_MOD_vtab$s_bar# adds r28 = 24, r29 ld8 r26 = [r28] cmp.ne p6, p7 = 0, r31 (p7) adds r31 = 24, r29 (p7) addl r30 = @ltoff(@fptr(__s_bar_mod_MOD_doit#)), gp (p7) ld8 r30 = [r30] (p7) st8 [r31] = r30 ld8 r27 = [r26], 8 And the last instruction segfaults because r26 is 0 when it should be the address of __s_bar_mod_MOD_doit. The load from r28 should not have been moved before the group of conditional instructions. This is correct up to the mach pass, where the IA-64 port runs the second instruction scheduling pass. The first instruction scheduling pass is before if-conversion, so we still have a branch around a block of instructions there. I'm seeing different instruction scheduling and bundle filling with -funroll-loops, though it isn't immediately clear why, as there are no loops here. I'm getting the same code with a x86-linux cross ia64-linux compiler. Just look for the code using __s_bar_mod_MOD_vtab$s_bar and __s_bar_mod_MOD_doit in main. So it should be possible to debug this on an x86-linux machine. -- wilson at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |wilson at gcc dot gnu dot | |org Status|UNCONFIRMED |NEW Ever Confirmed|0 |1 Last reconfirmed|0000-00-00 00:00:00 |2010-05-16 02:07:01 date| | http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43986