{
       if (rtl == NULL_RTX || is_pseudo_reg (rtl))
        {
-         tree declared_type = type_main_variant (TREE_TYPE (decl));
-         tree passed_type = type_main_variant (DECL_ARG_TYPE (decl));
+         tree declared_type = TREE_TYPE (decl);
+         tree passed_type = DECL_ARG_TYPE (decl);
+         enum machine_mode dmode = TYPE_MODE (declared_type);
+         enum machine_mode pmode = TYPE_MODE (passed_type);
 
          /* This decl represents a formal parameter which was optimized out.
             Note that DECL_INCOMING_RTL may be NULL in here, but we handle
             all cases where (rtl == NULL_RTX) just below.  */
-         if (declared_type == passed_type)
-           rtl = DECL_INCOMING_RTL (decl);
-         else if (! BYTES_BIG_ENDIAN
-                  && TREE_CODE (declared_type) == INTEGER_TYPE
-                  && (GET_MODE_SIZE (TYPE_MODE (declared_type))
-                      <= GET_MODE_SIZE (TYPE_MODE (passed_type))))
+         if (dmode == pmode)
            rtl = DECL_INCOMING_RTL (decl);
+         else if (SCALAR_INT_MODE_P (dmode)
+                  && GET_MODE_SIZE (dmode) <= GET_MODE_SIZE (pmode))
+           {
+             rtx inc = DECL_INCOMING_RTL (decl);
+             if (REG_P (inc))
+               rtl = inc;
+             else if (MEM_P (inc))
+               {
+                 if (BYTES_BIG_ENDIAN)
+                   rtl = adjust_address_nv (inc, dmode,
+                                            GET_MODE_SIZE (pmode)
+                                            - GET_MODE_SIZE (dmode));
+                 else
+                   rtl = inc;
+               }
+           }
        }
 
       /* If the parm was passed in registers, but lives on the stack, then