This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
c/3037: ARM port: Wrong flow info after reload
- To: gcc-gnats at gcc dot gnu dot org
- Subject: c/3037: ARM port: Wrong flow info after reload
- From: denisc at overta dot ru
- Date: Sat, 2 Jun 2001 13:16:35 +0400
- Cc: Richard Earnshaw <rearnsha at arm dot com>
- Reply-To: denisc at overta dot ru
>Number: 3037
>Category: c
>Synopsis: ARM port: Wrong flow info after reload
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: unassigned
>State: open
>Class: ice-on-legal-code
>Submitter-Id: net
>Arrival-Date: Sat Jun 02 02:26:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator: Denis
>Release: 3.0 20010525 (prerelease)
>Organization:
None
>Environment:
System: Linux localhost 2.3.2 #6 ðÔÎ ïËÔ 13 20:07:05 MSD 2000 i586 unknown
Architecture: i586
host: i586-pc-linux-gnu
build: i586-pc-linux-gnu
target: arm-elf-linux-gnu
configured with: /root/d/cvs/gcc-3.0/configure --target=arm-elf-linux --with-newlib --enable-languages=c : (reconfigured) /root/d/cvs/gcc-3.0/configure --target=arm-elf-linux --with-newlib --enable-languages=c --without-threads : (reconfigured) /root/d/cvs/gcc-3.0/configure --target=arm-elf-linux --with-newlib --enable-languages=c --disable-threads : (reconfigured) /root/d/cvs/gcc-3.0/configure --target=arm-elf-linux --with-newlib --enable-languages=c --disable-threads --disable-shared
>Description:
As I understand the ARM port have a `(define_expand "epilogue" ...)'
And this `define_expand' don't emit the moves on RTL level for restoring
a call-saved registers.
While `update_life_info' executed after reload the `mark_regs_live_at_end'
mark all registers used by the epilogue as being live at the end of
the function and don't unmark it because RTL version of epilogue
havn't a moves.
>How-To-Repeat:
typedef struct {
int e;
double d[40];
} mp_no;
typedef union { int i[2]; double d; } number;
static const number
radix = {{0x41700000, 0x00000000} },
zero = {{0x00000000, 0x00000000} },
one = {{0x3ff00000, 0x00000000} },
mone = {{0xbff00000, 0x00000000} };
void __dbl_mp(double x, mp_no *y, int p)
{
int i,n;
double u;
if (x == zero.d)
return;
else if (x > zero.d)
y->d[0] = one.d;
else
{
y->d[0] = mone.d;
x=-x;
}
for ( ; x < one.d; y->e -= one.d)
x *= radix.d;
}
>Fix:
One of:
1. emit a RTL moves in epilogue;
2. remove `(define_expand "epilogue" ...)' (Why it's needed ?)
3. Fix flow.c:mark_regs_live_at_end
Fragment from flow.c:mark_regs_live_at_end:
/* Mark all global registers, and all registers used by the epilogue
as being live at the end of the function since they may be
referenced by our caller. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (global_regs[i] || EPILOGUE_USES (i))
SET_REGNO_REG_SET (set, i);
if (HAVE_epilogue && reload_completed) /* ---- May be fixed here ? */
{
/* Mark all call-saved registers that we actually used. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (regs_ever_live[i] && ! call_used_regs[i] && ! LOCAL_REGNO (i))
SET_REGNO_REG_SET (set, i);
}
>Release-Note:
>Audit-Trail:
>Unformatted: