On 24-Aug-13, at 6:43 AM, Steven Bosscher wrote:
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.
I was trying to prevent "try_int" from being set to false in the "if"
if we
can't create a pseudo. If this is done, try_int gets set to true in
the second
"else if" in the failing testcase. As a result, we don't directly use
"emit_move_complex_parts" which currently needs a register on hppa64.
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?
I'll give your patch a try.
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;
}
Thanks,
Dave
--
John David Anglin dave.ang...@bell.net