From 92a2114171f4ab907f94f3629f1412579a8d8584 Mon Sep 17 00:00:00 2001 From: Brad Kaiser Date: Wed, 21 Nov 2001 00:04:47 +0000 Subject: [PATCH] reload1.c (elimination_effects): Use function_invariant_p instead of CONSTANT_P when... * reload1.c (elimination_effects): Use function_invariant_p instead of CONSTANT_P when considering register equivalences. From-SVN: r47226 --- gcc/ChangeLog | 5 ++ gcc/reload1.c | 2 +- gcc/testsuite/gcc.dg/20011119-1.c | 80 +++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/20011119-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2744c43620b..a4eea6c6cda 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2001-11-20 Brad Kaiser + + * reload1.c (elimination_effects): Use function_invariant_p + instead of CONSTANT_P when considering register equivalences. + 2001-11-20 David O'Brien * config.gcc: Add FreeBSD/PowerPC target. diff --git a/gcc/reload1.c b/gcc/reload1.c index c66b1a33e7d..1f20a489f62 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -2699,7 +2699,7 @@ elimination_effects (x, mem_mode) } else if (reg_renumber[regno] < 0 && reg_equiv_constant && reg_equiv_constant[regno] - && ! CONSTANT_P (reg_equiv_constant[regno])) + && ! function_invariant_p (reg_equiv_constant[regno])) elimination_effects (reg_equiv_constant[regno], mem_mode); return; diff --git a/gcc/testsuite/gcc.dg/20011119-1.c b/gcc/testsuite/gcc.dg/20011119-1.c new file mode 100644 index 00000000000..5b3c00cd36f --- /dev/null +++ b/gcc/testsuite/gcc.dg/20011119-1.c @@ -0,0 +1,80 @@ +/* Test for reload failing to eliminate from argp to sp. */ +/* { dg-do run { target i?86-*-* } } */ +/* { dg-options "-O2 -fomit-frame-pointer" } */ + +static int ustrsize (const char *s); +static int (*ucwidth) (int c); +static int (*ugetxc) (const char **s); +static int (*usetc) (char *s, int c); + +char *ustrzcat(char *dest, int size, const char *src) +{ + int pos = ustrsize(dest); + int c; + + size -= pos + ucwidth(0); + + while ((c = ugetxc(&src)) != 0) { + size -= ucwidth(c); + if (size < 0) + break; + + pos += usetc(dest+pos, c); + } + + usetc(dest+pos, 0); + + return dest; +} + +static int __attribute__((noinline)) +ustrsize (const char *s) +{ + return 0; +} + +static int +ucwidth_ (int c) +{ + return 1; +} + +static int +ugetxc_ (const char **s) +{ + return '\0'; +} + +static int +usetc_ (char *s, int c) +{ + return 1; +} + +int +main() +{ + ucwidth = ucwidth_; + ugetxc = ugetxc_; + usetc = usetc_; + + /* ??? It is impossible to explicitly modify the hard frame pointer. + This will run afoul of code in flow.c that declines to mark regs + in eliminate_regs in regs_ever_used. Apparently, we have to wait + for reload to decide that it won't need a frame pointer before a + variable can be allocated to %ebp. + + So save, restore, and clobber %ebp by hand. */ + + asm ("pushl %%ebp\n\t" + "movl $-1, %%ebp\n\t" + "pushl $0\n\t" + "pushl $0\n\t" + "pushl $0\n\t" + "call %P0\n\t" + "addl $12, %%esp\n\t" + "popl %%ebp" + : : "i"(ustrzcat)); + + return 0; +} -- 2.30.2