This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/36800] New: va_arg for _Decimal128 on 32-bit Power mishandled in certain cases
- From: "jsm28 at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 10 Jul 2008 23:40:52 -0000
- Subject: [Bug target/36800] New: va_arg for _Decimal128 on 32-bit Power mishandled in certain cases
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
The following fails on 32-bit hard-float powerpc*-*-linux* (tested for trunk,
code inspection indicates present for 4.3 as well).
#include <stdarg.h>
extern void abort (void);
void
f (int a, ...)
{
va_list ap;
if (a != 0)
abort ();
va_start (ap, a);
if (va_arg (ap, _Decimal128) != 1.2DL)
abort ();
if (va_arg (ap, _Decimal128) != 2.34DL)
abort ();
if (va_arg (ap, _Decimal128) != 3.456DL)
abort ();
if (va_arg (ap, _Decimal128) != 4.567DL)
abort ();
if (va_arg (ap, double) != 5.125)
abort ();
va_end (ap);
}
int
main (void)
{
f (0, 1.2DL, 2.34DL, 3.456DL, 4.567DL, 5.125);
return 0;
}
Suppose some arguments are passed in floating-point registers using all but
f8 and maybe f7 of the registers available for floating-point arguments.
Suppose the next argument is _Decimal128, so is passed on the stack because
an aligned pair of registers is not available, and that this _Decimal128
argument is one of the variable arguments in a call to a variadic function,
and that a following argument is one that would fit in a single floating-point
register if the _Decimal128 argument hadn't forced all subsequent
floating-point arguments to go on the stack.
Then the code to ensure that subsequent va_arg calls after the one getting
that _Decimal128 argument do not look in the saved floating-point
registers
if ((n_reg == 2 && !regalign) || n_reg > 2)
{
/* Ensure that we don't find any more args in regs.
Alignment has taken care of for special cases. */
t = build_gimple_modify_stmt (reg,
build_int_cst (TREE_TYPE (reg), 8));
gimplify_and_add (t, pre_p);
}
does not trigger because regalign is set. But unlike the alignment for
pairs of GPRs, the alignment here sets fpr to 7 leaving a subsequent va_arg
call thinking it can take a value from f8.
I think the fix is simply not to set regalign in this case, but I haven't
tested this.
--
Summary: va_arg for _Decimal128 on 32-bit Power mishandled in
certain cases
Product: gcc
Version: 4.4.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: jsm28 at gcc dot gnu dot org
GCC target triplet: powerpc*-*-linux*
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36800