]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/40446 (ICE in gen_lowpart_general)
authorJakub Jelinek <jakub@redhat.com>
Tue, 16 Jun 2009 13:48:07 +0000 (15:48 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 16 Jun 2009 13:48:07 +0000 (15:48 +0200)
PR middle-end/40446
* expr.c (expand_expr_real_1) <case VIEW_CONVERT_EXPR>: Don't
use gen_lowpart if op0 has complex mode.

* g++.dg/other/pr40446.C: New test.

From-SVN: r148533

gcc/ChangeLog
gcc/expr.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/other/pr40446.C [new file with mode: 0644]

index 524f71e8fcad1dc2497fd5f255a936c7702b9f10..bbf4e60feb8dfca658edd97c9412078a127ca7a8 100644 (file)
@@ -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
index ec1800e63a20192f4521f259d4135d8910e9a68f..34137c0cd07ebac43d32a34bc4222cd4973f99d3 100644 (file)
@@ -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);
index fd2ca7357dcaa558615b14a04192487154fe53c6..689597830a7466b7ac34b56741e2ff9aa4714f8b 100644 (file)
@@ -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 (file)
index 0000000..33dbcec
--- /dev/null
@@ -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;
+}