https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87254
Bug ID: 87254 Summary: Inlining clones in trivial wrappers Product: gcc Version: 9.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: normal Priority: P3 Component: ipa Assignee: unassigned at gcc dot gnu.org Reporter: glisse at gcc dot gnu.org CC: marxin at gcc dot gnu.org Target Milestone: --- int h(); static int f(int j,double*a){ if(j) { double t[1024]; for(int i=0;i<1024;++i){t[i]=i;} return t[(int)*a]; } else return h(); } int g(double*a){return f(0,a);} Compiled with -O3. The code in f is random crap, the key elements to reproduce are: - f is not inlined in einline, - f is cloned in IPA-CP, - the clone of f is not inlined in g. (so a simpler reproducer may be possible with -fdisable-tree-einline --param ipa-cp-eval-threshold=10) The first 2 steps are normal, but the last one seems wrong to me. There is nothing to lose by inlining f's clone into the trivial wrapper that is its only caller. The inline dump complains that "--param large-stack-frame-growth limit reached", but changing this param has no effect, I have to change "large-stack-frame" instead to convince it to inline. Just in case, before that I was investigating static int f(int j,double*a){ if(j) { double t[1024]; for(int i=0;i<1024;++i){t[i]=i;} return t[(int)*a]; } else { float t[1024]; for(int i=0;i<1024;++i){t[i]=i;} return t[(int)*a]; } } int g(double*a){return f(0,a);} int h(double*a){return f(1,a);} with -O3 -fdisable-tree-einline --param ipa-cp-eval-threshold=10 . In the past, I have seen such trivial left-over wrappers with -flto on GMP ( https://gmplib.org/list-archives/gmp-devel/2018-April/004874.html ), and I was reminded of it by https://stackoverflow.com/q/51152215/1918193 .