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