re PR target/28181 (ICE in reload_cse_simplify_operands, at postreload.c:393 on m68k)

gcc/
	PR target/28181
	* config/m68k/m68k-protos.h (m68k_secondary_reload_class): Declare.
	(m68k_preferred_reload_class): Likewise.
	* config/m68k/m68k.h (HARD_REGNO_MODE_OK): Remove duplicated comment.
	(SECONDARY_RELOAD_CLASS): Define.
	(PREFERRED_RELOAD_CLASS): Use m68k_preferred_reload_class.
	(LIMIT_RELOAD_CLASS): Delete.
	* config/m68k/m68k.c (m68k_regno_mode_ok): Don't prevent address
	registers from storing bytes.
	(m68k_secondary_reload_class): New function.
	(m68k_preferred_reload_class): Likewise.

gcc/testsuite/
	* gcc.c-torture/compile/m68k-byte-addr.c: New test.

From-SVN: r122609
This commit is contained in:
Richard Sandiford 2007-03-06 09:01:07 +00:00 committed by Richard Sandiford
parent 4f44ecc07f
commit ffa2596e3a
6 changed files with 110 additions and 39 deletions

View File

@ -1,3 +1,17 @@
2007-03-06 Richard Sandiford <richard@codesourcery.com>
PR target/28181
* config/m68k/m68k-protos.h (m68k_secondary_reload_class): Declare.
(m68k_preferred_reload_class): Likewise.
* config/m68k/m68k.h (HARD_REGNO_MODE_OK): Remove duplicated comment.
(SECONDARY_RELOAD_CLASS): Define.
(PREFERRED_RELOAD_CLASS): Use m68k_preferred_reload_class.
(LIMIT_RELOAD_CLASS): Delete.
* config/m68k/m68k.c (m68k_regno_mode_ok): Don't prevent address
registers from storing bytes.
(m68k_secondary_reload_class): New function.
(m68k_preferred_reload_class): Likewise.
2007-03-06 Richard Sandiford <richard@codesourcery.com>
* config/m68k/m68k.c (m68k_save_reg): Remove special case for

View File

@ -69,6 +69,9 @@ extern const char *m68k_output_movem (rtx *, rtx, HOST_WIDE_INT, bool);
#endif /* RTX_CODE */
extern bool m68k_regno_mode_ok (int, enum machine_mode);
extern enum reg_class m68k_secondary_reload_class (enum reg_class,
enum machine_mode, rtx);
extern enum reg_class m68k_preferred_reload_class (rtx, enum reg_class);
extern int flags_in_68881 (void);
extern void m68k_expand_prologue (void);
extern bool m68k_use_return_insn (void);

View File

@ -4153,9 +4153,10 @@ m68k_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED,
return 1;
}
/* Value is true if hard register REGNO can hold a value of machine-mode MODE.
On the 68000, the cpu registers can hold any mode except bytes in address
registers, but the 68881 registers can hold only SFmode or DFmode. */
/* Value is true if hard register REGNO can hold a value of machine-mode
MODE. On the 68000, we let the cpu registers can hold any mode, but
restrict the 68881 registers to floating-point modes. */
bool
m68k_regno_mode_ok (int regno, enum machine_mode mode)
{
@ -4167,10 +4168,6 @@ m68k_regno_mode_ok (int regno, enum machine_mode mode)
}
else if (ADDRESS_REGNO_P (regno))
{
/* Address Registers, can't hold bytes, can hold aggregate if
fits in. */
if (GET_MODE_SIZE (mode) == 1)
return false;
if (regno + GET_MODE_SIZE (mode) / 4 <= 16)
return true;
}
@ -4186,6 +4183,66 @@ m68k_regno_mode_ok (int regno, enum machine_mode mode)
return false;
}
/* Implement SECONDARY_RELOAD_CLASS. */
enum reg_class
m68k_secondary_reload_class (enum reg_class rclass,
enum machine_mode mode, rtx x)
{
int regno;
regno = true_regnum (x);
/* If one operand of a movqi is an address register, the other
operand must be a general register or constant. Other types
of operand must be reloaded through a data register. */
if (GET_MODE_SIZE (mode) == 1
&& reg_classes_intersect_p (rclass, ADDR_REGS)
&& !(INT_REGNO_P (regno) || CONSTANT_P (x)))
return DATA_REGS;
/* PC-relative addresses must be loaded into an address register first. */
if (TARGET_PCREL
&& !reg_class_subset_p (rclass, ADDR_REGS)
&& symbolic_operand (x, VOIDmode))
return ADDR_REGS;
return NO_REGS;
}
/* Implement PREFERRED_RELOAD_CLASS. */
enum reg_class
m68k_preferred_reload_class (rtx x, enum reg_class rclass)
{
enum reg_class secondary_class;
/* If RCLASS might need a secondary reload, try restricting it to
a class that doesn't. */
secondary_class = m68k_secondary_reload_class (rclass, GET_MODE (x), x);
if (secondary_class != NO_REGS
&& reg_class_subset_p (secondary_class, rclass))
return secondary_class;
/* Prefer to use moveq for in-range constants. */
if (GET_CODE (x) == CONST_INT
&& reg_class_subset_p (DATA_REGS, rclass)
&& IN_RANGE (INTVAL (x), -0x80, 0x7f))
return DATA_REGS;
/* ??? Do we really need this now? */
if (GET_CODE (x) == CONST_DOUBLE
&& GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
{
if (TARGET_HARD_FLOAT && reg_class_subset_p (FP_REGS, rclass))
return FP_REGS;
return NO_REGS;
}
return rclass;
}
/* Return floating point values in a 68881 register. This makes 68881 code
a little bit faster. It also makes -msoft-float code incompatible with
hard-float code, so people have to be careful not to mix the two.

View File

@ -401,13 +401,12 @@ Boston, MA 02110-1301, USA. */
#define HARD_REGNO_RENAME_OK(OLD_REG, NEW_REG) \
m68k_hard_regno_rename_ok (OLD_REG, NEW_REG)
/* Value is true if hard register REGNO can hold a value of machine-mode MODE.
On the 68000, the cpu registers can hold any mode except bytes in
address registers, the 68881 registers can hold only SFmode or DFmode. */
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
m68k_regno_mode_ok ((REGNO), (MODE))
#define SECONDARY_RELOAD_CLASS(CLASS, MODE, X) \
m68k_secondary_reload_class (CLASS, MODE, X)
#define MODES_TIEABLE_P(MODE1, MODE2) \
(! TARGET_HARD_FLOAT \
|| ((GET_MODE_CLASS (MODE1) == MODE_FLOAT \
@ -544,34 +543,8 @@ extern enum reg_class regno_reg_class[];
? const_call_operand (OP, VOIDmode) \
: 0)
/* On the m68k, use a data reg if possible when the
value is a constant in the range where moveq could be used
and we ensure that QImodes are reloaded into data regs. */
#define PREFERRED_RELOAD_CLASS(X,CLASS) \
((GET_CODE (X) == CONST_INT \
&& (unsigned) (INTVAL (X) + 0x80) < 0x100 \
&& (CLASS) != ADDR_REGS) \
? DATA_REGS \
: (GET_MODE (X) == QImode && (CLASS) != ADDR_REGS) \
? DATA_REGS \
: (GET_CODE (X) == CONST_DOUBLE \
&& GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \
? (TARGET_HARD_FLOAT && (CLASS == FP_REGS || CLASS == DATA_OR_FP_REGS) \
? FP_REGS : NO_REGS) \
: (TARGET_PCREL \
&& (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST \
|| GET_CODE (X) == LABEL_REF)) \
? ADDR_REGS \
: (CLASS))
/* Force QImode output reloads from subregs to be allocated to data regs,
since QImode stores from address regs are not supported. We make the
assumption that if the class is not ADDR_REGS, then it must be a superset
of DATA_REGS. */
#define LIMIT_RELOAD_CLASS(MODE, CLASS) \
(((MODE) == QImode && (CLASS) != ADDR_REGS) \
? DATA_REGS \
: (CLASS))
#define PREFERRED_RELOAD_CLASS(X,CLASS) \
m68k_preferred_reload_class (X, CLASS)
/* On the m68k, this is the size of MODE in words,
except in the FP regs, where a single reg is always enough. */

View File

@ -1,3 +1,7 @@
2007-03-06 Richard Sandiford <richard@codesourcery.com>
* gcc.c-torture/compile/m68k-byte-addr.c: New test.
2007-03-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* gcc.dg/torture/builtin-convert-4.c: New test.

View File

@ -0,0 +1,20 @@
/* This testcase triggered an attempt to reload a byte value into an
address register. */
extern volatile unsigned char x[];
#define DECLARE(I) orig##I, inc##I
#define READ(I) orig##I = x[I]
#define INC(I) inc##I = orig##I + 1
#define WRITE1(I) x[I] = orig##I
#define WRITE2(I) x[I] = inc##I
#define REPEAT(X) X(0), X(1), X(2), X(3), X(4), X(5), X(6), X(7), X(8)
void foo (void)
{
unsigned char REPEAT (DECLARE);
REPEAT (READ);
REPEAT (INC);
REPEAT (WRITE1);
REPEAT (WRITE2);
}