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

Reply via email to