From fc0cc704f6899e6f13f244d5530fe3e002f1d997 Mon Sep 17 00:00:00 2001
From: ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Tue, 1 Feb 2005 07:22:19 +0000
Subject: [PATCH] 	Patch from Richard Sandiford <rsandifo@redhat.com> 
 * reload1.c (choose_reload_regs): Prevent the find_equiv_reg() code 	from
 inheriting a subreg equivalence with a non-spill register.

	* tree.h (DECL_FUNCTION_CODE): Document that it is overloaded.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@94529 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog | 8 ++++++++
 gcc/reload1.c | 9 +++++++++
 gcc/tree.h    | 6 ++++--
 3 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ce0422c9323b..343125f41133 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2005-02-01  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+	Patch from Richard Sandiford <rsandifo@redhat.com>
+	* reload1.c (choose_reload_regs): Prevent the find_equiv_reg() code
+	from inheriting a subreg equivalence with a non-spill register.
+
+	* tree.h (DECL_FUNCTION_CODE): Document that it is overloaded.
+
 2005-02-01  Alexandre Oliva  <aoliva@redhat.com>
 
 	* config/frv/frv.c (movcc_fp_destination_operand): New.
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 7961c99b9c46..d4141be5aee2 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -5589,6 +5589,15 @@ choose_reload_regs (struct insn_chain *chain)
 		      gcc_assert (GET_CODE (equiv) == SUBREG);
 		      regno = subreg_regno (equiv);
 		      equiv = gen_rtx_REG (rld[r].mode, regno);
+		      /* If we choose EQUIV as the reload register, but the
+			 loop below decides to cancel the inheritance, we'll
+			 end up reloading EQUIV in rld[r].mode, not the mode
+			 it had originally.  That isn't safe when EQUIV isn't
+			 available as a spill register since its value might
+			 still be live at this point.  */
+		      for (i = regno; i < regno + (int) rld[r].nregs; i++)
+			if (TEST_HARD_REG_BIT (reload_reg_unavailable, i))
+			  equiv = 0;
 		    }
 		}
 
diff --git a/gcc/tree.h b/gcc/tree.h
index a4c590b476ab..10012e406fd3 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2000,8 +2000,10 @@ struct tree_binfo GTY (())
    that describes the status of this function.  */
 #define DECL_STRUCT_FUNCTION(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.u2.f)
 
-/* For FUNCTION_DECL, if it is built-in,
-   this identifies which built-in operation it is.  */
+/* For FUNCTION_DECL, if it is built-in, this identifies which built-in
+   operation it is.  Note, however, that this field is overloaded, with
+   DECL_BUILT_IN_CLASS as the discriminant, so the latter must always be
+   checked before any access to the former.  */
 #define DECL_FUNCTION_CODE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.u1.f)
 
 /* The DECL_VINDEX is used for FUNCTION_DECLS in two different ways.
-- 
GitLab