aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/expr.c3
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/torture/pr77919.C11
4 files changed, 20 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 88805bd..95da0d1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,9 @@
2016-10-28 Jakub Jelinek <jakub@redhat.com>
+ PR rtl-optimization/77919
+ * expr.c (expand_expr_real_1) <normal_inner_ref>: Force CONCAT into
+ MEM if mode1 is not a complex mode.
+
PR rtl-optimization/78132
* ree.c (combine_reaching_defs): Give up if copy_needed and
!HARD_REGNO_MODE_OK (REGNO (src_reg), dst_mode).
diff --git a/gcc/expr.c b/gcc/expr.c
index 38ef07c..6420e27 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -10421,7 +10421,8 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
if (GET_CODE (op0) == CONCAT && !must_force_mem)
{
if (bitpos == 0
- && bitsize == GET_MODE_BITSIZE (GET_MODE (op0)))
+ && bitsize == GET_MODE_BITSIZE (GET_MODE (op0))
+ && COMPLEX_MODE_P (mode1))
{
if (reversep)
op0 = flip_storage_order (GET_MODE (op0), op0);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 08cc8bd..f13b2bd 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2016-10-28 Jakub Jelinek <jakub@redhat.com>
+ PR rtl-optimization/77919
+ * g++.dg/torture/pr77919.C: New test.
+
PR rtl-optimization/78132
* gcc.target/i386/pr78132.c: New test.
diff --git a/gcc/testsuite/g++.dg/torture/pr77919.C b/gcc/testsuite/g++.dg/torture/pr77919.C
new file mode 100644
index 0000000..cab6e90
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr77919.C
@@ -0,0 +1,11 @@
+// PR rtl-optimization/77919
+// { dg-do compile }
+// { dg-additional-options "-Wno-psabi" }
+
+struct A { A (double) {} _Complex double i; };
+typedef int __attribute__ ((vector_size (16))) B;
+typedef struct { B b; } C;
+struct D { D (const B &x) : b (x) {} B b; };
+static inline B foo (const double *x) { C *a; a = (C *) x; return a->b; }
+static inline D baz (const A &x) { return foo ((double *) &x); }
+D b = baz (0);