Message ID | 52712245.1090509@redhat.com |
---|---|
State | New |
Headers | show |
On 30 Oct 2013, at 08:16, "Vladimir Makarov" <vmakarov@redhat.com> wrote: > The following patch fixes: > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58785 > > LRA chooses constraint 'm' for const_int operand. It means that the > const_int should be placed in memory but it does not happen as preferred > reload class hook returns LO_REGS for class NO_REGS which is result of > LRA choosing 'm'. I don't know why reload pass needs such value but it > should be return NO_REGS IMHO as it results in much less reload insns. > > Is this patch ok to commit to the trunk? > > 2013-10-30 Vladimir Makarov <vmakarov@redhat.com> > > PR target/58785 > * config/arm/arm.c (arm_preferred_reload_class): Don't return > LO_REGS for NO_REGS for LRA. > > 2013-10-30 Vladimir Makarov <vmakarov@redhat.com> > > PR target/58785 > * gcc.target/arm/pr58785.c: New. > > <pr58785.patch> We've been suspicious of this hunk of code for a while now. One reading of the manual suggests that p_r_c can only return a subset of rclass, not a different class. On that basis, lo_regs as a result should only be returned when rclass is general_regs, even for traditional reload. R.
Index: config/arm/arm.c =================================================================== --- config/arm/arm.c (revision 204213) +++ config/arm/arm.c (working copy) @@ -6884,7 +6884,7 @@ arm_preferred_reload_class (rtx x ATTRIB { if (rclass == GENERAL_REGS || rclass == HI_REGS - || rclass == NO_REGS + || (! lra_in_progress && rclass == NO_REGS) || rclass == STACK_REG) return LO_REGS; else Index: testsuite/gcc.target/arm/pr58785.c =================================================================== --- testsuite/gcc.target/arm/pr58785.c (revision 0) +++ testsuite/gcc.target/arm/pr58785.c (working copy) @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mthumb" } */ + +typedef _Fract HQtype __attribute__ ((mode (HQ))); +extern void *memcpy (void *,const void *,int); + +HQtype f() +{ + HQtype c; + int z = 0xfada; + memcpy (&c, &z, 2); + return c; +}