re PR target/44942 (Bug in argument passing of long double)
PR target/44942 * config/i386/i386-protos.h (ix86_function_arg_boundary): Change second argument to const_tree. * config/i386/i386.c (function_arg_advance): If padding needs to be inserted before argument, increment cum->words by number of padding words as well. (contains_aligned_value_p): Change argument to const_tree. (ix86_function_arg_boundary): Change second argument to const_tree. * gcc.c-torture/execute/pr44942.c: New test. * gcc.target/i386/pr44942.c: New test. From-SVN: r162255
This commit is contained in:
parent
ba2dc63db7
commit
88ad03c2cb
@ -1,3 +1,14 @@
|
||||
2010-07-16 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR target/44942
|
||||
* config/i386/i386-protos.h (ix86_function_arg_boundary): Change second
|
||||
argument to const_tree.
|
||||
* config/i386/i386.c (function_arg_advance): If padding needs to be
|
||||
inserted before argument, increment cum->words by number of padding
|
||||
words as well.
|
||||
(contains_aligned_value_p): Change argument to const_tree.
|
||||
(ix86_function_arg_boundary): Change second argument to const_tree.
|
||||
|
||||
2010-07-16 Bernd Schmidt <bernds@codesourcery.com>
|
||||
|
||||
PR target/42235
|
||||
|
@ -140,8 +140,8 @@ extern enum machine_mode ix86_fp_compare_mode (enum rtx_code);
|
||||
extern rtx ix86_libcall_value (enum machine_mode);
|
||||
extern bool ix86_function_arg_regno_p (int);
|
||||
extern void ix86_asm_output_function_label (FILE *, const char *, tree);
|
||||
extern int ix86_function_arg_boundary (enum machine_mode, tree);
|
||||
extern bool ix86_solaris_return_in_memory (const_tree,const_tree);
|
||||
extern int ix86_function_arg_boundary (enum machine_mode, const_tree);
|
||||
extern bool ix86_solaris_return_in_memory (const_tree, const_tree);
|
||||
extern rtx ix86_force_to_memory (enum machine_mode, rtx);
|
||||
extern void ix86_free_from_memory (enum machine_mode);
|
||||
extern enum calling_abi ix86_cfun_abi (void);
|
||||
|
@ -6157,9 +6157,8 @@ function_arg_advance_64 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
if (!named && VALID_AVX256_REG_MODE (mode))
|
||||
return;
|
||||
|
||||
if (!examine_argument (mode, type, 0, &int_nregs, &sse_nregs))
|
||||
cum->words += words;
|
||||
else if (sse_nregs <= cum->sse_nregs && int_nregs <= cum->nregs)
|
||||
if (examine_argument (mode, type, 0, &int_nregs, &sse_nregs)
|
||||
&& sse_nregs <= cum->sse_nregs && int_nregs <= cum->nregs)
|
||||
{
|
||||
cum->nregs -= int_nregs;
|
||||
cum->sse_nregs -= sse_nregs;
|
||||
@ -6167,7 +6166,11 @@ function_arg_advance_64 (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
cum->sse_regno += sse_nregs;
|
||||
}
|
||||
else
|
||||
cum->words += words;
|
||||
{
|
||||
int align = ix86_function_arg_boundary (mode, type) / BITS_PER_WORD;
|
||||
cum->words = (cum->words + align - 1) & ~(align - 1);
|
||||
cum->words += words;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -6508,7 +6511,7 @@ ix86_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
|
||||
/* Return true when TYPE should be 128bit aligned for 32bit argument passing
|
||||
ABI. */
|
||||
static bool
|
||||
contains_aligned_value_p (tree type)
|
||||
contains_aligned_value_p (const_tree type)
|
||||
{
|
||||
enum machine_mode mode = TYPE_MODE (type);
|
||||
if (((TARGET_SSE && SSE_REG_MODE_P (mode))
|
||||
@ -6558,7 +6561,7 @@ contains_aligned_value_p (tree type)
|
||||
specified mode and type. */
|
||||
|
||||
int
|
||||
ix86_function_arg_boundary (enum machine_mode mode, tree type)
|
||||
ix86_function_arg_boundary (enum machine_mode mode, const_tree type)
|
||||
{
|
||||
int align;
|
||||
if (type)
|
||||
|
@ -1,3 +1,9 @@
|
||||
2010-07-16 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR target/44942
|
||||
* gcc.c-torture/execute/pr44942.c: New test.
|
||||
* gcc.target/i386/pr44942.c: New test.
|
||||
|
||||
2010-07-15 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/44909
|
||||
|
70
gcc/testsuite/gcc.c-torture/execute/pr44942.c
Normal file
70
gcc/testsuite/gcc.c-torture/execute/pr44942.c
Normal file
@ -0,0 +1,70 @@
|
||||
/* PR target/44942 */
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
void
|
||||
test1 (int a, int b, int c, int d, int e, int f, int g, long double h, ...)
|
||||
{
|
||||
int i;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, h);
|
||||
i = va_arg (ap, int);
|
||||
if (i != 1234)
|
||||
__builtin_abort ();
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
void
|
||||
test2 (int a, int b, int c, int d, int e, int f, int g, long double h, int i,
|
||||
long double j, int k, long double l, int m, long double n, ...)
|
||||
{
|
||||
int o;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, n);
|
||||
o = va_arg (ap, int);
|
||||
if (o != 1234)
|
||||
__builtin_abort ();
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
void
|
||||
test3 (double a, double b, double c, double d, double e, double f,
|
||||
double g, long double h, ...)
|
||||
{
|
||||
double i;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, h);
|
||||
i = va_arg (ap, double);
|
||||
if (i != 1234.0)
|
||||
__builtin_abort ();
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
void
|
||||
test4 (double a, double b, double c, double d, double e, double f, double g,
|
||||
long double h, double i, long double j, double k, long double l,
|
||||
double m, long double n, ...)
|
||||
{
|
||||
double o;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, n);
|
||||
o = va_arg (ap, double);
|
||||
if (o != 1234.0)
|
||||
__builtin_abort ();
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
test1 (0, 0, 0, 0, 0, 0, 0, 0.0L, 1234);
|
||||
test2 (0, 0, 0, 0, 0, 0, 0, 0.0L, 0, 0.0L, 0, 0.0L, 0, 0.0L, 1234);
|
||||
test3 (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0L, 1234.0);
|
||||
test4 (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0L, 0.0, 0.0L,
|
||||
0.0, 0.0L, 0.0, 0.0L, 1234.0);
|
||||
return 0;
|
||||
}
|
44
gcc/testsuite/gcc.target/i386/pr44942.c
Normal file
44
gcc/testsuite/gcc.target/i386/pr44942.c
Normal file
@ -0,0 +1,44 @@
|
||||
/* PR target/44942 */
|
||||
/* { dg-do run { target lp64 } } */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <emmintrin.h>
|
||||
|
||||
void
|
||||
test1 (double a, double b, double c, double d, double e, double f,
|
||||
double g, __m128d h, ...)
|
||||
{
|
||||
double i;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, h);
|
||||
i = va_arg (ap, double);
|
||||
if (i != 1234.0)
|
||||
__builtin_abort ();
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
void
|
||||
test2 (double a, double b, double c, double d, double e, double f, double g,
|
||||
__m128d h, double i, __m128d j, double k, __m128d l,
|
||||
double m, __m128d n, ...)
|
||||
{
|
||||
double o;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, n);
|
||||
o = va_arg (ap, double);
|
||||
if (o != 1234.0)
|
||||
__builtin_abort ();
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
__m128d m = _mm_set1_pd (7.0);
|
||||
test1 (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, m, 1234.0);
|
||||
test2 (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, m, 0.0, m,
|
||||
0.0, m, 0.0, m, 1234.0);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user