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