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/expr.c | |
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/expr.c')
-rw-r--r-- | gcc/expr.c | 27 |
1 files changed, 26 insertions, 1 deletions
@@ -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 |