diff options
author | H.J. Lu <hongjiu.lu@intel.com> | 2008-05-27 20:18:33 +0000 |
---|---|---|
committer | H.J. Lu <hjl@gcc.gnu.org> | 2008-05-27 13:18:33 -0700 |
commit | 23ac85e7a888409d32e951245d50bcd5795eb66b (patch) | |
tree | 1e3cfa64b5f12ecca612662ef5b96bb2ba0ff018 | |
parent | 61bed51903da5de082dd2272d9aa99d83b1b4c56 (diff) | |
download | gcc-23ac85e7a888409d32e951245d50bcd5795eb66b.zip gcc-23ac85e7a888409d32e951245d50bcd5795eb66b.tar.gz gcc-23ac85e7a888409d32e951245d50bcd5795eb66b.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr35767-1.c | 25 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr35767-1d.c | 25 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr35767-1i.c | 25 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr35767-2.c | 25 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr35767-2d.c | 25 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr35767-2i.c | 25 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr35767-3.c | 26 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr35767-4.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr35767-5.c | 17 |
12 files changed, 239 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 92c82d0..c25c438 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,14 @@ 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. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 6cac18a..cbb122a 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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)))) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4983df2..59bf3a9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,17 @@ +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. diff --git a/gcc/testsuite/gcc.target/i386/pr35767-1.c b/gcc/testsuite/gcc.target/i386/pr35767-1.c new file mode 100644 index 0000000..5ed5b85 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr35767-1.c @@ -0,0 +1,25 @@ +/* { 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 (); +} diff --git a/gcc/testsuite/gcc.target/i386/pr35767-1d.c b/gcc/testsuite/gcc.target/i386/pr35767-1d.c new file mode 100644 index 0000000..cdf17fa --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr35767-1d.c @@ -0,0 +1,25 @@ +/* { 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 (); +} diff --git a/gcc/testsuite/gcc.target/i386/pr35767-1i.c b/gcc/testsuite/gcc.target/i386/pr35767-1i.c new file mode 100644 index 0000000..188e8e7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr35767-1i.c @@ -0,0 +1,25 @@ +/* { 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 (); +} diff --git a/gcc/testsuite/gcc.target/i386/pr35767-2.c b/gcc/testsuite/gcc.target/i386/pr35767-2.c new file mode 100644 index 0000000..82062ff --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr35767-2.c @@ -0,0 +1,25 @@ +/* { 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 (); +} diff --git a/gcc/testsuite/gcc.target/i386/pr35767-2d.c b/gcc/testsuite/gcc.target/i386/pr35767-2d.c new file mode 100644 index 0000000..ae96cd8 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr35767-2d.c @@ -0,0 +1,25 @@ +/* { 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 (); +} diff --git a/gcc/testsuite/gcc.target/i386/pr35767-2i.c b/gcc/testsuite/gcc.target/i386/pr35767-2i.c new file mode 100644 index 0000000..d241644 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr35767-2i.c @@ -0,0 +1,25 @@ +/* { 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 (); +} diff --git a/gcc/testsuite/gcc.target/i386/pr35767-3.c b/gcc/testsuite/gcc.target/i386/pr35767-3.c new file mode 100644 index 0000000..e7592ff --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr35767-3.c @@ -0,0 +1,26 @@ +/* { 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 (); +} diff --git a/gcc/testsuite/gcc.target/i386/pr35767-4.c b/gcc/testsuite/gcc.target/i386/pr35767-4.c new file mode 100644 index 0000000..e12f64f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr35767-4.c @@ -0,0 +1,14 @@ +/* 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); +} diff --git a/gcc/testsuite/gcc.target/i386/pr35767-5.c b/gcc/testsuite/gcc.target/i386/pr35767-5.c new file mode 100644 index 0000000..4372d2e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr35767-5.c @@ -0,0 +1,17 @@ +/* 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; +} |