https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67262

            Bug ID: 67262
           Summary: Massive number of nested SWITCH statements with -O1
                    causes g++ internal error
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: minor
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: clem at clem dot com
  Target Milestone: ---

Created attachment 36207
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36207&action=edit
Compress .cpp file with massive nested SWITCHes that causes g++ internal err
with -O1 flag

gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC)

Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla
--enable-bootstrap --enable-shared --enable-threads=posix
--enable-checking=release --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-gnu-unique-object
--enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk
--disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre
--enable-libgcj-multifile --enable-java-maintainer-mode
--with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib
--with-ppl --with-cloog --with-tune=generic --with-arch_32=i686
--build=x86_64-redhat-linux
Thread model: posix

I created this code with a program that creates a Trie function implemented
with a massive number of nested SWITCH (and IF-THEN-ELSE) statements.  (This is
a straightforward function with no includes or preprocessor directives).

I kind of doubt I can make a much smaller example (sorry about that.)  In
other, smaller versions of the code (fewer strings to match), the compiler
appears to compile correctly.  So, I suspect I blew up some sort of internal
limit.  It does take a while to compile (over 20 minutes).

There also seems to be some sort of optimization problem which I couldn't
isolate.  I tried a number of different flags:

g++ -c     host_rank.bad.cpp -o Ono  # No error
g++ -c -O0 host_rank.bad.cpp -o O0   # No error
g++ -c -O1 host_rank.bad.cpp -o O1   # INTERNAL ERROR

These are some of the optimizations that are in -O1 that aren't in -O0 that I
tried separately:

g++ -c -fmerge-constants host_rank.bad.cpp -o Ofmerge-constants  # No error
g++ -c -fguess-branch-probability host_rank.bad.cpp -o
O-fguess-branch-probability  # No error
g++ -c -fcprop-registers  host_rank.bad.cpp -o O-fcprop-registers # No error
g++ -c -fif-conversion host_rank.bad.cpp -o O-fif-conversion   # No error
g++ -c -fif-conversion2 host_rank.bad.cpp -o O-fif-conversion2 # No error
g++ -c -ftree-ccp host_rank.bad.cpp -o O-ftree-ccp     # No error
g++ -c -ftree-sink  host_rank.bad.cpp -o O-ftree-sink  # No Error
g++ -c -ftree-dse host_rank.bad.cpp -o O-ftree-dse     # No Error
g++ -c -ftree-copy-prop  host_rank.bad.cpp -o O-ftree-copy-prop # No Error
g++ -c -ftree-dominator-opts host_rank.bad.cpp -o O-ftree-dominator-opts # No
error
g++ -c -ftree-fre host_rank.bad.cpp -o O-ftree-fre # No error
g++ -c -ftree-copy-prop  host_rank.bad.cpp -o O-ftree-copy-prop  # No Error

(I didn't try -O2)
g++ -c -O3 host_rank.bad.cpp -o O3   # INTERNAL ERROR


The difference between -O0 and -O1 is these are enabled (by comparing
gcc -c -Q -O0 --help=optimizers
gcc -c -Q -O1 --help=optimizers
)

-fcprop-registers
-fdefer-pop
-fguess-branch-probability
-fif-conversion
-fif-conversion2
-fipa-pure-const
-fipa-reference
-fmerge-constants
-fomit-frame-pointer
-fsplit-wide-types
-ftree-ccp
-ftree-ch
-ftree-copy-prop
-ftree-copyrename
-ftree-dce
-ftree-dominator-opts
-ftree-dse
-ftree-fre
-ftree-sink
-ftree-sra
-ftree-ter


The error message I get is:

g++: Internal error: Killed (program cc1plus)
Please submit a full bug report.
See <http://bugzilla.redhat.com/bugzilla> for instructions.



Unfortunately, the source file is 8MB, so I had to attach it as a compressed
.gz file

The start of the code looks like this (99639 lines total).
No #includes or any preprocessing whatsoever.

double host_rank_trie(const char* s){

    switch(s[0]){
    case '8': if (s[1] == '6' && s[2] == '.' && s[3] == '6' && s[4] == '2' &&
s[5] == '2' && s[6] == '.' && s[7] == '2' && s[8] == '1' && s[9] == '.' &&
s[10] == '4' && s[11] == '0' && s[12] == '2' && s[13] == '.') return 3.6; else
return 8.0; // 86.622.21.402. (13)
    case 'a':
        switch(s[1]){
        case 'b':
            switch(s[2]){
            case '.':
                switch(s[3]){
                case 'a': if (s[4] == 'v' && s[5] == 'i' && s[6] == 'z' && s[7]
== 'u' && s[8] == 'l' && s[9] == 'k' && s[10] == 's' && s[11] == 'k' && s[12]
== 'e' && s[13] == '.') return 4.0; else return 8.0; // ab.avizulkske. (10)
/// ETC

Reply via email to