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))

Reply via email to