Hi Jeff,
this patch tries to fix the handling of pic_offset_rtx + const(unspec(symbol_ref)+ const_int) in may_trap_p, and restores the original state of affairs in update_equiv_regs. What do you think is it OK to extract the symbol_ref out of the unspec in this way, or is does it need a target hook? Patch works at least for x86_64 and arm. Is it OK for trunk? Bernd.
2017-04-23 Bernd Edlinger <bernd.edlin...@hotmail.de> rtl-optimizatoin/79286 * ira.c (update_equiv_regs): Revert to using may_tap_p again. * rtlanal.c (rtx_addr_can_trap_p_1): SYMBOL_REF_FUNCTION_P can never trap. Extract constant offset from pic_offset_table_rtx + const(unspec(symbol_ref)+int_val) and pic_offset_table_rtx + const(unspec(symbol_ref)), otherwise RTL may trap. Index: gcc/ira.c =================================================================== --- gcc/ira.c (revision 247077) +++ gcc/ira.c (working copy) @@ -3551,7 +3551,8 @@ update_equiv_regs (void) if (DF_REG_DEF_COUNT (regno) == 1 && note && !rtx_varies_p (XEXP (note, 0), 0) - && def_dominates_uses (regno)) + && (!may_trap_or_fault_p (XEXP (note, 0)) + || def_dominates_uses (regno))) { rtx note_value = XEXP (note, 0); remove_note (insn, note); Index: gcc/rtlanal.c =================================================================== --- gcc/rtlanal.c (revision 247077) +++ gcc/rtlanal.c (working copy) @@ -485,7 +485,7 @@ rtx_addr_can_trap_p_1 (const_rtx x, HOST_WIDE_INT case SYMBOL_REF: if (SYMBOL_REF_WEAK (x)) return 1; - if (!CONSTANT_POOL_ADDRESS_P (x)) + if (!CONSTANT_POOL_ADDRESS_P (x) && !SYMBOL_REF_FUNCTION_P (x)) { tree decl; HOST_WIDE_INT decl_size; @@ -645,8 +645,23 @@ rtx_addr_can_trap_p_1 (const_rtx x, HOST_WIDE_INT case PLUS: /* An address is assumed not to trap if: - it is the pic register plus a constant. */ - if (XEXP (x, 0) == pic_offset_table_rtx && CONSTANT_P (XEXP (x, 1))) - return 0; + if (XEXP (x, 0) == pic_offset_table_rtx + && GET_CODE (XEXP (x, 1)) == CONST) + { + x = XEXP (XEXP (x, 1), 0); + if (GET_CODE (x) == UNSPEC + && GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF) + return rtx_addr_can_trap_p_1(XVECEXP (x, 0, 0), + offset, size, mode, unaligned_mems); + if (GET_CODE (x) == PLUS + && GET_CODE (XEXP (x, 0)) == UNSPEC + && GET_CODE (XVECEXP (XEXP (x, 0), 0, 0)) == SYMBOL_REF + && CONST_INT_P (XEXP (x, 1))) + return rtx_addr_can_trap_p_1(XVECEXP (XEXP (x, 0), 0, 0), + offset + INTVAL (XEXP (x, 1)), + size, mode, unaligned_mems); + return 1; + } /* - or it is an address that can't trap plus a constant integer. */ if (CONST_INT_P (XEXP (x, 1))