If an inline function has multiple return statements the compiler misses the
opportunity to optimize the code following the function for return statements
returning constants.

here is a little test case to illustrate the problem:

static inline int inline1(int* val) {
  return 2;
}

static inline int inline2(int* val) {
  if(val == 0) return 1;
  ++*val;
  return 3;
}

void a(int*);
void b(int*);
void c(int*);
void d(int*);

void func1(int* val) {
  const void *const labels[] = { &&a, &&b, &&c, &&d };
  goto *labels[inline1(val)];
  a: a(val);
  b: b(val);
  c: c(val);
  d: d(val);
}

void func2(int* val) {
  const void *const labels[] = { &&a, &&b, &&c, &&d };
  goto *labels[inline2(val)];
  a: a(val);
  b: b(val);
  c: c(val);
  d: d(val);
}

compiled with gcc -S -O3 -fomit-frame-pointer -march=nocona -Wall test.c

for func1, the compiler optimizes the code after the inline function knowing
that inline1 always returns 2.
in func2 however, the compiler generates a computed goto instead of knowing
that inline2 always returns 1 or 3.

optimal code for inline2 would be something like this:

  testl  %eax, %eax
  je     b
  addl   $1, (%eax)
  jmp    d



gcc -v
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: /var/tmp/portage/gcc-4.1.2/work/gcc-4.1.2/configure
--prefix=/usr --bindir=/usr/i686-pc-linux-gnu/gcc-bin/4.1.2
--includedir=/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/include
--datadir=/usr/share/gcc-data/i686-pc-linux-gnu/4.1.2
--mandir=/usr/share/gcc-data/i686-pc-linux-gnu/4.1.2/man
--infodir=/usr/share/gcc-data/i686-pc-linux-gnu/4.1.2/info
--with-gxx-include-dir=/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/include/g++-v4
--host=i686-pc-linux-gnu --build=i686-pc-linux-gnu --disable-altivec
--enable-nls --without-included-gettext --with-system-zlib --disable-checking
--disable-werror --enable-secureplt --disable-libunwind-exceptions
--disable-multilib --disable-libmudflap --disable-libssp --disable-libgcj
--enable-languages=c,c++ --enable-shared --enable-threads=posix
--enable-__cxa_atexit --enable-clocale=gnu
Thread model: posix
gcc version 4.1.2 (Gentoo 4.1.2)


-- 
           Summary: missed optimization after inline functions with multiple
                    return statements
           Product: gcc
           Version: 4.1.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: manuelle at ee dot ethz dot ch
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32791

Reply via email to