From 2584991bcfc6246a70190a63d54f13a21fdeba24 Mon Sep 17 00:00:00 2001
From: ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Mon, 6 Oct 2003 08:52:23 +0000
Subject: [PATCH] 2003-10-06  Eric Botcazou  <ebotcazou@libertysurf.fr>

	PR optimization/11637
	* combine.c (adjust_for_new_dest): New function to adjust the
	notes and LOG_LINKS when the dest of an insn has changed.
	(try_combine): Use it when deleting the first insn of a two-insn
	parallel or splitting a two-load parallel.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@72138 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog                     |  9 +++++-
 gcc/combine.c                     | 50 ++++++++++++++++++++++++-------
 gcc/testsuite/ChangeLog           |  4 +++
 gcc/testsuite/g++.dg/opt/float1.C | 21 +++++++++++++
 4 files changed, 72 insertions(+), 12 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/opt/float1.C

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 444fd5897763..2e56e27f8137 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2003-10-06  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+	PR optimization/11637
+	* combine.c (adjust_for_new_dest): New function to adjust the
+	notes and LOG_LINKS when the dest of an insn has changed.
+	(try_combine): Use it when deleting the first insn of a two-insn
+	parallel or splitting a two-load parallel.
+
 2003-10-06  Richard Sandiford  <rsandifo@redhat.com>
 
 	* config/mips/mips.c (mips_classify_constant): Only allow UNSPECs
@@ -77,7 +85,6 @@
 	* config/mn10300/mn10300.md: Likewise.
 	* config/sh/sh.h: Likewise.
 
->>>>>>> 2.1294
 2003-10-05  Richard Henderson  <rth@redhat.com>
 
 	* tree-inline.c (remap_type): New.
diff --git a/gcc/combine.c b/gcc/combine.c
index 5ad0a0fae6db..7a0b5d3cad4d 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -1438,6 +1438,33 @@ cant_combine_insn_p (rtx insn)
   return 0;
 }
 
+/* Adjust INSN after we made a change to its destination.
+
+   Changing the destination can invalidate notes that say something about
+   the results of the insn and a LOG_LINK pointing to the insn.  */
+
+static void
+adjust_for_new_dest (rtx insn)
+{
+  rtx *loc;
+
+  /* For notes, be conservative and simply remove them.  */
+  loc = &REG_NOTES (insn);
+  while (*loc)
+    {
+      enum reg_note kind = REG_NOTE_KIND (*loc);
+      if (kind == REG_EQUAL || kind == REG_EQUIV)
+	*loc = XEXP (*loc, 1);
+      else
+	loc = &XEXP (*loc, 1);
+    }
+
+  /* The new insn will have a destination that was previously the destination
+     of an insn just above it.  Call distribute_links to make a LOG_LINK from
+     the next use of that destination.  */
+  distribute_links (gen_rtx_INSN_LIST (VOIDmode, insn, NULL_RTX));
+}
+
 /* Try to combine the insns I1 and I2 into I3.
    Here I1 and I2 appear earlier than I3.
    I1 can be zero; then we combine just I2 into I3.
@@ -2057,6 +2084,14 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
     {
       newpat = XVECEXP (newpat, 0, 1);
       insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
+ 
+      if (insn_code_number >= 0)
+	{
+	  /* If we will be able to accept this, we have made a change to the
+	     destination of I3.  This requires us to do a few adjustments.  */
+	  PATTERN (i3) = newpat;
+	  adjust_for_new_dest (i3);
+	}
     }
 
   /* If we were combining three insns and the result is a simple SET
@@ -2327,16 +2362,9 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
 	  rtx link;
 
 	  /* If we will be able to accept this, we have made a change to the
-	     destination of I3.  This can invalidate a LOG_LINKS pointing
-	     to I3.  No other part of combine.c makes such a transformation.
-
-	     The new I3 will have a destination that was previously the
-	     destination of I1 or I2 and which was used in i2 or I3.  Call
-	     distribute_links to make a LOG_LINK from the next use of
-	     that destination.  */
-
+	     destination of I3.  This requires us to do a few adjustments.  */
 	  PATTERN (i3) = newpat;
-	  distribute_links (gen_rtx_INSN_LIST (VOIDmode, i3, NULL_RTX));
+	  adjust_for_new_dest (i3);
 
 	  /* I3 now uses what used to be its destination and which is
 	     now I2's destination.  That means we need a LOG_LINK from
@@ -12909,8 +12937,8 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2)
 }
 
 /* Similarly to above, distribute the LOG_LINKS that used to be present on
-   I3, I2, and I1 to new locations.  This is also called in one case to
-   add a link pointing at I3 when I3's destination is changed.  */
+   I3, I2, and I1 to new locations.  This is also called to add a link
+   pointing at I3 when I3's destination is changed.  */
 
 static void
 distribute_links (rtx links)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6361f9e33c26..0264d7a5012c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2003-10-06  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+	* g++.dg/opt/float1.C: New test.
+
 2003-10-04  Eric Botcazou  <ebotcazou@libertysurf.fr>
 
 	* gcc.dg/c90-array-lval-6.c: New test.
diff --git a/gcc/testsuite/g++.dg/opt/float1.C b/gcc/testsuite/g++.dg/opt/float1.C
new file mode 100644
index 000000000000..8f26ed5c852c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/float1.C
@@ -0,0 +1,21 @@
+// PR optimization/11637
+// Origin: <nick@ilm.com>
+
+// This used to fail to assemble on x86 because a decimal
+// floating point litteral was emitted, which originated
+// from a bogus REG_EQUAL note not removed by the combiner.
+
+// { dg-do assemble }
+// { dg-options "-O2 -fnon-call-exceptions" }
+
+void f(long int seed);
+
+void g(float &o)
+{
+  float a = 0.05f;
+  float b = 1.0 - a;
+  float c = 1.0 + a;
+
+  f(0);
+  o = a;
+}
-- 
GitLab