diff options
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/expr.c | 3 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/other/pr40446.C | 46 |
4 files changed, 59 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 524f71e8fca..bbf4e60feb8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2009-06-16 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/40446 + * expr.c (expand_expr_real_1) <case VIEW_CONVERT_EXPR>: Don't + use gen_lowpart if op0 has complex mode. + 2009-06-16 Richard Guenther <rguenther@suse.de> * tree-ssa-structalias.c (do_ds_constraint): Stores in global diff --git a/gcc/expr.c b/gcc/expr.c index ec1800e63a2..34137c0cd07 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -8321,7 +8321,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, /* If neither mode is BLKmode, and both modes are the same size then we can use gen_lowpart. */ else if (mode != BLKmode && GET_MODE (op0) != BLKmode - && GET_MODE_SIZE (mode) == GET_MODE_SIZE (GET_MODE (op0))) + && GET_MODE_SIZE (mode) == GET_MODE_SIZE (GET_MODE (op0)) + && !COMPLEX_MODE_P (GET_MODE (op0))) { if (GET_CODE (op0) == SUBREG) op0 = force_reg (GET_MODE (op0), op0); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fd2ca7357dc..689597830a7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-06-16 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/40446 + * g++.dg/other/pr40446.C: New test. + 2009-06-16 Richard Guenther <rguenther@suse.de> * gcc.dg/tree-ssa/pta-escape-1.c: New testcase. diff --git a/gcc/testsuite/g++.dg/other/pr40446.C b/gcc/testsuite/g++.dg/other/pr40446.C new file mode 100644 index 00000000000..33dbcec7159 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/pr40446.C @@ -0,0 +1,46 @@ +// PR middle-end/40446 +// { dg-do run { target i?86-*-* x86_64-*-* } } +// { dg-options "-O1 -msse2" } + +#include <emmintrin.h> +#include "cpuid.h" + +extern "C" void abort (); + +struct S +{ + S (double r, double i) { __real__ s = r; __imag__ s = i; } + __complex__ double s; +}; + +__m128d +foo () +{ + S c (0, 1); + return _mm_load_pd ((double *) &c); +} + +static void +__attribute__((noinline)) +sse2_test () +{ + union { __m128d vec; double val[2]; } u; + u.vec = foo (); + if (u.val[0] != 0 || u.val[1] != 1) + abort (); +} + +int +main () +{ + unsigned int eax, ebx, ecx, edx; + + if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) + return 0; + + /* Run SSE2 test only if host has SSE2 support. */ + if (edx & bit_SSE2) + sse2_test (); + + return 0; +} |