re PR rtl-optimization/5120 (tail recursion incorrect using -O2)
PR opt/5120 * sibcall.c (optimize_sibling_and_tail_recursive_call): Clear RTX_UNCHANGING_P for the functions arguments when a tail call is made. From-SVN: r51969
This commit is contained in:
parent
b014888471
commit
b1896e6103
@ -1,3 +1,10 @@
|
||||
2002-04-06 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR opt/5120
|
||||
* sibcall.c (optimize_sibling_and_tail_recursive_call): Clear
|
||||
RTX_UNCHANGING_P for the functions arguments when a tail call
|
||||
is made.
|
||||
|
||||
2002-04-06 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* toplev.c (flag_no_inline, flag_really_no_inline): Default to 2.
|
||||
|
@ -31,6 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#include "basic-block.h"
|
||||
#include "output.h"
|
||||
#include "except.h"
|
||||
#include "tree.h"
|
||||
|
||||
/* In case alternate_exit_block contains copy from pseudo, to return value,
|
||||
record the pseudo here. In such case the pseudo must be set to function
|
||||
@ -730,6 +731,7 @@ optimize_sibling_and_tail_recursive_calls ()
|
||||
if (successful_sibling_call)
|
||||
{
|
||||
rtx insn;
|
||||
tree arg;
|
||||
|
||||
/* A sibling call sequence invalidates any REG_EQUIV notes made for
|
||||
this function's incoming arguments.
|
||||
@ -754,6 +756,16 @@ optimize_sibling_and_tail_recursive_calls ()
|
||||
if (INSN_P (insn))
|
||||
purge_mem_unchanging_flag (PATTERN (insn));
|
||||
}
|
||||
|
||||
/* Similarly, invalidate RTX_UNCHANGING_P for any incoming
|
||||
arguments passed in registers. */
|
||||
for (arg = DECL_ARGUMENTS (current_function_decl);
|
||||
arg;
|
||||
arg = TREE_CHAIN (arg))
|
||||
{
|
||||
if (REG_P (DECL_RTL (arg)))
|
||||
RTX_UNCHANGING_P (DECL_RTL (arg)) = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* There may have been NOTE_INSN_BLOCK_{BEGIN,END} notes in the
|
||||
|
@ -1,3 +1,8 @@
|
||||
2002-04-06 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c/5120
|
||||
* gcc.dg/20020406-1.c: New test.
|
||||
|
||||
2002-04-04 David S. Miller <davem@redhat.com>
|
||||
|
||||
* gcc.c-torture/execute/20020404-1.c: New test.
|
||||
|
123
gcc/testsuite/gcc.c-torture/execute/20020406-1.c
Normal file
123
gcc/testsuite/gcc.c-torture/execute/20020406-1.c
Normal file
@ -0,0 +1,123 @@
|
||||
// Origin: abbott@dima.unige.it
|
||||
// PR c/5120
|
||||
|
||||
typedef unsigned int FFelem;
|
||||
|
||||
FFelem FFmul(const FFelem x, const FFelem y)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
struct DUPFFstruct
|
||||
{
|
||||
int maxdeg;
|
||||
int deg;
|
||||
FFelem *coeffs;
|
||||
};
|
||||
|
||||
typedef struct DUPFFstruct *DUPFF;
|
||||
|
||||
|
||||
int DUPFFdeg(const DUPFF f)
|
||||
{
|
||||
return f->deg;
|
||||
}
|
||||
|
||||
|
||||
DUPFF DUPFFnew(const int maxdeg)
|
||||
{
|
||||
DUPFF ans = (DUPFF)malloc(sizeof(struct DUPFFstruct));
|
||||
ans->coeffs = 0;
|
||||
if (maxdeg >= 0) ans->coeffs = (FFelem*)malloc((maxdeg+1)*sizeof(FFelem));
|
||||
ans->maxdeg = maxdeg;
|
||||
ans->deg = -1;
|
||||
return ans;
|
||||
}
|
||||
|
||||
void DUPFFfree(DUPFF x)
|
||||
{
|
||||
}
|
||||
|
||||
void DUPFFswap(DUPFF x, DUPFF y)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DUPFF DUPFFcopy(const DUPFF x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
void DUPFFshift_add(DUPFF f, const DUPFF g, int deg, const FFelem coeff)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DUPFF DUPFFexgcd(DUPFF *fcofac, DUPFF *gcofac, const DUPFF f, const DUPFF g)
|
||||
{
|
||||
DUPFF u, v, uf, ug, vf, vg;
|
||||
FFelem q, lcu, lcvrecip, p;
|
||||
int df, dg, du, dv;
|
||||
|
||||
printf("DUPFFexgcd called on degrees %d and %d\n", DUPFFdeg(f), DUPFFdeg(g));
|
||||
if (DUPFFdeg(f) < DUPFFdeg(g)) return DUPFFexgcd(gcofac, fcofac, g, f); /*** BUG IN THIS LINE ***/
|
||||
if (DUPFFdeg(f) != 2 || DUPFFdeg(g) != 1) abort();
|
||||
if (f->coeffs[0] == 0) return f;
|
||||
/****** NEVER REACH HERE IN THE EXAMPLE ******/
|
||||
p = 2;
|
||||
|
||||
df = DUPFFdeg(f); if (df < 0) df = 0; /* both inputs are zero */
|
||||
dg = DUPFFdeg(g); if (dg < 0) dg = 0; /* one input is zero */
|
||||
u = DUPFFcopy(f);
|
||||
v = DUPFFcopy(g);
|
||||
|
||||
uf = DUPFFnew(dg); uf->coeffs[0] = 1; uf->deg = 0;
|
||||
ug = DUPFFnew(df);
|
||||
vf = DUPFFnew(dg);
|
||||
vg = DUPFFnew(df); vg->coeffs[0] = 1; vg->deg = 0;
|
||||
|
||||
while (DUPFFdeg(v) > 0)
|
||||
{
|
||||
dv = DUPFFdeg(v);
|
||||
lcvrecip = FFmul(1, v->coeffs[dv]);
|
||||
while (DUPFFdeg(u) >= dv)
|
||||
{
|
||||
du = DUPFFdeg(u);
|
||||
lcu = u->coeffs[du];
|
||||
q = FFmul(lcu, lcvrecip);
|
||||
DUPFFshift_add(u, v, du-dv, p-q);
|
||||
DUPFFshift_add(uf, vf, du-dv, p-q);
|
||||
DUPFFshift_add(ug, vg, du-dv, p-q);
|
||||
}
|
||||
DUPFFswap(u, v);
|
||||
DUPFFswap(uf, vf);
|
||||
DUPFFswap(ug, vg);
|
||||
}
|
||||
if (DUPFFdeg(v) == 0)
|
||||
{
|
||||
DUPFFswap(u, v);
|
||||
DUPFFswap(uf, vf);
|
||||
DUPFFswap(ug, vg);
|
||||
}
|
||||
DUPFFfree(vf);
|
||||
DUPFFfree(vg);
|
||||
DUPFFfree(v);
|
||||
*fcofac = uf;
|
||||
*gcofac = ug;
|
||||
return u;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
DUPFF f, g, cf, cg, h;
|
||||
f = DUPFFnew(1); f->coeffs[1] = 1; f->deg = 1;
|
||||
g = DUPFFnew(2); g->coeffs[2] = 1; g->deg = 2;
|
||||
|
||||
printf("calling DUPFFexgcd on degrees %d and %d\n", DUPFFdeg(f), DUPFFdeg(g)) ;
|
||||
h = DUPFFexgcd(&cf, &cg, f, g);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user