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; }