------- Comment #6 from wilson at gcc dot gnu dot org 2010-03-15 04:08 ------- I can reproduce the original problem with 28490 by changing the line in ia64_legitimate_constant_p from return (addend & 0x3fff) == 0; to return true; and compiling the testcase with -O. What happens is that in reload.c we see a REG_EQUAL note with symbol+8 and put it in reg_equiv_constant because it is accepted by LEGITIMATE_CONSTANT_P. This then gets substituted into a SET_SRC. Except that this insn now requires a scratch register, and we are after reload, so we end up aborting.
The traditional solution for this is to define LEGITIMATE_PIC_OPERAND_P so that it rejects symbol+const when it would require a scratch register. See the sparc port for instance. However, this works only if flag_pic is set. IA-64 is PIC always, and we use flag_pic for shared libraries, so we can't just set it. Or at least, I'm not sure what will happen if we set it, and I don't want to spend that much time looking into it. Another traditional solution is to rewrite pic symbols in such a way that they can't be recognized as constants anymore, for instance, by putting them inside unspecs. This is ugly, and I only mention it for completeness. I don't recommend fixing the problem this way. It might be tempting to check for reload_in_progress, but unfortunately the LEGITIMATE_CONSTANT_P check in reload1.c comes before reload_in_progress is set, so that won't work. And messing with reload isn't a good idea, so we shouldn't try moving where reload_in_progress is set. That leaves the currently_expanding_to_rtl solution. We can accept any constant if that var is true, and we use the current code if that var is false. I think this is the second best solution after the LEGITIMATE_PIC_OPERAND_P solution. I tried this, and found that it is an imperfect solution. I don't get a core dump for 28490, and I don't get a constant pool entry for the 42040 testcase. Unfortunately, I do now get a constant pool entry for the 28490 testcase. Because symbol+8 is no longer a LEGITIMATE_CONSTANT_P, reload decides to call force_const_mem and put it in reg_equiv_memory_loc. So this solution doesn't completely eliminate the constant pool entries, but it will eliminate most of them. To eliminate all of them, we would have to get the LEGITIMATE_PIC_OPERAND_P solution working. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42040