[PATCH]: Fix PR middle-end/56382 -- Only move MODE_COMPLEX_FLOAT by parts if we can create pseudos

Steven Bosscher stevenb.gcc@gmail.com
Sat Aug 24 12:05:00 GMT 2013


On Fri, Aug 23, 2013 at 2:47 AM, John David Anglin wrote:
> Ping.
>
>
> On 28-Jul-13, at 12:17 PM, John David Anglin wrote:
>
>> This patch fixes PR middle-end/56382 on hppa64-hp-hpux11.11.  The patch
>> prevents moving a complex float by parts if we can't
>> create pseudos.  On a big endian 64-bit target, we need a psuedo to move a
>> complex float and this fails during reload.
>>
>> OK for trunk?
>>

I'm trying to understand how the patch would help...

The code you're patching is:

  /* Move floating point as parts.  */
  if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
+    && can_create_pseudo_p ()
      && optab_handler (mov_optab, GET_MODE_INNER (mode)) != CODE_FOR_nothing)
    try_int = false;
  /* Not possible if the values are inherently not adjacent.  */
  else if (GET_CODE (x) == CONCAT || GET_CODE (y) == CONCAT)
    try_int = false;
  /* Is possible if both are registers (or subregs of registers).  */
  else if (register_operand (x, mode) && register_operand (y, mode))
    try_int = true;
  /* If one of the operands is a memory, and alignment constraints
     are friendly enough, we may be able to do combined memory operations.
     We do not attempt this if Y is a constant because that combination is
     usually better with the by-parts thing below.  */
  else if ((MEM_P (x) ? !CONSTANT_P (y) : MEM_P (y))
           && (!STRICT_ALIGNMENT
               || get_mode_alignment (mode) == BIGGEST_ALIGNMENT))
    try_int = true;
  else
    try_int = false;

With the new test for can_create_pseudo_p, you're trying to make
"try_int" be false. Apparently your failure happens if one of the
operands is a MEM? Otherwise the second "else if " test would find x
and y be registers and "try_int" still ends up being true.

It seems to me that can_create_pseudo_p is not the right test anyway.
There many be other targets that can take this path just fine without
needing new registers. In the PR audit trail you say: "The problem is
SCmode is the same size as DImode on this target, so the subreg can't
be extracted by a move." Using can_create_pseudo_p is too big a hammer
to solve this problem. The right test would be to see if you end up
needing extra registers to perform the move. But emit_move_change_mode
already handles that, AFAICT, so can you please try and test if the
following patch solves the PR for you?

Ciao!
Steven


Index: expr.c
===================================================================
--- expr.c      (revision 201887)
+++ expr.c      (working copy)
@@ -3268,7 +3268,7 @@ emit_move_complex (enum machine_mode mode, rtx x,
          return get_last_insn ();
        }

-      ret = emit_move_via_integer (mode, x, y, true);
+      ret = emit_move_via_integer (mode, x, y, can_create_pseudo_p ());
       if (ret)
        return ret;
     }



More information about the Gcc-patches mailing list