------- Comment #2 from rguenth at gcc dot gnu dot org 2008-01-11 09:42 ------- Confirmed.
void foo(char *p); void test1(char * p) { foo(p++); foo(p++); foo(p++); foo(p++); } void test2(char * p) { foo(p); p++; foo(p); p++; foo(p); p++; foo(p); p++; } The problem is with the first variant we have two registers life over each function call, while with the second variant only one. This can be seen from the optimized tree-dump already: test1 (p) { <bb 2>: p_3 = p_1(D) + 1; foo (p_1(D)); p_5 = p_3 + 1; foo (p_3); p_7 = p_5 + 1; foo (p_5); foo (p_7) [tail call]; return; } test2 (p) { <bb 2>: foo (p_1(D)); p_2 = p_1(D) + 1; foo (p_2); p_3 = p_2 + 1; foo (p_3); p_4 = p_3 + 1; foo (p_4) [tail call]; return; } and is initially caused by gimplification which produces p.0 = p; p = p + 1; foo (p.0); from foo (p++ ); no further pass undos this transformation. With GCC 4.0 TER produced foo (p); foo (p + 1B); foo (p + 2B); ... where we can generate good code from. From 4.1 on this is no longer done. -- rguenth at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |rguenth at gcc dot gnu dot | |org Severity|normal |enhancement Status|UNCONFIRMED |NEW Component|c |tree-optimization Ever Confirmed|0 |1 GCC target triplet|multiple-none-none | Keywords| |missed-optimization Last reconfirmed|0000-00-00 00:00:00 |2008-01-11 09:42:38 date| | Summary|missed optimization, foo(p);|Inefficient gimplification |p++ is better then foo(p++) |of post-modified function | |arguments, TER doesn't do | |its work http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34737