On Wed, Jun 26, 2013 at 3:39 PM, Yufeng Zhang <yufeng.zh...@arm.com> wrote: > This patch updates assign_parm_find_data_types to assign passed_mode and > nominal_mode with the mode of the built pointer type instead of the > hard-coded Pmode in the case of pass-by-reference. This is in line with the > assignment to passed_mode and nominal_mode in other cases inside the > function. > > assign_parm_find_data_types generally uses TYPE_MODE to calculate > passed_mode and nominal_mode: > > /* Find mode of arg as it is passed, and mode of arg as it should be > during execution of this function. */ > passed_mode = TYPE_MODE (passed_type); > nominal_mode = TYPE_MODE (nominal_type); > > this includes the case when the passed argument is a pointer by itself. > > However there is a discrepancy when it deals with argument passed by > invisible reference; it builds the argument's corresponding pointer type, > but sets passed_mode and nominal_mode with Pmode directly. > > This is OK for targets where Pmode == ptr_mode, but on AArch64 with ILP32 > they are different with Pmode as DImode and ptr_mode as SImode. When such a > reference is passed on stack, the reference is prepared by the caller in the > lower 4 bytes of an 8-byte slot but is fetched by the callee as an 8-byte > datum, of which the higher 4 bytes may contain junk. It is probably the > combination of Pmode != ptr_mode and the particular ABI specification that > make the AArch64 ILP32 the first target on which the issue manifests itself. > > Bootstrapped on x86_64-none-linux-gnu. > > OK for the trunk?
IA64-hpux also uses Pmode != ptr_mode, can you provide the testcase which fails without this change? I used a powerpc64 target where Pmode != ptr_mode which did not hit this bug either. Thanks, Andrew > > Thanks, > Yufeng > > > gcc/ > * function.c (assign_parm_find_data_types): Set passed_mode and > nominal_mode to the TYPE_MODE of nominal_type for the built > pointer type in case of the struct-pass-by-reference.