This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug tree-optimization/21254] New: Incorrect code with -funroll-loops for multiple targets with same code


The following C++, when compiled with g++-4.0.0, produces incorrect code when 
compiled with -O1 -funroll-loops on both sparc-sun-solaris2.8 and i686-pc-linux-
gnu.  This is a bare-bones simplification of real code from an application using 
the Boost.Spirit library.  If compiled without -funroll-loops, then the 
behaviour is as expected (no exception thrown; see below).

$ /opt/gcc-4.0.0-cross/sparc-sun-solaris2.8/bin/sparc-sun-solaris2.8-g++ -v
Using built-in specs.
Target: sparc-sun-solaris2.8
Configured with: ../../gcc-4.0.0/configure --with-dwarf2 --enable-languages=c,
c++ --enable-threads=no --disable-shared --prefix=/opt/gcc-4.0.0-cross/sparc-
sun-solaris2.8 --with-gnu-as --with-gnu-ld --disable-multilib --enable-concept-
checks --enable-clocale=generic --enable-libstdcxx-allocator=mt --build=i686-pc-
linux-gnu --host=i686-pc-linux-gnu --target=sparc-sun-solaris2.8 --with-
sysroot=/opt/sysroot/sparc-sun-solaris2.8/
Thread model: single
gcc version 4.0.0

$ /opt/gcc-4.0.0-cross/i686-pc-linux-gnu/bin/i686-pc-linux-gnu-g++ -v
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ../../gcc-4.0.0/configure --with-dwarf2 --enable-languages=c,
c++ --enable-threads=no --disable-shared --prefix=/opt/gcc-4.0.0-cross/i686-pc-
linux-gnu --with-gnu-as --with-gnu-ld --disable-multilib --enable-concept-checks 
--enable-clocale=generic --enable-libstdcxx-allocator=mt --build=i686-pc-linux-
gnu --host=i686-pc-linux-gnu --target=i686-pc-linux-gnu
Thread model: single
gcc version 4.0.0

The (poor, but simple) C++ program is as follows:

// sparc-sun-solaris2.8-g++ -Wall -O1 -funroll-loops -o opt-sparc 
test_optimizer.cc
//
// or
//
// i686-pc-linux-gnu-g++ -Wall -O1 -funroll-loops -o opt-x86 test_optimizer.cc

#include <bitset>
#include <stdexcept>

class basic
{
public:
  void set(char from, char to)
  {
    for (int i = from; i <= to; ++i) {
      bset.set(static_cast<unsigned char>(i));
    }
  }
  
private:
  std::bitset<256> bset;
};

// Nevermind that this is not robust code; it's the simplest failure case.
void func(basic * const ptr,
          const char *definition)
{
  char ch = *definition;
  ++definition;
  
  while (ch) {
    char next = *definition;
    ++definition;

    if (next == '-') {
      next = *definition;
      ++definition;

      ptr->set(ch, next);
    }
    ch = next;
  }
}

int
main(const int argc,
     const char * const * const argv)
{
  basic ptr;
  func(&ptr, "A-B");
}

This program should just set a couple of bits in the bitset and exit without any 
output.  However, if compiled as described above, it triggers bitset's throw of 
std::out_of_range:

$ ./opt-sparc 
terminate called after throwing an instance of 'std::out_of_range'
  what():  bitset::set
Abort

$ ./opt-x86 
terminate called after throwing an instance of 'std::out_of_range'
  what():  bitset::set
Aborted

The loop in func() has been "simplified" to remove all untaken branch pathways 
while still triggering the bug.

This appears to be a regression since gcc-3.4.3 (for both targets) has no 
trouble with this code.  Version info from those compilers is shown below.

$ /opt/gcc-3.4.3-cross/sparc-sun-solaris2.8/bin/sparc-sun-solaris2.8-g++ -v
Reading specs from /opt/gcc-3.4.3-cross/sparc-sun-solaris2.8/lib/gcc/sparc-sun-
solaris2.8/3.4.3/specs
Configured with: ../../gcc-3.4.3/configure --with-dwarf2 --enable-languages=c,
c++ --enable-threads=no --disable-shared --prefix=/opt/gcc-3.4.3-cross/sparc-
sun-solaris2.8 --with-gnu-as --with-gnu-ld --disable-multilib --enable-concept-
checks --enable-clocale=generic --enable-libstdcxx-allocator=mt --build=i686-pc-
linux-gnu --host=i686-pc-linux-gnu --target=sparc-sun-solaris2.8 --with-
sysroot=/opt/sysroot/sparc-sun-solaris2.8/
Thread model: single
gcc version 3.4.3

$ /opt/gcc-3.4.3-cross/i686-pc-linux-gnu/bin/i686-pc-linux-gnu-g++ -v
Reading specs from /opt/gcc-3.4.3-cross/i686-pc-linux-gnu/lib/gcc/i686-pc-linux-
gnu/3.4.3/specs
Configured with: ../../gcc-3.4.3/configure --with-dwarf2 --enable-languages=c,
c++ --enable-threads=no --disable-shared --prefix=/opt/gcc-3.4.3-cross/i686-pc-
linux-gnu --with-gnu-as --with-gnu-ld --disable-multilib --enable-concept-checks 
--enable-clocale=generic --enable-libstdcxx-allocator=mt --build=i686-pc-linux-
gnu --host=i686-pc-linux-gnu --target=i686-pc-linux-gnu
Thread model: single
gcc version 3.4.3

-- 
           Summary: Incorrect code with -funroll-loops for multiple targets
                    with same code
           Product: gcc
           Version: 4.0.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: tree-optimization
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: spencer at infointeractive dot com
                CC: gcc-bugs at gcc dot gnu dot org


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]