aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2013-09-02 16:19:20 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2013-09-02 16:19:20 +0000
commitd617d2d806dd4a1cb6c25f06de191593831bcd40 (patch)
treee039d2e13dc40305ec9caffe6a31b046d9e7c791 /gcc/expr.c
parent49322b127ddcce7bfc01751a88b2bc83a1540367 (diff)
downloadgcc-d617d2d806dd4a1cb6c25f06de191593831bcd40.zip
gcc-d617d2d806dd4a1cb6c25f06de191593831bcd40.tar.gz
gcc-d617d2d806dd4a1cb6c25f06de191593831bcd40.tar.bz2
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
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index bbe0401..167d4f5 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)