https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97445
--- Comment #36 from Jan Hubicka <hubicka at ucw dot cz> ---
> Find attached the temporary files for net/core/skbuff.c, as it is indeed what
> initially triggered my focus on this issue. I don't expect such a function at
> all:
>
> 00000cc8 <csum_partial>:
> cc8: 48 00 00 00 b cc8 <csum_partial>
> cc8: R_PPC_REL24 __csum_partial
>
>
> Every function should call __csum_partial() directly.
Here csum_artial is:
static inline __attribute__((__gnu_inline__)) __attribute__((__unused__))
__attribute__((__no_instrument_function__)) __wsum csum_add(__wsum csum, __wsum
addend)
{
if (__builtin_constant_p(csum) && csum == 0)
return addend;
if (__builtin_constant_p(addend) && addend == 0)
return csum;
asm("addc %0,%0,%1;"
"addze %0,%0;"
: "+r" (csum) : "r" (addend) : "xer");
return csum;
}
static inline __attribute__((__gnu_inline__)) __attribute__((__unused__))
__attribute__((__no_instrument_function__)) __wsum csum_partial(const void
*buff, int len, __wsum sum)
{
if (__builtin_constant_p(len) && len <= 16 && (len & 1) == 0) {
if (len == 2)
sum = csum_add(sum, ( __wsum)*(const u16 *)buff);
if (len >= 4)
sum = csum_add(sum, ( __wsum)*(const u32 *)buff);
if (len == 6)
sum = csum_add(sum, ( __wsum)
*(const u16 *)(buff + 4));
if (len >= 8)
sum = csum_add(sum, ( __wsum)
*(const u32 *)(buff + 4));
if (len == 10)
sum = csum_add(sum, ( __wsum)
*(const u16 *)(buff + 8));
if (len >= 12)
sum = csum_add(sum, ( __wsum)
*(const u32 *)(buff + 8));
if (len == 14)
sum = csum_add(sum, ( __wsum)
*(const u16 *)(buff + 12));
if (len >= 16)
sum = csum_add(sum, ( __wsum)
*(const u32 *)(buff + 12));
} else if (__builtin_constant_p(len) && (len & 3) == 0) {
sum = csum_add(sum, ip_fast_csum_nofold(buff, len >> 2));
} else {
sum = __csum_partial(buff, len, sum);
}
return sum;
}
So again it expands to really large decision tree with many
builtion_constant_p checks that makes inliner to give up.
You should see all such cases easilly with -Winline