http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46763
Richard Guenther <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |NEW
Last reconfirmed| |2010.12.02 13:26:31
CC| |rguenth at gcc dot gnu.org
Depends on| |41490
Ever Confirmed|0 |1
Severity|normal |enhancement
--- Comment #2 from Richard Guenther <rguenth at gcc dot gnu.org> 2010-12-02
13:26:31 UTC ---
GCC has to preserve the stores and loads around the call to bar() as that
might change the value of the variable. So transforming to
int g;
extern int bar(int);
void foo(int n)
{
int i;
int tem = g;
for (i = 0; i < n; i++)
{
if (tem)
{
tem++;
tem = bar(i);
}
else
tem = i;
}
g = tem;
}
if that is what you did in your source-to-source transformation isn't valid.
GCC can't do conditional store motion, that is, transform it to
int g;
extern int bar(int);
void foo(int n)
{
int i;
int tem = g;
for (i = 0; i < n; i++)
{
if (tem)
{
tem++;
g = tem;
tem = bar(i);
}
else
tem = i;
}
g = tem;
}
which would be valid. An enabling transform is missing as well, sinking
the store to g:
int g;
extern int bar(int);
void foo(int n)
{
int i;
for (i = 0; i < n; i++)
{
if (g)
{
g++;
tem = bar(i);
}
else
tem = i;
g = tem;
}
}
which would then allow us to do the load part of the partial store motion
by PRE. That is, you'd get
int g;
extern int bar(int);
void foo(int n)
{
int i,tem;
tem = g;
for (i = 0; i < n; i++)
{
if (tem)
{
tem++;
g = tem;
tem = bar(i);
}
else
tem = i;
g = tem;
}
}
but we don't understand that we can sink the store out of the loop
as we don't understand the combined effect of g = tem; tem = bar (i);
to g. You also get the above with -O3 because we see a partial partial
redundancy but then you retain three stores (we still miss both
sinking opportunities). Fixing PR41490 might fix both.