Commit 4d41c2d1 by Richard Sandiford

re PR rtl-optimization/48830 (unrecognized insn: storing invalid upper FP reg in SImode)

gcc/
	PR rtl-optimization/48830
	PR rtl-optimization/48808
	PR rtl-optimization/48792
	* reload.c (push_reload): Check contains_reg_of_mode.
	* reload1.c (strip_paradoxical_subreg): New function.
	(gen_reload_chain_without_interm_reg_p): Use it to handle
	paradoxical subregs.
	(emit_output_reload_insns, gen_reload): Likewise.

gcc/testsuite/
2011-06-01  Eric Botcazou  <ebotcazou@adacore.com>
	    Hans-Peter Nilsson  <hp@axis.com>

	PR rtl-optimization/48830
	* gcc.target/sparc/ultrasp12.c: New test.

From-SVN: r174540
parent 7448d2e7
2011-06-01 Richard Sandiford <rdsandiford@googlemail.com>
PR rtl-optimization/48830
PR rtl-optimization/48808
PR rtl-optimization/48792
* reload.c (push_reload): Check contains_reg_of_mode.
* reload1.c (strip_paradoxical_subreg): New function.
(gen_reload_chain_without_interm_reg_p): Use it to handle
paradoxical subregs.
(emit_output_reload_insns, gen_reload): Likewise.
2011-06-01 David Li <davidxl@google.com>
* predict.c : Change pass name
......
......@@ -1019,6 +1019,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
#ifdef CANNOT_CHANGE_MODE_CLASS
&& !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (in)), inmode, rclass)
#endif
&& contains_reg_of_mode[(int) rclass][(int) GET_MODE (SUBREG_REG (in))]
&& (CONSTANT_P (SUBREG_REG (in))
|| GET_CODE (SUBREG_REG (in)) == PLUS
|| strict_low
......@@ -1125,6 +1126,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
#ifdef CANNOT_CHANGE_MODE_CLASS
&& !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (out)), outmode, rclass)
#endif
&& contains_reg_of_mode[(int) rclass][(int) GET_MODE (SUBREG_REG (out))]
&& (CONSTANT_P (SUBREG_REG (out))
|| strict_low
|| (((REG_P (SUBREG_REG (out))
......
......@@ -4471,6 +4471,43 @@ scan_paradoxical_subregs (rtx x)
}
}
}
/* *OP_PTR and *OTHER_PTR are two operands to a conceptual reload.
If *OP_PTR is a paradoxical subreg, try to remove that subreg
and apply the corresponding narrowing subreg to *OTHER_PTR.
Return true if the operands were changed, false otherwise. */
static bool
strip_paradoxical_subreg (rtx *op_ptr, rtx *other_ptr)
{
rtx op, inner, other, tem;
op = *op_ptr;
if (GET_CODE (op) != SUBREG)
return false;
inner = SUBREG_REG (op);
if (GET_MODE_SIZE (GET_MODE (op)) <= GET_MODE_SIZE (GET_MODE (inner)))
return false;
other = *other_ptr;
tem = gen_lowpart_common (GET_MODE (inner), other);
if (!tem)
return false;
/* If the lowpart operation turned a hard register into a subreg,
rather than simplifying it to another hard register, then the
mode change cannot be properly represented. For example, OTHER
might be valid in its current mode, but not in the new one. */
if (GET_CODE (tem) == SUBREG
&& REG_P (other)
&& HARD_REGISTER_P (other))
return false;
*op_ptr = inner;
*other_ptr = tem;
return true;
}
/* A subroutine of reload_as_needed. If INSN has a REG_EH_REGION note,
examine all of the reload insns between PREV and NEXT exclusive, and
......@@ -5538,7 +5575,7 @@ gen_reload_chain_without_interm_reg_p (int r1, int r2)
chain reloads or do need an intermediate hard registers. */
bool result = true;
int regno, n, code;
rtx out, in, tem, insn;
rtx out, in, insn;
rtx last = get_last_insn ();
/* Make r2 a component of r1. */
......@@ -5557,11 +5594,7 @@ gen_reload_chain_without_interm_reg_p (int r1, int r2)
/* If IN is a paradoxical SUBREG, remove it and try to put the
opposite SUBREG on OUT. Likewise for a paradoxical SUBREG on OUT. */
if (GET_CODE (in) == SUBREG
&& (GET_MODE_SIZE (GET_MODE (in))
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
&& (tem = gen_lowpart_common (GET_MODE (SUBREG_REG (in)), out)) != 0)
in = SUBREG_REG (in), out = tem;
strip_paradoxical_subreg (&in, &out);
if (GET_CODE (in) == PLUS
&& (REG_P (XEXP (in, 0))
......@@ -7557,7 +7590,6 @@ emit_output_reload_insns (struct insn_chain *chain, struct reload *rl,
if (tertiary_icode != CODE_FOR_nothing)
{
rtx third_reloadreg = rld[tertiary_reload].reg_rtx;
rtx tem;
/* Copy primary reload reg to secondary reload reg.
(Note that these have been swapped above, then
......@@ -7566,13 +7598,7 @@ emit_output_reload_insns (struct insn_chain *chain, struct reload *rl,
/* If REAL_OLD is a paradoxical SUBREG, remove it
and try to put the opposite SUBREG on
RELOADREG. */
if (GET_CODE (real_old) == SUBREG
&& (GET_MODE_SIZE (GET_MODE (real_old))
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (real_old))))
&& 0 != (tem = gen_lowpart_common
(GET_MODE (SUBREG_REG (real_old)),
reloadreg)))
real_old = SUBREG_REG (real_old), reloadreg = tem;
strip_paradoxical_subreg (&real_old, &reloadreg);
gen_reload (reloadreg, second_reloadreg,
rl->opnum, rl->when_needed);
......@@ -8388,16 +8414,8 @@ gen_reload (rtx out, rtx in, int opnum, enum reload_type type)
/* If IN is a paradoxical SUBREG, remove it and try to put the
opposite SUBREG on OUT. Likewise for a paradoxical SUBREG on OUT. */
if (GET_CODE (in) == SUBREG
&& (GET_MODE_SIZE (GET_MODE (in))
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
&& (tem = gen_lowpart_common (GET_MODE (SUBREG_REG (in)), out)) != 0)
in = SUBREG_REG (in), out = tem;
else if (GET_CODE (out) == SUBREG
&& (GET_MODE_SIZE (GET_MODE (out))
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
&& (tem = gen_lowpart_common (GET_MODE (SUBREG_REG (out)), in)) != 0)
out = SUBREG_REG (out), in = tem;
if (!strip_paradoxical_subreg (&in, &out))
strip_paradoxical_subreg (&out, &in);
/* How to do this reload can get quite tricky. Normally, we are being
asked to reload a simple operand, such as a MEM, a constant, or a pseudo
......
2011-06-01 Eric Botcazou <ebotcazou@adacore.com>
Hans-Peter Nilsson <hp@axis.com>
PR rtl-optimization/48830
* gcc.target/sparc/ultrasp12.c: New test.
2011-06-01 David Li <davidxl@google.com>
* testsuite/gcc.dg/profile-dir-1.c: Change pass name.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment