This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix struct passing on targets that rely on TYPE in BLOCK_REG_PADDING if mode is not BLKmode (PR middle-end/37316)


Hi!

Daniel's 2008-07-0{1,7} function.c changes added
assign_parm_remove_parallels call that replaced some code in
assign_parm_setup_block.  Previously, emit_group_store in
assign_parm_setup_block was being passed 3 different types
in different places.
For non-BLKmode parallels with more than one hard reg containing
the parameter and use_register_for_decl (parm) it used:
          if (data->nominal_mode != data->passed_mode)
            {
              rtx t = gen_reg_rtx (GET_MODE (entry_parm));
              emit_group_store (t, entry_parm, NULL_TREE,
                                GET_MODE_SIZE (GET_MODE (entry_parm)));
              convert_move (parmreg, t, 0);
            }
          else
            emit_group_store (parmreg, entry_parm, data->nominal_type,
                              int_size_in_bytes (data->nominal_type));
and otherwise:
emit_group_store (mem, entry_parm, data->passed_type, size);
The last call remains in assign_parm_setup_block and
assign_parm_remove_parallels handles the non-BLKmode cases only,
but it passes NULL_TREE as type to emit_group_store.
On targets that look at type in BLOCK_REG_PADDING macro
even for non-BLKmode mode this means (or could mean) an ABI change.
On the calls.c side, emit_group_load* is always passed
TREE_TYPE (arg->tree_value), except for libcalls where NULL_TREE
is passed.  I believe this corresponds to passed_type, so I'd say
we should use data->passed_type always (and it certainly fixes the
testcase referenced in the PR).  After all, we should care about
the type in which the arguments is passed, what type is used in the
rest of the function should be irrelevant for how it is padded in the
hard registers.

I've bootstrapped/regtested this on x86_64-linux, which doesn't say
much, given that emit_group_store doesn't care about type if
BLOCK_REG_PADDING isn't defined.  BLOCK_REG_PADDING is
defined on arm, mips, pa and some powerpc variants, but
apparently on powerpc64-linux I have access to type is only looked
at if mode is BLKmode.  On TARGET_AAPCS_BASED big endian ARM
type is dereferenced unconditionally, so if it works at all, it
can't hit this case (i.e. can't use partial regs in PARALLELs),
on other ARMs it is ignored.  So the only places where this
patch could make a difference is:
1) hppa*-*
2) powerpc*-aix* (AGGREGATES_PAD_UPWARD_ALWAYS 1)
3) maybe mips*-*
Unfortunately, I have access to none of these, could somebody please
bootstrap/regtest this there?  It can affect only the callee
side, not caller, so if there is a problem, it would show up as
an ABI incompatibility between caller and callee.

2008-10-23  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/37316
	* function.c (assign_parm_remove_parallels): Pass
	data->passed_type as third argument to emit_group_store.

--- gcc/function.c.jj	2008-10-23 09:07:04.000000000 +0200
+++ gcc/function.c	2008-10-23 10:52:08.000000000 +0200
@@ -2436,7 +2436,7 @@ 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->passed_type,
 			GET_MODE_SIZE (GET_MODE (entry_parm)));
       entry_parm = parmreg;
     }

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]