------- Comment #7 from jakub at gcc dot gnu dot org 2008-10-22 15:37 ------- Was the "I am reasonably sure it will only affect only E500" comment in http://gcc.gnu.org/ml/gcc-patches/2008-06/msg00255.html meant for this patch or the other one? Clearly it makes a big difference. I think the bug is that emit_group_store is called with NULL_TREE third argument (the type) in the new assign_parm_remove_parallels function, while previously it has been called sometimes with NULL_TREE (if nominal_mode != passed_mode) or nominal_type (if the modes are the same) or with passed_type in another part of the routine. And on PA BLOCK_REG_PASSING depends on the type, particularly has different results if type is non-NULL and aggregate vs. NULL or non-aggregate.
--- function.c.jj10 2008-09-30 16:57:11.000000000 +0200 +++ function.c 2008-10-22 17:32:26.000000000 +0200 @@ -2436,7 +2436,9 @@ assign_parm_remove_parallels (struct ass if (GET_CODE (entry_parm) == PARALLEL && GET_MODE (entry_parm) != BLKmode) { rtx parmreg = gen_reg_rtx (GET_MODE (entry_parm)); - emit_group_store (parmreg, entry_parm, NULL_TREE, + emit_group_store (parmreg, entry_parm, + data->nominal_mode == data->passed_mode + ? data->passed_type : NULL_TREE, GET_MODE_SIZE (GET_MODE (entry_parm))); entry_parm = parmreg; } patch fixes this for me (at least, from eyeballing assembly and/or RTL from a cross compiler), though I'm not sure if data->passed_type or data->nominal_type should be used and whether the data->nominal_mode == data->passed_mode guard is needed or not. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37316