backport: re PR target/39678 (complex type isn't passed correctly)

gcc/

2009-04-14  H.J. Lu  <hongjiu.lu@intel.com>

	Backport from mainline:
	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-14  H.J. Lu  <hongjiu.lu@intel.com>

	Backport from mainline:
	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: r146061
This commit is contained in:
H.J. Lu 2009-04-14 20:27:30 +00:00 committed by H.J. Lu
parent aa5e8d0ba3
commit c496a6845f
13 changed files with 281 additions and 3 deletions

View File

@ -1,3 +1,12 @@
2009-04-14 H.J. Lu <hongjiu.lu@intel.com>
Backport from mainline:
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-14 Uros Bizjak <ubizjak@gmail.com>
Backport from mainline:

View File

@ -5163,7 +5163,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;

View File

@ -1,3 +1,23 @@
2009-04-14 H.J. Lu <hongjiu.lu@intel.com>
Backport from mainline:
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-14 Jason Merrill <jason@redhat.com>
PR c++/39763

View 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;
}

View File

@ -1,4 +1,5 @@
/* { dg-options "-O" } */
/* { dg-options "-O -Wno-psabi" } */
#ifdef __x86_64__
#include "struct-complex-1.h"

View File

@ -1,4 +1,4 @@
/* { dg-options "-O" } */
/* { dg-options "-O -Wno-psabi" } */
#ifdef __x86_64__
#include <stdlib.h>

View 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;
};

View 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

View 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

View 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

View 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;
}

View 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;
}

View File

@ -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;
}