aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2016-10-29 22:22:36 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2016-10-29 22:22:36 +0200
commit205b9ed14e15672ea5496d48430f954d12b089a3 (patch)
treeaa26aad337f9a7f61eff3d734f7a3f9e8de39d3d /gcc/expr.c
parente421be7677f480f1ca5842c5a2a96c829fd47266 (diff)
downloadgcc-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.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 6420e27..596b1bf 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