re PR target/39678 (complex type isn't passed correctly)
gcc/ 2009-04-09 H.J. Lu <hongjiu.lu@intel.com> PR target/39678 * config/i386/i386.c (classify_argument): Handle SCmode with (bit_offset % 64) != 0. gcc/testsuite/ 2009-04-09 H.J. Lu <hongjiu.lu@intel.com> PR target/39678 * g++.dg/torture/pr39678.C: New. * gcc.dg/compat/struct-complex-2.h: Likewise. * gcc.dg/compat/struct-complex-2_main.c: Likewise. * gcc.dg/compat/struct-complex-2_x.c: Likewise. * gcc.dg/compat/struct-complex-2_y.c: Likewise. * gcc.dg/torture/pr39678.c: Likewise. * gcc.target/i386/pr39678.c: Likewise. * gcc.dg/compat/struct-complex-1_x.c: Add -Wno-psabi. * gcc.dg/compat/struct-complex-1_y.c: Likewise. * gcc.target/x86_64/abi/test_passing_structs.c: Include <complex.h>. Add tests for structure with complex float. From-SVN: r145865
This commit is contained in:
parent
8c70d28b4d
commit
805586285d
13 changed files with 275 additions and 3 deletions
|
@ -1,3 +1,9 @@
|
|||
2009-04-09 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR target/39678
|
||||
* config/i386/i386.c (classify_argument): Handle SCmode with
|
||||
(bit_offset % 64) != 0.
|
||||
|
||||
2009-04-09 Sandra Loosemore <sandra@codesourcery.com>
|
||||
|
||||
* doc/invoke.texi (Optimize Options): Add cross-reference to
|
||||
|
|
|
@ -5273,7 +5273,22 @@ classify_argument (enum machine_mode mode, const_tree type,
|
|||
return 2;
|
||||
case SCmode:
|
||||
classes[0] = X86_64_SSE_CLASS;
|
||||
return 1;
|
||||
if (!(bit_offset % 64))
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
static bool warned;
|
||||
|
||||
if (!warned && warn_psabi)
|
||||
{
|
||||
warned = true;
|
||||
inform (input_location,
|
||||
"The ABI of passing structure with complex float"
|
||||
" member has changed in GCC 4.4");
|
||||
}
|
||||
classes[1] = X86_64_SSESF_CLASS;
|
||||
return 2;
|
||||
}
|
||||
case DCmode:
|
||||
classes[0] = X86_64_SSEDF_CLASS;
|
||||
classes[1] = X86_64_SSEDF_CLASS;
|
||||
|
|
|
@ -1,3 +1,20 @@
|
|||
2009-04-09 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR target/39678
|
||||
* g++.dg/torture/pr39678.C: New.
|
||||
* gcc.dg/compat/struct-complex-2.h: Likewise.
|
||||
* gcc.dg/compat/struct-complex-2_main.c: Likewise.
|
||||
* gcc.dg/compat/struct-complex-2_x.c: Likewise.
|
||||
* gcc.dg/compat/struct-complex-2_y.c: Likewise.
|
||||
* gcc.dg/torture/pr39678.c: Likewise.
|
||||
* gcc.target/i386/pr39678.c: Likewise.
|
||||
|
||||
* gcc.dg/compat/struct-complex-1_x.c: Add -Wno-psabi.
|
||||
* gcc.dg/compat/struct-complex-1_y.c: Likewise.
|
||||
|
||||
* gcc.target/x86_64/abi/test_passing_structs.c: Include
|
||||
<complex.h>. Add tests for structure with complex float.
|
||||
|
||||
2009-04-10 Ben Elliston <bje@au.ibm.com>
|
||||
Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
|
|
26
gcc/testsuite/g++.dg/torture/pr39678.C
Normal file
26
gcc/testsuite/g++.dg/torture/pr39678.C
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* PR target/39678 */
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-Wno-psabi" } */
|
||||
struct Y {};
|
||||
struct X {
|
||||
struct Y y;
|
||||
__complex__ float val;
|
||||
};
|
||||
|
||||
struct X __attribute__((noinline))
|
||||
foo (float *p)
|
||||
{
|
||||
struct X x;
|
||||
__real x.val = p[0];
|
||||
__imag x.val = p[1];
|
||||
return x;
|
||||
}
|
||||
extern "C" void abort (void);
|
||||
float a[2] = { 3., -2. };
|
||||
int main()
|
||||
{
|
||||
struct X x = foo(a);
|
||||
if (__real x.val != 3. || __imag x.val != -2.)
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
/* { dg-options "-O" } */
|
||||
/* { dg-options "-O -Wno-psabi" } */
|
||||
|
||||
|
||||
#ifdef __x86_64__
|
||||
#include "struct-complex-1.h"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* { dg-options "-O" } */
|
||||
/* { dg-options "-O -Wno-psabi" } */
|
||||
|
||||
#ifdef __x86_64__
|
||||
#include <stdlib.h>
|
||||
|
|
15
gcc/testsuite/gcc.dg/compat/struct-complex-2.h
Normal file
15
gcc/testsuite/gcc.dg/compat/struct-complex-2.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#include <complex.h>
|
||||
|
||||
struct st
|
||||
{
|
||||
int s1;
|
||||
float complex x;
|
||||
};
|
||||
|
||||
typedef struct { float r, i; } _complex;
|
||||
|
||||
struct stc
|
||||
{
|
||||
int s1;
|
||||
_complex x;
|
||||
};
|
21
gcc/testsuite/gcc.dg/compat/struct-complex-2_main.c
Normal file
21
gcc/testsuite/gcc.dg/compat/struct-complex-2_main.c
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* { dg-options "-O" } */
|
||||
|
||||
#ifdef __x86_64__
|
||||
/* Test function argument passing. PR target/39678. */
|
||||
|
||||
extern void struct_complex_2_x (void);
|
||||
extern void exit (int);
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
struct_complex_2_x ();
|
||||
exit (0);
|
||||
}
|
||||
#else
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
30
gcc/testsuite/gcc.dg/compat/struct-complex-2_x.c
Normal file
30
gcc/testsuite/gcc.dg/compat/struct-complex-2_x.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
/* { dg-options "-O -Wno-psabi" } */
|
||||
|
||||
|
||||
#ifdef __x86_64__
|
||||
#include "struct-complex-2.h"
|
||||
|
||||
struct st st1;
|
||||
struct stc st2;
|
||||
|
||||
extern void foo ();
|
||||
extern void bar ();
|
||||
|
||||
int
|
||||
struct_complex_2_x ()
|
||||
{
|
||||
st1.s1 = 1;
|
||||
__real__ st1.x = 2;
|
||||
__imag__ st1.x = 4;
|
||||
st2.s1 = 1;
|
||||
st2.x.r = 2;
|
||||
st2.x.i = 4;
|
||||
foo (st1);
|
||||
foo (st2);
|
||||
bar (st1);
|
||||
bar (st2);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int dummy_x;
|
||||
#endif
|
23
gcc/testsuite/gcc.dg/compat/struct-complex-2_y.c
Normal file
23
gcc/testsuite/gcc.dg/compat/struct-complex-2_y.c
Normal file
|
@ -0,0 +1,23 @@
|
|||
/* { dg-options "-O -Wno-psabi" } */
|
||||
|
||||
#ifdef __x86_64__
|
||||
#include <stdlib.h>
|
||||
#include "struct-complex-2.h"
|
||||
|
||||
void
|
||||
bar(struct st x)
|
||||
{
|
||||
if (x.s1 != 1
|
||||
|| __real__ x.x != 2 || __imag__ x.x != 4)
|
||||
abort ();
|
||||
}
|
||||
|
||||
void
|
||||
foo(struct stc x)
|
||||
{
|
||||
if (x.s1 != 1 || x.x.r != 2 || x.x.i != 4)
|
||||
abort ();
|
||||
}
|
||||
#else
|
||||
int dummy_y;
|
||||
#endif
|
27
gcc/testsuite/gcc.dg/torture/pr39678.c
Normal file
27
gcc/testsuite/gcc.dg/torture/pr39678.c
Normal file
|
@ -0,0 +1,27 @@
|
|||
/* PR target/39678 */
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-Wno-psabi" } */
|
||||
|
||||
struct X {
|
||||
char c;
|
||||
__complex__ float val;
|
||||
};
|
||||
|
||||
struct X __attribute__((noinline))
|
||||
foo (float *p)
|
||||
{
|
||||
struct X x;
|
||||
x.c = -3;
|
||||
__real x.val = p[0];
|
||||
__imag x.val = p[1];
|
||||
return x;
|
||||
}
|
||||
extern void abort (void);
|
||||
float a[2] = { 3., -2. };
|
||||
int main()
|
||||
{
|
||||
struct X x = foo(a);
|
||||
if (x.c != -3 || __real x.val != a[0] || __imag x.val != a[1])
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
19
gcc/testsuite/gcc.target/i386/pr39678.c
Normal file
19
gcc/testsuite/gcc.target/i386/pr39678.c
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* PR target/39678 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-require-effective-target lp64 } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
struct X {
|
||||
char c;
|
||||
__complex__ float val;
|
||||
};
|
||||
|
||||
struct X
|
||||
foo (float *p)
|
||||
{ /* { dg-message "note: The ABI of passing structure with complex float member has changed in GCC 4.4" } */
|
||||
struct X x;
|
||||
x.c = -3;
|
||||
__real x.val = p[0];
|
||||
__imag x.val = p[1];
|
||||
return x;
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "defines.h"
|
||||
#include "args.h"
|
||||
#include <complex.h>
|
||||
|
||||
struct IntegerRegisters iregs;
|
||||
struct FloatRegisters fregs;
|
||||
|
@ -116,6 +117,45 @@ check_struct_passing8 (struct flex2_struct is ATTRIBUTE_UNUSED)
|
|||
check_int_arguments;
|
||||
}
|
||||
|
||||
struct complex1_struct
|
||||
{
|
||||
int c;
|
||||
__complex__ float x;
|
||||
};
|
||||
|
||||
struct complex1a_struct
|
||||
{
|
||||
long l;
|
||||
float f;
|
||||
};
|
||||
|
||||
struct complex2_struct
|
||||
{
|
||||
int c;
|
||||
__complex__ float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
struct complex2a_struct
|
||||
{
|
||||
long l;
|
||||
double d;
|
||||
};
|
||||
|
||||
void
|
||||
check_struct_passing9 (struct complex1_struct is ATTRIBUTE_UNUSED)
|
||||
{
|
||||
check_int_arguments;
|
||||
check_float_arguments;
|
||||
}
|
||||
|
||||
void
|
||||
check_struct_passing10 (struct complex2_struct is ATTRIBUTE_UNUSED)
|
||||
{
|
||||
check_int_arguments;
|
||||
check_double_arguments;
|
||||
}
|
||||
|
||||
static struct flex1_struct f1s = { 60, { } };
|
||||
static struct flex2_struct f2s = { 61, { } };
|
||||
|
||||
|
@ -136,6 +176,18 @@ main (void)
|
|||
};
|
||||
int i;
|
||||
#endif
|
||||
struct complex1_struct c1s = { 4, ( -13.4 + 3.5*I ) };
|
||||
union
|
||||
{
|
||||
struct complex1_struct c;
|
||||
struct complex1a_struct u;
|
||||
} c1u;
|
||||
struct complex2_struct c2s = { 4, ( -13.4 + 3.5*I ), -34.5 };
|
||||
union
|
||||
{
|
||||
struct complex2_struct c;
|
||||
struct complex2a_struct u;
|
||||
} c2u;
|
||||
|
||||
clear_struct_registers;
|
||||
iregs.I0 = is.i;
|
||||
|
@ -185,5 +237,25 @@ main (void)
|
|||
clear_int_hardware_registers;
|
||||
WRAP_CALL (check_struct_passing8)(f2s);
|
||||
|
||||
clear_struct_registers;
|
||||
c1u.c = c1s;
|
||||
iregs.I0 = c1u.u.l;
|
||||
num_iregs = 1;
|
||||
fregs.xmm0._float [0] = c1u.u.f;
|
||||
num_fregs = 1;
|
||||
clear_int_hardware_registers;
|
||||
clear_float_hardware_registers;
|
||||
WRAP_CALL (check_struct_passing9)(c1s);
|
||||
|
||||
clear_struct_registers;
|
||||
c2u.c = c2s;
|
||||
iregs.I0 = c2u.u.l;
|
||||
num_iregs = 1;
|
||||
fregs.xmm0._double[0] = c2u.u.d;
|
||||
num_fregs = 1;
|
||||
clear_int_hardware_registers;
|
||||
clear_float_hardware_registers;
|
||||
WRAP_CALL (check_struct_passing10)(c2s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue