re PR target/60604 (GCC incorrectly compiles s_csinh function on MIPS32 (32bit fp))
gcc/ PR rtl-optimization/60604 * recog.c (general_operand): Incorporate REG_CANNOT_CHANGE_MODE_P check from register_operand. (register_operand): Redefine in terms of general_operand. (nonmemory_operand): Use register_operand for the non-constant cases. From-SVN: r208984
This commit is contained in:
parent
fb0aab2335
commit
3343cf6a6e
@ -1,3 +1,11 @@
|
||||
2014-04-01 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
PR rtl-optimization/60604
|
||||
* recog.c (general_operand): Incorporate REG_CANNOT_CHANGE_MODE_P
|
||||
check from register_operand.
|
||||
(register_operand): Redefine in terms of general_operand.
|
||||
(nonmemory_operand): Use register_operand for the non-constant cases.
|
||||
|
||||
2014-04-01 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* gimple.h (struct gimple_statement_base): Align subcode to
|
||||
|
75
gcc/recog.c
75
gcc/recog.c
@ -1023,6 +1023,19 @@ general_operand (rtx op, enum machine_mode mode)
|
||||
&& MEM_P (sub))
|
||||
return 0;
|
||||
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
if (REG_P (sub)
|
||||
&& REGNO (sub) < FIRST_PSEUDO_REGISTER
|
||||
&& REG_CANNOT_CHANGE_MODE_P (REGNO (sub), GET_MODE (sub), mode)
|
||||
&& GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_INT
|
||||
&& GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_FLOAT
|
||||
/* LRA can generate some invalid SUBREGS just for matched
|
||||
operand reload presentation. LRA needs to treat them as
|
||||
valid. */
|
||||
&& ! LRA_SUBREG_P (op))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
/* FLOAT_MODE subregs can't be paradoxical. Combine will occasionally
|
||||
create such rtl, and we must reject it. */
|
||||
if (SCALAR_FLOAT_MODE_P (GET_MODE (op))
|
||||
@ -1083,9 +1096,6 @@ address_operand (rtx op, enum machine_mode mode)
|
||||
int
|
||||
register_operand (rtx op, enum machine_mode mode)
|
||||
{
|
||||
if (GET_MODE (op) != mode && mode != VOIDmode)
|
||||
return 0;
|
||||
|
||||
if (GET_CODE (op) == SUBREG)
|
||||
{
|
||||
rtx sub = SUBREG_REG (op);
|
||||
@ -1096,41 +1106,12 @@ register_operand (rtx op, enum machine_mode mode)
|
||||
(Ideally, (SUBREG (MEM)...) should not exist after reload,
|
||||
but currently it does result from (SUBREG (REG)...) where the
|
||||
reg went on the stack.) */
|
||||
if (! reload_completed && MEM_P (sub))
|
||||
return general_operand (op, mode);
|
||||
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
if (REG_P (sub)
|
||||
&& REGNO (sub) < FIRST_PSEUDO_REGISTER
|
||||
&& REG_CANNOT_CHANGE_MODE_P (REGNO (sub), GET_MODE (sub), mode)
|
||||
&& GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_INT
|
||||
&& GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_FLOAT
|
||||
/* LRA can generate some invalid SUBREGS just for matched
|
||||
operand reload presentation. LRA needs to treat them as
|
||||
valid. */
|
||||
&& ! LRA_SUBREG_P (op))
|
||||
if (!REG_P (sub) && (reload_completed || !MEM_P (sub)))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
/* FLOAT_MODE subregs can't be paradoxical. Combine will occasionally
|
||||
create such rtl, and we must reject it. */
|
||||
if (SCALAR_FLOAT_MODE_P (GET_MODE (op))
|
||||
/* LRA can use subreg to store a floating point value in an
|
||||
integer mode. Although the floating point and the
|
||||
integer modes need the same number of hard registers, the
|
||||
size of floating point mode can be less than the integer
|
||||
mode. */
|
||||
&& ! lra_in_progress
|
||||
&& GET_MODE_SIZE (GET_MODE (op)) > GET_MODE_SIZE (GET_MODE (sub)))
|
||||
return 0;
|
||||
|
||||
op = sub;
|
||||
}
|
||||
|
||||
return (REG_P (op)
|
||||
&& (REGNO (op) >= FIRST_PSEUDO_REGISTER
|
||||
|| in_hard_reg_set_p (operand_reg_set,
|
||||
GET_MODE (op), REGNO (op))));
|
||||
else if (!REG_P (op))
|
||||
return 0;
|
||||
return general_operand (op, mode);
|
||||
}
|
||||
|
||||
/* Return 1 for a register in Pmode; ignore the tested mode. */
|
||||
@ -1232,27 +1213,7 @@ nonmemory_operand (rtx op, enum machine_mode mode)
|
||||
{
|
||||
if (CONSTANT_P (op))
|
||||
return immediate_operand (op, mode);
|
||||
|
||||
if (GET_MODE (op) != mode && mode != VOIDmode)
|
||||
return 0;
|
||||
|
||||
if (GET_CODE (op) == SUBREG)
|
||||
{
|
||||
/* Before reload, we can allow (SUBREG (MEM...)) as a register operand
|
||||
because it is guaranteed to be reloaded into one.
|
||||
Just make sure the MEM is valid in itself.
|
||||
(Ideally, (SUBREG (MEM)...) should not exist after reload,
|
||||
but currently it does result from (SUBREG (REG)...) where the
|
||||
reg went on the stack.) */
|
||||
if (! reload_completed && MEM_P (SUBREG_REG (op)))
|
||||
return general_operand (op, mode);
|
||||
op = SUBREG_REG (op);
|
||||
}
|
||||
|
||||
return (REG_P (op)
|
||||
&& (REGNO (op) >= FIRST_PSEUDO_REGISTER
|
||||
|| in_hard_reg_set_p (operand_reg_set,
|
||||
GET_MODE (op), REGNO (op))));
|
||||
return register_operand (op, mode);
|
||||
}
|
||||
|
||||
/* Return 1 if OP is a valid operand that stands for pushing a
|
||||
|
Loading…
x
Reference in New Issue
Block a user