From: Jakub Jelinek Date: Sat, 29 Oct 2016 20:22:36 +0000 (+0200) Subject: re PR rtl-optimization/77919 (ICE converting DC to V2DF mode) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=205b9ed14e15672ea5496d48430f954d12b089a3;p=gcc.git re PR rtl-optimization/77919 (ICE converting DC to V2DF mode) PR rtl-optimization/77919 * expr.c (expand_expr_real_1) : 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7d153d27f37..e0d1c4860dc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2016-10-29 Jakub Jelinek + + PR rtl-optimization/77919 + * expr.c (expand_expr_real_1) : 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 * config/pa/pa64-hpux.h (FINI_SECTION_ASM_OP): Define to null string. diff --git a/gcc/expr.c b/gcc/expr.c index 6420e278f3d..596b1bf8227 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -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 d23181c3592..7ebc61642d2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2016-10-29 Jakub Jelinek + 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 00000000000..d61e704cb44 --- /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);