mips_pic_call_symbol_from_set has code to get the symbol associated with a %call16 reloc, and can also get the symbol from a REG_EQUAL or REG_EQUIV note. But in call-3.c, which tests a call to hidden symbol, we have a plain:
(set (reg ...) (symbol_ref ...)) This patch handles that case too. Tested on mips64-linux-gnu. Applied. Richard gcc/ * config/mips/mips.c (mips_pic_call_symbol_from_set): Check for SYMBOL_REF SET_SRCs. Index: gcc/config/mips/mips.c =================================================================== --- gcc/config/mips/mips.c 2012-08-26 23:14:04.000000000 +0100 +++ gcc/config/mips/mips.c 2012-08-26 23:19:04.403933875 +0100 @@ -14706,13 +14706,13 @@ mips_pic_call_symbol_from_set (df_ref de { rtx note, src, symbol; - /* First, look at REG_EQUAL/EQUIV notes. */ - note = find_reg_equal_equiv_note (def_insn); - if (note && GET_CODE (XEXP (note, 0)) == SYMBOL_REF) - return XEXP (note, 0); - - /* For %call16 references we don't have REG_EQUAL. */ + /* First see whether the source is a plain symbol. This is used + when calling symbols that are not lazily bound. */ src = SET_SRC (set); + if (GET_CODE (src) == SYMBOL_REF) + return src; + + /* Handle %call16 references. */ symbol = mips_strip_unspec_call (src); if (symbol) { @@ -14720,6 +14720,12 @@ mips_pic_call_symbol_from_set (df_ref de return symbol; } + /* If we have something more complicated, look for a + REG_EQUAL or REG_EQUIV note. */ + note = find_reg_equal_equiv_note (def_insn); + if (note && GET_CODE (XEXP (note, 0)) == SYMBOL_REF) + return XEXP (note, 0); + /* Follow at most one simple register copy. Such copies are interesting in cases like: