This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR c/6358
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Henderson <rth at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 18 Apr 2002 18:40:36 +0200
- Subject: [PATCH] Fix PR c/6358
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
The following testcase would ICE, because current_function_return_rtx
was used (in diddle_return_value called down from expand_null_return)
before it was changed to the actual hard register in expand_function_end.
Thus, we ended up with:
(insn 10 8 11 (clobber (reg:DF 58)) -1 (nil)
(nil))
(insn 11 10 12 (clobber (reg:DF 58)) -1 (nil)
(nil))
(jump_insn 12 11 13 (set (pc)
(label_ref 16)) -1 (nil)
(nil))
(barrier 13 12 14)
(note 14 13 19 NOTE_INSN_FUNCTION_END)
(insn 19 14 20 (clobber (reg/i:DF 8 st(0))) -1 (nil)
(nil))
(insn 20 19 16 (clobber (reg:DF 58)) -1 (nil)
(nil))
(code_label 16 20 18 1 "" "" [0 uses])
(insn 18 16 21 (set (reg/i:DF 8 st(0))
(reg:DF 58)) -1 (nil)
(nil))
(insn 21 18 0 (use (reg/i:DF 8 st(0))) -1 (nil)
(nil))
while insn 10 should have been (clobber (reg/i:DF 8 st(0))).
Fixed by splitting real_decl_rtl assignment into assign_parms
and leaving the rest (copying DECL_RTL(DECL_RESULT(current_function_decl))
into it) in expand_function_end.
>From what I could see, all users of current_function_return_rtx outside
of function.c are post expand_function_end (thus nothing changes for them
by this patch) and the only place where it should make a difference is in
diddle_return_value where we really want the hard register, not pseudo.
Ok to commit if testing succeeds?
2002-04-18 Jakub Jelinek <jakub@redhat.com>
PR c/6358
* function.c (assign_parms): Assign hard current_function_return_rtx
register here...
(expand_function_end): ...not here.
* gcc.c-torture/compile/20020418-1.c: New test.
--- gcc/testsuite/gcc.c-torture/compile/20020418-1.c.jj Thu Apr 18 18:39:31 2002
+++ gcc/testsuite/gcc.c-torture/compile/20020418-1.c Thu Apr 18 18:35:44 2002
@@ -0,0 +1,18 @@
+/* PR c/6358
+ This testcase ICEd on IA-32 in foo, because current_function_return_rtx
+ was assigned a hard register only after expand_null_return was called,
+ thus return pseudo was clobbered twice and the hard register not at
+ all. */
+
+void baz (void);
+
+double foo (void)
+{
+ baz ();
+ return;
+}
+
+double bar (void)
+{
+ baz ();
+}
--- gcc/function.c.jj Mon Apr 15 14:42:04 2002
+++ gcc/function.c Thu Apr 18 18:31:42 2002
@@ -5144,6 +5144,35 @@ assign_parms (fndecl)
current_function_return_rtx
= (DECL_RTL_SET_P (DECL_RESULT (fndecl))
? DECL_RTL (DECL_RESULT (fndecl)) : NULL_RTX);
+
+ /* If scalar return value was computed in a pseudo-reg, or was a named
+ return value that got dumped to the stack, copy that to the hard
+ return register. */
+ if (DECL_RTL_SET_P (DECL_RESULT (fndecl)))
+ {
+ tree decl_result = DECL_RESULT (fndecl);
+ rtx decl_rtl = DECL_RTL (decl_result);
+
+ if (REG_P (decl_rtl)
+ ? REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER
+ : DECL_REGISTER (decl_result))
+ {
+ rtx real_decl_rtl;
+
+#ifdef FUNCTION_OUTGOING_VALUE
+ real_decl_rtl = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl_result),
+ fndecl);
+#else
+ real_decl_rtl = FUNCTION_VALUE (TREE_TYPE (decl_result),
+ fndecl);
+#endif
+ REG_FUNCTION_VALUE_P (real_decl_rtl) = 1;
+ /* The delay slot scheduler assumes that current_function_return_rtx
+ holds the hard register containing the return value, not a
+ temporary pseudo. */
+ current_function_return_rtx = real_decl_rtl;
+ }
+ }
}
/* Indicate whether REGNO is an incoming argument to the current function
@@ -6957,16 +6986,11 @@ expand_function_end (filename, line, end
? REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER
: DECL_REGISTER (decl_result))
{
- rtx real_decl_rtl;
+ rtx real_decl_rtl = current_function_return_rtx;
-#ifdef FUNCTION_OUTGOING_VALUE
- real_decl_rtl = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl_result),
- current_function_decl);
-#else
- real_decl_rtl = FUNCTION_VALUE (TREE_TYPE (decl_result),
- current_function_decl);
-#endif
- REG_FUNCTION_VALUE_P (real_decl_rtl) = 1;
+ /* This should be set in assign_parms. */
+ if (! REG_FUNCTION_VALUE_P (real_decl_rtl))
+ abort ();
/* If this is a BLKmode structure being returned in registers,
then use the mode computed in expand_return. Note that if
@@ -6994,11 +7018,6 @@ expand_function_end (filename, line, end
int_size_in_bytes (TREE_TYPE (decl_result)));
else
emit_move_insn (real_decl_rtl, decl_rtl);
-
- /* The delay slot scheduler assumes that current_function_return_rtx
- holds the hard register containing the return value, not a
- temporary pseudo. */
- current_function_return_rtx = real_decl_rtl;
}
}
Jakub