Commit 23ac85e7 by H.J. Lu Committed by H.J. Lu

re PR target/35767 (x86 backend uses aligned load on unaligned memory)

gcc/

2008-05-27  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/35767
	PR target/35771
	* config/i386/i386.c (ix86_function_arg_boundary): Use
	alignment of canonical type.
	(ix86_expand_vector_move): Check unaligned memory access for
	all SSE modes.

gcc/testsuite/

2008-05-27  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/35767
	PR target/35771
	* gcc.target/i386/pr35767-1.c: New.
	* gcc.target/i386/pr35767-1d.c: Likewise.
	* gcc.target/i386/pr35767-1i.c: Likewise.
	* gcc.target/i386/pr35767-2.c: Likewise.
	* gcc.target/i386/pr35767-2d.c: Likewise.
	* gcc.target/i386/pr35767-2i.c: Likewise.
	* gcc.target/i386/pr35767-3.c: Likewise.
	* gcc.target/i386/pr35767-4.c: Likewise.
	* gcc.target/i386/pr35767-5.c: Likewise.

From-SVN: r136054
parent 61bed519
2008-05-27 H.J. Lu <hongjiu.lu@intel.com>
PR target/35767
PR target/35771
* config/i386/i386.c (ix86_function_arg_boundary): Use
alignment of canonical type.
(ix86_expand_vector_move): Check unaligned memory access for
all SSE modes.
2008-05-27 H.J. Lu <hongjiu.lu@intel.com>
* dwarf2out.c (current_fde): Change return type to dw_fde_ref.
Moved to the front of file.
......
......@@ -4638,7 +4638,12 @@ ix86_function_arg_boundary (enum machine_mode mode, tree type)
{
int align;
if (type)
align = TYPE_ALIGN (type);
{
if (TYPE_STRUCTURAL_EQUALITY_P (type))
align = TYPE_ALIGN (type);
else
align = TYPE_ALIGN (TYPE_CANONICAL (type));
}
else
align = GET_MODE_ALIGNMENT (mode);
if (align < PARM_BOUNDARY)
......@@ -10408,12 +10413,10 @@ ix86_expand_vector_move (enum machine_mode mode, rtx operands[])
&& standard_sse_constant_p (op1) <= 0)
op1 = validize_mem (force_const_mem (mode, op1));
/* TDmode values are passed as TImode on the stack. TImode values
are moved via xmm registers, and moving them to stack can result in
unaligned memory access. Use ix86_expand_vector_move_misalign()
if memory operand is not aligned correctly. */
/* We need to check memory alignment for SSE mode since attribute
can make operands unaligned. */
if (can_create_pseudo_p ()
&& (mode == TImode) && !TARGET_64BIT
&& SSE_REG_MODE_P (mode)
&& ((MEM_P (op0) && (MEM_ALIGN (op0) < align))
|| (MEM_P (op1) && (MEM_ALIGN (op1) < align))))
{
......
2008-05-27 H.J. Lu <hongjiu.lu@intel.com>
PR target/35767
PR target/35771
* gcc.target/i386/pr35767-1.c: New.
* gcc.target/i386/pr35767-1d.c: Likewise.
* gcc.target/i386/pr35767-1i.c: Likewise.
* gcc.target/i386/pr35767-2.c: Likewise.
* gcc.target/i386/pr35767-2d.c: Likewise.
* gcc.target/i386/pr35767-2i.c: Likewise.
* gcc.target/i386/pr35767-3.c: Likewise.
* gcc.target/i386/pr35767-4.c: Likewise.
* gcc.target/i386/pr35767-5.c: Likewise.
2008-05-27 Tobias Burnus <burnus@net-b.de>
* gfortran.dg/assignment_3.f90: Add missing cleanup-modules.
......
/* { dg-do run } */
/* { dg-options "-O2 -msse2" } */
#include "sse2-check.h"
typedef struct { __m128 f __attribute__((packed)); } packed;
__m128 __attribute__((noinline))
foo (__m128 a1, __m128 a2, __m128 a3, __m128 a4,
__m128 a5, __m128 a6, __m128 a7, __m128 a8,
int b1, int b2, int b3, int b4, int b5, int b6, int b7, packed y)
{
return y.f;
}
void
sse2_test (void)
{
packed x;
__m128 y = { 0 };
x.f = y;
y = foo (y, y, y, y, y, y, y, y, 1, 2, 3, 4, 5, 6, -1, x);
if (__builtin_memcmp (&y, &x.f, sizeof (y)) != 0)
abort ();
}
/* { dg-do run } */
/* { dg-options "-O2 -msse2" } */
#include "sse2-check.h"
typedef struct { __m128d f __attribute__((packed)); } packed;
__m128d __attribute__((noinline))
foo (__m128d a1, __m128d a2, __m128d a3, __m128d a4,
__m128d a5, __m128d a6, __m128d a7, __m128d a8,
int b1, int b2, int b3, int b4, int b5, int b6, int b7, packed y)
{
return y.f;
}
void
sse2_test (void)
{
packed x;
__m128d y = { 0 };
x.f = y;
y = foo (y, y, y, y, y, y, y, y, 1, 2, 3, 4, 5, 6, -1, x);
if (__builtin_memcmp (&y, &x.f, sizeof (y)) != 0)
abort ();
}
/* { dg-do run } */
/* { dg-options "-O2 -msse2" } */
#include "sse2-check.h"
typedef struct { __m128i f __attribute__((packed)); } packed;
__m128i __attribute__((noinline))
foo (__m128i a1, __m128i a2, __m128i a3, __m128i a4,
__m128i a5, __m128i a6, __m128i a7, __m128i a8,
int b1, int b2, int b3, int b4, int b5, int b6, int b7, packed y)
{
return y.f;
}
void
sse2_test (void)
{
packed x;
__m128i y = { 0 };
x.f = y;
y = foo (y, y, y, y, y, y, y, y, 1, 2, 3, 4, 5, 6, -1, x);
if (__builtin_memcmp (&y, &x.f, sizeof (y)) != 0)
abort ();
}
/* { dg-do run } */
/* { dg-options "-O2 -msse2" } */
#include "sse2-check.h"
typedef __m128 __attribute__((aligned(1))) unaligned;
__m128 __attribute__((noinline))
foo (__m128 a1, __m128 a2, __m128 a3, __m128 a4,
__m128 a5, __m128 a6, __m128 a7, __m128 a8,
int b1, int b2, int b3, int b4, int b5, int b6, int b7, unaligned y)
{
return y;
}
void
sse2_test (void)
{
unaligned x;
__m128 y = { 0 };
x = y;
y = foo (y, y, y, y, y, y, y, y, 1, 2, 3, 4, 5, 6, -1, x);
if (__builtin_memcmp (&y, &x, sizeof (y)) != 0)
abort ();
}
/* { dg-do run } */
/* { dg-options "-O2 -msse2" } */
#include "sse2-check.h"
typedef __m128d __attribute__((aligned(1))) unaligned;
__m128d __attribute__((noinline))
foo (__m128d a1, __m128d a2, __m128d a3, __m128d a4,
__m128d a5, __m128d a6, __m128d a7, __m128d a8,
int b1, int b2, int b3, int b4, int b5, int b6, int b7, unaligned y)
{
return y;
}
void
sse2_test (void)
{
unaligned x;
__m128d y = { 0 };
x = y;
y = foo (y, y, y, y, y, y, y, y, 1, 2, 3, 4, 5, 6, -1, x);
if (__builtin_memcmp (&y, &x, sizeof (y)) != 0)
abort ();
}
/* { dg-do run } */
/* { dg-options "-O2 -msse2" } */
#include "sse2-check.h"
typedef __m128i __attribute__((aligned(1))) unaligned;
__m128i __attribute__((noinline))
foo (__m128i a1, __m128i a2, __m128i a3, __m128i a4,
__m128i a5, __m128i a6, __m128i a7, __m128i a8,
int b1, int b2, int b3, int b4, int b5, int b6, int b7, unaligned y)
{
return y;
}
void
sse2_test (void)
{
unaligned x;
__m128i y = { 0 };
x = y;
y = foo (y, y, y, y, y, y, y, y, 1, 2, 3, 4, 5, 6, -1, x);
if (__builtin_memcmp (&y, &x, sizeof (y)) != 0)
abort ();
}
/* { dg-do run } */
/* { dg-require-effective-target dfp } */
/* { dg-options "-O -msse2 -std=gnu99" } */
#include "sse2-check.h"
typedef _Decimal128 unaligned __attribute__((aligned(1)));
_Decimal128 __attribute__((noinline))
foo (_Decimal128 a1, _Decimal128 a2, _Decimal128 a3, _Decimal128 a4,
_Decimal128 a5, _Decimal128 a6, _Decimal128 a7, _Decimal128 a8,
int b1, int b2, int b3, int b4, int b5, int b6, int b7, unaligned y)
{
return y;
}
void
sse2_test (void)
{
unaligned x;
_Decimal128 y = -1;
x = y;
y = foo (0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, -1, x);
if (__builtin_memcmp (&y, &x, sizeof (y)))
abort ();
}
/* Test that we generate aligned load when memory is aligned. */
/* { dg-do compile } */
/* { dg-require-effective-target dfp } */
/* { dg-options "-O -march=x86-64 -mtune=generic -std=gnu99" } */
/* { dg-final { scan-assembler-not "movdqu" } } */
/* { dg-final { scan-assembler "movdqa" } } */
extern _Decimal128 foo (_Decimal128, _Decimal128, _Decimal128);
void
bar (void)
{
foo (0, 0, 0);
}
/* Test that we generate aligned load when memory is aligned. */
/* { dg-do compile } */
/* { dg-options "-O -msse2 -mtune=generic" } */
/* { dg-final { scan-assembler-not "movups" } } */
/* { dg-final { scan-assembler "movaps" } } */
typedef float v4sf __attribute__ ((__vector_size__ (16)));
extern void foo(v4sf, v4sf, v4sf, v4sf, v4sf, v4sf, v4sf, v4sf, v4sf);
int test(void)
{
v4sf x = { 0.0, 1.0, 2.0, 3.0 };
foo (x, x, x, x, x, x, x, x, x);
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment