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]

Re: Candidate fix for ia64 compat/struct-return-19 failure


Zack Weinberg wrote:

The compat/struct-return-19 testcase has been failing on ia64-hpux
(and I imagine all other ia64 targets as well) for some time.  I have
tracked the problem to an improperly handled case in several parts of
the code generation for function calls.

On ia64, this structure

struct Ssds { struct Sd { double d; } sd; };

is passed in registers and returned in registers.  Floating-point
registers.  (It's a 'homogenous floating-point aggregate'.)  GCC
emits code to load it into the appropriate floating point register for
both call and return, but it uses the wrong move instruction: the one
you're supposed to use to load an integer into a floating-point
register.  (ldf8 instead of ldfd; setf.sig instead of setf.d; etc.)
This garbles the value.

The basic issue is that calls.c, expr.c, function.c, and ia64.c all
assume in various places that a BLKmode quantity is to be loaded into
a register, any register, using word_mode (DImode, in this case)
moves.  This is wrong when loading a DFmode value into one of the
ia64's floating point registers; it's gotta be loaded as DFmode or it
will be mangled.

The simplest fix for this problem that I can find is to give the
structure type DFmode instead of BLKmode.  This is the default
behavior, but it's being overridden in ia64/hpux.h by
MEMBER_TYPE_FORCES_BLK, which evaluates true for any nested structure
no matter what its contents.  As far as I can tell, the point of that
definition is to get a structure containing a short integer to be
passed in the high half of the register as required for big-endian
IA64.  (Y'all may puke now.)  Giving BLKmode to the above structure is
unintentional.  This can easily be corrected by having
MEMBER_TYPE_FORCES_BLK look only at its mode argument, and that is
what the patch does.

There is no PR for this failure but I would like to suggest it for 3.4
anyway since it fixes a calling-convention bug.  (There are no ABI
consequences - it's passing the wrong value in the right place.)  The
patch by definition cannot affect any target other than ia64-hpux.

Bootstrapped on ia64-hp-hpux11.23 (3.4 branch, C/C++ only) with no
regressions.  OK mainline?  3.4 branch?

Yup, this is OK for mainline and 3.4.0.

Thanks for detailed explanation.

--
Mark Mitchell
CodeSourcery, LLC
(916) 791-8304
mark@codesourcery.com


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