------- 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