https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116191
Bug ID: 116191 Summary: Avoid inlining in unlikely branches Product: gcc Version: 14.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: ilija.tovilo at me dot com Target Milestone: --- Note that I raised this issue on the mailing list first, but was asked to create a bug report instead. https://gcc.gnu.org/pipermail/gcc/2024-July/244509.html I noticed that, in our codebase, gcc inlines some non-trivial functions in unlikely branches, as signaled by __builtin_expect or __builtin_expect_with_probability with any probability. This example is adapted from php-src. https://godbolt.org/z/aEcoKMdrr void normal(zend_string *s) { zend_string_release(s); } __attribute__((cold)) void cold_function(zend_string *s) { zend_string_release(s); } void unlikely_branch(zend_string *s, bool cond) { if (__builtin_expect_with_probability(cond, 0, 0.999)) { zend_string_release(s); } printf("Hello world"); } __attribute__((hot)) void unlikely_branch_in_hot_function(zend_string *s, bool cond) { if (__builtin_expect_with_probability(cond, 0, 0.999)) { zend_string_release(s); } printf("Hello world"); } In this particular example, zend_string_release() is inlined in all but the cold_function(). It seems to be like there should be some threshold where gcc avoids inlining in unlikely branches. Especially in hot functions, growing unlikely branches may lead to more instruction cache misses. Coincidentally, Clang does the exact opposite, inlining in cold functions, but not in unlikely branches. What threshold that should be is unclear to me. Note that, optimally, gcc would also avoid inlining extern inline functions in unlikely branches, despite the inline hint, as it is the only way to allow inlining from other compilation units. I get this behavior on godbolt.org from gcc 10.x onward. Of course, this is just a singular example. I don't know the details of gcc's inlining heuristics, so please close this issue if adjusting this is not an option. Thank you for the wonderful compiler that is gcc!