------- Comment #18 from dave at hiauly1 dot hia dot nrc dot ca 2008-10-25
16:53 -------
Subject: Re: [4.4 Regression] Small structs are not passed correctly on
hppa64-*-*
> emit_group_store clearly doesn't care about BLOCK_REG_PADDING if dst is
> CONCAT,
> I think the code pretty much assumes that GET_MODE_SIZE (dest_mode) ==
> GET_MODE_SIZE (tmps[i]). If bytepos, adj_bytelen pair pick up just the first
> or second register of the CONCAT, then it is I think fine, the code falls
> through
> into the optional down shift depending on BLOCK_REG_PADDING and
> store_bit_field
> which always takes lsb bits from tmps[i].
> But for the case where both regs of the CONCAT need to be set, nothing
> considers BLOCK_REG_PADDING at all. In the GET_MODE_ALIGNMENT (dest_mode) <
> GET_MODE_ALIGNMENT (tmp_mode) case, it would be enough just to add some offset
> to the address depending on BLOCK_REG_PADDING, but in the other case we might
> be even allocating a stack slot smaller than needed.
Regarding BLOCK_REG_PADDING, there is a bug in function_arg_padding in pa.c.
It is not handling complex and vector types. This explains the incorrect
padding. The test in comment #16 passes with the following change:
Index: config/pa/pa.c
===================================================================
--- config/pa/pa.c (revision 141361)
+++ config/pa/pa.c (working copy)
@@ -5888,7 +5888,11 @@
function_arg_padding (enum machine_mode mode, const_tree type)
{
if (mode == BLKmode
- || (TARGET_64BIT && type && AGGREGATE_TYPE_P (type)))
+ || (TARGET_64BIT
+ && type
+ && (AGGREGATE_TYPE_P (type)
+ || TREE_CODE (type) == COMPLEX_TYPE
+ || TREE_CODE (type) == VECTOR_TYPE)))
{
/* Return none if justification is not required. */
if (type
@@ -9277,7 +9281,7 @@
offset += 8;
}
- return gen_rtx_PARALLEL (mode, gen_rtvec_v (ub, loc));
+ return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (ub, loc));
}
}
else
The latter hunk works around the incorrect argument value passed
from checkgcc to checkcc when downward padding is specified. The
idea was simply that BLOCK_REG_PADDING applies to blocks. The
32-bit code already uses BLKmode.
This bug went away when I changed the padding for complex and vector
types to upward.
I'm not sure why Daniel's change exposed this problem, but is
probably a separate issue.
Dave
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37316