diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 225b3bcae34360f400f48664c32fadb6ef7195b0..8194605cf6f29b56e8727376b3fdb3cba110511a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+Thu Feb 24 20:04:11 2000  J"orn Rennecke <amylaar@cygnus.co.uk>
+
+	Fix breakage from 6th Feb thread_prologue_and_epilogue_insns change:
+	* sh-protos.h (sh_need_epilogue): Declare.
+	* sh.c (sh_need_epilogue_known): New static variable.
+	(sh_need_epilogue): New function.
+	(function_epilogue): Clear need_epilogue_known.
+	* sh.md (return): Split into expander / insn pattern.
+	Make the expander conditional on ! sh_need_epilogue ().
+
 2000-02-24  Nathan Sidwell  <nathan@codesourcery.com>
 
 	* machmode.h (get_mode_alignment): Declare.
diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h
index 273444b2c6de17eda0d046f0b4fe397f68561212..402bf6068ab0e4706a77156314d480f512b2134c 100644
--- a/gcc/config/sh/sh-protos.h
+++ b/gcc/config/sh/sh-protos.h
@@ -107,6 +107,7 @@ extern struct rtx_def *get_fpscr_rtx PARAMS ((void));
 extern void output_file_start PARAMS ((FILE *));
 extern void sh_expand_prologue PARAMS ((void));
 extern void sh_expand_epilogue PARAMS ((void));
+extern int sh_need_epilogue PARAMS ((void));
 extern void function_epilogue PARAMS ((FILE *, int));
 extern int initial_elimination_offset PARAMS ((int, int));
 extern void emit_fpscr_use PARAMS ((void));
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 8c10ca55ee974d84f8d558448ad9e14f98743e48..c90fdb373b4e98067807dfe3748d431c2c3315cf 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -3919,6 +3919,26 @@ sh_expand_epilogue ()
     emit_insn (gen_sp_switch_2 ());
 }
 
+static int sh_need_epilogue_known = 0;
+
+int
+sh_need_epilogue ()
+{
+  if (! sh_need_epilogue_known)
+    {
+      rtx epilogue;
+
+      start_sequence ();
+      sh_expand_epilogue ();
+      epilogue = gen_sequence ();
+      end_sequence ();
+      sh_need_epilogue_known
+	= (GET_CODE (epilogue) == SEQUENCE && XVECLEN (epilogue, 0) == 0
+	   ? -1 : 1);
+    }
+  return sh_need_epilogue_known > 0;
+}
+
 /* Clear variables at function end.  */
 
 void
@@ -3927,6 +3947,7 @@ function_epilogue (stream, size)
      int size ATTRIBUTE_UNUSED;
 {
   trap_exit = pragma_interrupt = pragma_trapa = pragma_nosave_low_regs = 0;
+  sh_need_epilogue_known = 0;
   sp_switch = NULL_RTX;
 }
 
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 903199e119bfeb0a0561a23f716517b8feb0dc27..62aac30d9c99594c830476a9349531762949a9f0 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -3484,12 +3484,12 @@
 }"
   [(set_attr "length" "4")])
 
-;; ??? This is not the proper place to invoke another compiler pass;
-;; Alas, there is no proper place to put it.
-;; ??? This is also an odd place for the call to emit_fpscr_use.  It
-;; would be all right if it were for an define_expand for return, but
-;; that doesn't mix with emitting a prologue.
-(define_insn "return"
+(define_expand "return"
+  [(return)]
+  "reload_completed && ! sh_need_epilogue ()"
+  "")
+
+(define_insn "*return_i"
   [(return)]
   "reload_completed"
   "%@	%#"