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.