diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4f58b58d198757e3764effd53c20efe931bbeff2..93763f25bb64f0fb941506c4746328ad210a7a44 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2004-02-19  Alan Modra  <amodra@bigpond.net.au>
+
+	* function.c (assign_parms): When building decl_rtl for
+	SPLIT_COMPLEX_ARGS, ensure inner modes of concat match outer.
+
 2004-02-19  Olivier Hainque  <hainque@act-europe.fr>
 
 	* expr.c (is_aligning_offset): Check if we are aligning the
diff --git a/gcc/function.c b/gcc/function.c
index bbb9a51b0679fbc32144904522002b7f079058d9..3991ff841fedcfd20ab350e2e06910deeeff1091 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -5231,15 +5231,27 @@ assign_parms (tree fndecl)
 	{
 	  if (TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE)
 	    {
-	      rtx tmp;
-
-	      SET_DECL_RTL (parm,
-			    gen_rtx_CONCAT (DECL_MODE (parm),
-					    DECL_RTL (fnargs),
-					    DECL_RTL (TREE_CHAIN (fnargs))));
-	      tmp = gen_rtx_CONCAT (DECL_MODE (parm),
-				    DECL_INCOMING_RTL (fnargs),
-				    DECL_INCOMING_RTL (TREE_CHAIN (fnargs)));
+	      rtx tmp, real, imag;
+	      enum machine_mode inner = GET_MODE_INNER (DECL_MODE (parm));
+
+	      real = DECL_RTL (fnargs);
+	      imag = DECL_RTL (TREE_CHAIN (fnargs));
+	      if (inner != GET_MODE (real))
+		{
+		  real = gen_lowpart_SUBREG (inner, real);
+		  imag = gen_lowpart_SUBREG (inner, imag);
+		}
+	      tmp = gen_rtx_CONCAT (DECL_MODE (parm), real, imag);
+	      SET_DECL_RTL (parm, tmp);
+
+	      real = DECL_INCOMING_RTL (fnargs);
+	      imag = DECL_INCOMING_RTL (TREE_CHAIN (fnargs));
+	      if (inner != GET_MODE (real))
+		{
+		  real = gen_lowpart_SUBREG (inner, real);
+		  imag = gen_lowpart_SUBREG (inner, imag);
+		}
+	      tmp = gen_rtx_CONCAT (DECL_MODE (parm), real, imag);
 	      set_decl_incoming_rtl (parm, tmp);
 	      fnargs = TREE_CHAIN (fnargs);
 	    }