re PR middle-end/56382 (FAIL: gcc.c-torture/compile/pr55921.c (internal compiler...
authorEric Botcazou <ebotcazou@adacore.com>
Mon, 2 Sep 2013 16:19:20 +0000 (16:19 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 2 Sep 2013 16:19:20 +0000 (16:19 +0000)
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
gcc/expr.c

index 94e9992..918e667 100644 (file)
@@ -1,3 +1,9 @@
+2013-09-02  Eric Botcazou  <ebotcazou@adacore.com>
+
+       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  <rguenther@suse.de>
 
        PR middle-end/57511
index bbe0401..167d4f5 100644 (file)
@@ -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)