diff options
author | Jakub Jelinek <jakub@redhat.com> | 2016-10-29 22:22:36 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2016-10-29 22:22:36 +0200 |
commit | 205b9ed14e15672ea5496d48430f954d12b089a3 (patch) | |
tree | aa26aad337f9a7f61eff3d734f7a3f9e8de39d3d /gcc | |
parent | e421be7677f480f1ca5842c5a2a96c829fd47266 (diff) | |
download | gcc-205b9ed14e15672ea5496d48430f954d12b089a3.zip gcc-205b9ed14e15672ea5496d48430f954d12b089a3.tar.gz gcc-205b9ed14e15672ea5496d48430f954d12b089a3.tar.bz2 |
re PR rtl-optimization/77919 (ICE converting DC to V2DF mode)
PR rtl-optimization/77919
* expr.c (expand_expr_real_1) <normal_inner_ref>: Only avoid forcing
into memory if both modes are complex and their inner modes have the
same precision. If the two modes are different complex modes, convert
each part separately and generate a new CONCAT.
* g++.dg/torture/pr77919-2.C: New test.
From-SVN: r241681
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/expr.c | 27 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr77919-2.C | 10 |
4 files changed, 47 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7d153d2..e0d1c48 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2016-10-29 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/77919 + * expr.c (expand_expr_real_1) <normal_inner_ref>: Only avoid forcing + into memory if both modes are complex and their inner modes have the + same precision. If the two modes are different complex modes, convert + each part separately and generate a new CONCAT. + 2016-10-29 John David Anglin <danglin@gcc.gnu.org> * config/pa/pa64-hpux.h (FINI_SECTION_ASM_OP): Define to null string. @@ -10422,10 +10422,35 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, { if (bitpos == 0 && bitsize == GET_MODE_BITSIZE (GET_MODE (op0)) - && COMPLEX_MODE_P (mode1)) + && COMPLEX_MODE_P (mode1) + && COMPLEX_MODE_P (GET_MODE (op0)) + && (GET_MODE_PRECISION (GET_MODE_INNER (mode1)) + == GET_MODE_PRECISION (GET_MODE_INNER (GET_MODE (op0))))) { if (reversep) op0 = flip_storage_order (GET_MODE (op0), op0); + if (mode1 != GET_MODE (op0)) + { + rtx parts[2]; + for (int i = 0; i < 2; i++) + { + rtx op = read_complex_part (op0, i != 0); + if (GET_CODE (op) == SUBREG) + op = force_reg (GET_MODE (op), op); + rtx temp = gen_lowpart_common (GET_MODE_INNER (mode1), + op); + if (temp) + op = temp; + else + { + if (!REG_P (op) && !MEM_P (op)) + op = force_reg (GET_MODE (op), op); + op = gen_lowpart (GET_MODE_INNER (mode1), op); + } + parts[i] = op; + } + op0 = gen_rtx_CONCAT (mode1, parts[0], parts[1]); + } return op0; } if (bitpos == 0 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d23181c..7ebc616 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2016-10-29 Jakub Jelinek <jakub@redhat.com> + PR rtl-optimization/77919 + * g++.dg/torture/pr77919-2.C: New test. + PR target/78148 * gcc.dg/pr78148.c: New test. diff --git a/gcc/testsuite/g++.dg/torture/pr77919-2.C b/gcc/testsuite/g++.dg/torture/pr77919-2.C new file mode 100644 index 0000000..d61e704 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr77919-2.C @@ -0,0 +1,10 @@ +// PR rtl-optimization/77919 +// { dg-do compile } + +typedef _Complex long long B; +struct A { A (double) {} _Complex double i; }; +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); |