https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121692
--- Comment #7 from Jan Hubicka <hubicka at ucw dot cz> --- > > Inliner does not track argument as a constant and predicates does not have > > condition "op is not constant". So we end up accounting __builtin_constant_p > > path as well as !builting_constant_p path. > > That is find, but the builtin_constant_p path should really be small since it > folds to a constant. inliner knows that builtion_constant_p will not generate any code itself. If it does not know the particular value of the parameter, it will however account all code implementing the special cases for particular constants (even if in final code only one of the code paths will survive), since it does not know if the value will be constnat propagated later. It kind of sucks indeed. I was thinking of adjusting this to simply account the largest case in such scenarios, but never implemented it. It is not completely trivial to pattern match this situation and also inline summaries are additive and do not allow to represent "take max of two values" at the moment. > > > This is kind of necessary, since inliner does not have enough info to tell > > that __builtin_constant_p will be false after inlinng. > > Does that mean __builtin_constant_p cannot be used to optimize such functions > in the presence of cold functions without forcing the function inline via > always_inline? Yep. Even if function is not explicitely marked cold, inliner heuristics may act funy on functions having larger __builtin_constant_p decision trees, so making them always_inline if they should be always inlined is a good idea. Honza