From d617d2d806dd4a1cb6c25f06de191593831bcd40 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 2 Sep 2013 16:19:20 +0000 Subject: [PATCH] re PR middle-end/56382 (FAIL: gcc.c-torture/compile/pr55921.c (internal compiler error)) PR middle-end/56382 * expr.c (emit_move_complex): Do not move complex FP values as parts if the source or the destination is a single hard register. From-SVN: r202179 --- gcc/ChangeLog | 6 ++++++ gcc/expr.c | 13 +++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 94e99927253..918e667c02e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2013-09-02 Eric Botcazou + + PR middle-end/56382 + * expr.c (emit_move_complex): Do not move complex FP values as parts if + the source or the destination is a single hard register. + 2013-09-02 Richard Biener PR middle-end/57511 diff --git a/gcc/expr.c b/gcc/expr.c index bbe0401291b..167d4f5d5ce 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -3232,11 +3232,16 @@ emit_move_complex (enum machine_mode mode, rtx x, rtx y) if (push_operand (x, mode)) return emit_move_complex_push (mode, x, y); - /* See if we can coerce the target into moving both values at once. */ - - /* Move floating point as parts. */ + /* See if we can coerce the target into moving both values at once, except + for floating point where we favor moving as parts if this is easy. */ if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT - && optab_handler (mov_optab, GET_MODE_INNER (mode)) != CODE_FOR_nothing) + && optab_handler (mov_optab, GET_MODE_INNER (mode)) != CODE_FOR_nothing + && !(REG_P (x) + && HARD_REGISTER_P (x) + && hard_regno_nregs[REGNO(x)][mode] == 1) + && !(REG_P (y) + && HARD_REGISTER_P (y) + && hard_regno_nregs[REGNO(y)][mode] == 1)) try_int = false; /* Not possible if the values are inherently not adjacent. */ else if (GET_CODE (x) == CONCAT || GET_CODE (y) == CONCAT) -- 2.30.2