aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2017-11-23 12:26:32 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2017-11-23 12:26:32 +0100
commit2145b601d083b313197c0ef3bfbef1df8aa26479 (patch)
tree3dd6d215d0749639bcd61bbd8c74072b2c907f19 /gcc/expr.c
parentf36a7f04f65f3e11e2c656e4171657acf59f3655 (diff)
downloadgcc-2145b601d083b313197c0ef3bfbef1df8aa26479.zip
gcc-2145b601d083b313197c0ef3bfbef1df8aa26479.tar.gz
gcc-2145b601d083b313197c0ef3bfbef1df8aa26479.tar.bz2
re PR middle-end/82253 (ICE in convert_move, at expr.c:604)
PR middle-end/82253 * expr.c (expand_assignment): For CONCAT to_rtx, complex type from and bitpos/bitsize covering the whole destination, use store_expr only if the complex mode is the same. Otherwise, use expand_normal and if it returns CONCAT, subreg each part separately instead of trying to subreg the whole result. * gfortran.dg/pr82253.f90: New test. From-SVN: r255095
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c33
1 files changed, 25 insertions, 8 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 290f0c4..ee07de5 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -5107,7 +5107,8 @@ expand_assignment (tree to, tree from, bool nontemporal)
else if (GET_CODE (to_rtx) == CONCAT)
{
unsigned short mode_bitsize = GET_MODE_BITSIZE (GET_MODE (to_rtx));
- if (COMPLEX_MODE_P (TYPE_MODE (TREE_TYPE (from)))
+ if (TYPE_MODE (TREE_TYPE (from)) == GET_MODE (to_rtx)
+ && COMPLEX_MODE_P (GET_MODE (to_rtx))
&& bitpos == 0
&& bitsize == mode_bitsize)
result = store_expr (from, to_rtx, false, nontemporal, reversep);
@@ -5128,14 +5129,30 @@ expand_assignment (tree to, tree from, bool nontemporal)
nontemporal, reversep);
else if (bitpos == 0 && bitsize == mode_bitsize)
{
- rtx from_rtx;
result = expand_normal (from);
- from_rtx = simplify_gen_subreg (GET_MODE (to_rtx), result,
- TYPE_MODE (TREE_TYPE (from)), 0);
- emit_move_insn (XEXP (to_rtx, 0),
- read_complex_part (from_rtx, false));
- emit_move_insn (XEXP (to_rtx, 1),
- read_complex_part (from_rtx, true));
+ if (GET_CODE (result) == CONCAT)
+ {
+ machine_mode to_mode = GET_MODE_INNER (GET_MODE (to_rtx));
+ machine_mode from_mode = GET_MODE_INNER (GET_MODE (result));
+ rtx from_real
+ = simplify_gen_subreg (to_mode, XEXP (result, 0),
+ from_mode, 0);
+ rtx from_imag
+ = simplify_gen_subreg (to_mode, XEXP (result, 1),
+ from_mode, 1);
+ emit_move_insn (XEXP (to_rtx, 0), from_real);
+ emit_move_insn (XEXP (to_rtx, 1), from_imag);
+ }
+ else
+ {
+ rtx from_rtx
+ = simplify_gen_subreg (GET_MODE (to_rtx), result,
+ TYPE_MODE (TREE_TYPE (from)), 0);
+ emit_move_insn (XEXP (to_rtx, 0),
+ read_complex_part (from_rtx, false));
+ emit_move_insn (XEXP (to_rtx, 1),
+ read_complex_part (from_rtx, true));
+ }
}
else
{