public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* strengthen protection against REG_EQUIV/EQUAL on !REG set
@ 2012-04-12  9:54 Olivier Hainque
  2012-04-12 10:02 ` Olivier Hainque
  2012-04-24 22:06 ` Richard Sandiford
  0 siblings, 2 replies; 11+ messages in thread
From: Olivier Hainque @ 2012-04-12  9:54 UTC (permalink / raw)
  To: GCC Patches; +Cc: Olivier Hainque

[-- Attachment #1: Type: text/plain, Size: 931 bytes --]

Hello,

This is a followup on a suggestion made along the thread at

  http://gcc.gnu.org/ml/gcc-patches/2010-09/msg00967.html

where we were observing the middle-end setting invalid REG_EQUIV
notes on set(mem) insns. At the time we had fixed specific locations
where this was happening via explicit calls to set_unique_reg_note.

Steven suggested to add some code to set_unique_reg_note as well. This
patch implements this suggestion. We (AdaCore) have been using it without
problem for a while now, it turned out useful to prevent a real case in
the gcc-4.5 series and we never saw the original issue resurface again
since then.

Bootstrapped and regtested on x86_64-suse-linux

OK to commit ?

Thanks in advance,

With Kind Regards,

Olivier

2012-04-12  Olivier Hainque  <hainque@adacore.com>

 	* emit-rtl.c (set_unique_reg_note): Don't add REG_EQUAL or REG_EQUIV
	on a SET if the destination isn't a REG or a SUBREG of REG.


[-- Attachment #2: regequiv.dif --]
[-- Type: video/x-dv, Size: 982 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread
* strengthen protection against REG_EQUIV/EQUAL on !REG set
@ 2014-05-26 12:28 Olivier Hainque
  2014-05-27 18:23 ` Jeff Law
  0 siblings, 1 reply; 11+ messages in thread
From: Olivier Hainque @ 2014-05-26 12:28 UTC (permalink / raw)
  To: gcc-patches; +Cc: Olivier Hainque, Richard Sandiford

[-- Attachment #1: Type: text/plain, Size: 796 bytes --]

Hello,

This is a follow up on a thread started long ago there:

  http://gcc.gnu.org/ml/gcc-patches/2010-09/msg00967.html

With a first followup and a patch proposal there:

  http://gcc.gnu.org/ml/gcc-patches/2012-04/msg00731.html

Then a refinement suggested by Richard Sandiford here:

  http://gcc.gnu.org/ml/gcc-patches/2012-04/msg01515.html

We have been running with the proposed patch for years now,
it still applies on mainline and bootstraps + regtests fine
on x86_64-linux for languages=all,ada.

Ok to commit ?

Thanks in advance,

With Kind Regards,

Olivier

2014-05-26  Richard Sandiford  <rdsandiford@googlemail.com>

	* rtl.h (set_for_reg_notes): Declare.
	* emit-rtl.c (set_for_reg_notes): New function.
	(set_unique_reg_note): Use it.
	* optabs.c (add_equal_note): Likewise.


[-- Attachment #2: ehregnote.diff --]
[-- Type: application/octet-stream, Size: 3651 bytes --]

diff --git gcc/emit-rtl.c gcc/emit-rtl.c
index 4736f8d..b066111 100644
--- gcc/emit-rtl.c
+++ gcc/emit-rtl.c
@@ -4956,6 +4956,45 @@ gen_use (rtx x)
   return seq;
 }
 
+/* Notes like REG_EQUAL and REG_EQUIV refer to a set in an instruction.
+   Return the set in INSN that such notes describe, or NULL if the notes
+   have no meaning for INSN.  */
+
+rtx
+set_for_reg_notes (rtx insn)
+{
+  rtx pat, reg;
+
+  if (!INSN_P (insn))
+    return NULL_RTX;
+
+  pat = PATTERN (insn);
+  if (GET_CODE (pat) == PARALLEL)
+    {
+      /* We do not use single_set because that ignores SETs of unused
+	 registers.  REG_EQUAL and REG_EQUIV notes really do require the
+	 PARALLEL to have a single SET.  */
+      if (multiple_sets (insn))
+	return NULL_RTX;
+      pat = XVECEXP (pat, 0, 0);
+    }
+
+  if (GET_CODE (pat) != SET)
+    return NULL_RTX;
+
+  reg = SET_DEST (pat);
+
+  /* Notes apply to the contents of a STRICT_LOW_PART.  */
+  if (GET_CODE (reg) == STRICT_LOW_PART)
+    reg = XEXP (reg, 0);
+
+  /* Check that we have a register.  */
+  if (!(REG_P (reg) || GET_CODE (reg) == SUBREG))
+    return NULL_RTX;
+
+  return pat;
+}
+
 /* Place a note of KIND on insn INSN with DATUM as the datum. If a
    note of this type already exists, remove it first.  */
 
@@ -4968,39 +5007,26 @@ set_unique_reg_note (rtx insn, enum reg_note kind, rtx datum)
     {
     case REG_EQUAL:
     case REG_EQUIV:
-      /* Don't add REG_EQUAL/REG_EQUIV notes if the insn
-	 has multiple sets (some callers assume single_set
-	 means the insn only has one set, when in fact it
-	 means the insn only has one * useful * set).  */
-      if (GET_CODE (PATTERN (insn)) == PARALLEL && multiple_sets (insn))
-	{
-	  gcc_assert (!note);
-	  return NULL_RTX;
-	}
+      if (!set_for_reg_notes (insn))
+	return NULL_RTX;
 
       /* Don't add ASM_OPERAND REG_EQUAL/REG_EQUIV notes.
 	 It serves no useful purpose and breaks eliminate_regs.  */
       if (GET_CODE (datum) == ASM_OPERANDS)
 	return NULL_RTX;
-
-      if (note)
-	{
-	  XEXP (note, 0) = datum;
-	  df_notes_rescan (insn);
-	  return note;
-	}
       break;
 
     default:
-      if (note)
-	{
-	  XEXP (note, 0) = datum;
-	  return note;
-	}
       break;
     }
 
-  add_reg_note (insn, kind, datum);
+  if (note)
+    XEXP (note, 0) = datum;
+  else
+    {
+      add_reg_note (insn, kind, datum);
+      note = REG_NOTES (insn);
+    }
 
   switch (kind)
     {
@@ -5012,14 +5038,14 @@ set_unique_reg_note (rtx insn, enum reg_note kind, rtx datum)
       break;
     }
 
-  return REG_NOTES (insn);
+  return note;
 }
 
 /* Like set_unique_reg_note, but don't do anything unless INSN sets DST.  */
 rtx
 set_dst_reg_note (rtx insn, enum reg_note kind, rtx datum, rtx dst)
 {
-  rtx set = single_set (insn);
+  rtx set = set_for_reg_notes (insn);
 
   if (set && SET_DEST (set) == dst)
     return set_unique_reg_note (insn, kind, datum);
diff --git gcc/optabs.c gcc/optabs.c
index e16f055..8480627 100644
--- gcc/optabs.c
+++ gcc/optabs.c
@@ -228,7 +228,7 @@ add_equal_note (rtx insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
       return 0;
     }
 
-  set = single_set (last_insn);
+  set = set_for_reg_notes (last_insn);
   if (set == NULL_RTX)
     return 1;
 
diff --git gcc/rtl.h gcc/rtl.h
index f1cda4c..445cb4b 100644
--- gcc/rtl.h
+++ gcc/rtl.h
@@ -1987,6 +1987,7 @@ extern enum machine_mode choose_hard_reg_mode (unsigned int, unsigned int,
 					       bool);
 
 /* In emit-rtl.c  */
+extern rtx set_for_reg_notes (rtx);
 extern rtx set_unique_reg_note (rtx, enum reg_note, rtx);
 extern rtx set_dst_reg_note (rtx, enum reg_note, rtx, rtx);
 extern void set_insn_deleted (rtx);

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2014-05-28  8:42 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-12  9:54 strengthen protection against REG_EQUIV/EQUAL on !REG set Olivier Hainque
2012-04-12 10:02 ` Olivier Hainque
2012-04-24 22:06 ` Richard Sandiford
2012-04-26  8:39   ` Olivier Hainque
2012-05-04 13:34     ` Olivier Hainque
2012-05-04 14:16       ` Richard Sandiford
2012-05-04 15:44         ` Olivier Hainque
2012-05-07  9:36         ` Richard Sandiford
2014-05-26 12:28 Olivier Hainque
2014-05-27 18:23 ` Jeff Law
2014-05-28  8:42   ` Olivier Hainque

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).