From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 527 invoked by alias); 17 Nov 2011 09:00:14 -0000 Received: (qmail 475 invoked by uid 22791); 17 Nov 2011 09:00:09 -0000 X-SWARE-Spam-Status: No, hits=-2.7 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00,TW_BJ,TW_CX,TW_DC,TW_GX X-Spam-Check-By: sourceware.org Received: from localhost (HELO gcc.gnu.org) (127.0.0.1) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 17 Nov 2011 08:59:53 +0000 From: "jurij at wooyd dot org" To: gcc-bugs@gcc.gnu.org Subject: [Bug c/51187] New: gcc 4.6.2 miscompiles genrecog.c when building gcc 4.5.3 with --target=avr on Debian/sparc Date: Thu, 17 Nov 2011 09:11:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: jurij at wooyd dot org X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Changed-Fields: Message-ID: X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated Content-Type: text/plain; charset="UTF-8" MIME-Version: 1.0 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2011-11/txt/msg01727.txt.bz2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51187 Bug #: 51187 Summary: gcc 4.6.2 miscompiles genrecog.c when building gcc 4.5.3 with --target=avr on Debian/sparc Classification: Unclassified Product: gcc Version: 4.6.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned@gcc.gnu.org ReportedBy: jurij@wooyd.org Hello, We discovered this bug in gcc 4.6.2 in Debian due to build failure of gcc-avr package on sparc (tracked in Debian as http://bugs.debian.org/648016), which uses gcc 4.5 source to build an AVR cross-compiler. I was not able to come up with a nice self-contained test-case, but here are the steps to reproduce the failure. 1. Download the gcc-4.5.3.tar.bz2 release tarball. 2. Configure it with ./configure -v --enable-languages=c,c++ --prefix=/usr/lib --infodir=/usr/share/info --mandir=/usr/share/man --bindir=/usr/bin --libexecdir=/usr/lib --libdir=/usr/lib --enable-shared --with-system-zlib --enable-long-long --enable-nls --without-included-gettext --disable-checking --disable-libssp --build=sparc-linux-gnu --host=sparc-linux-gnu --target=avr Unfortunately, this will probably require binutils-avr to be installed, even though I believe the build never gets far enough to actually use them. 3. Start the build with 'make' using gcc 4.6. In my case the default Debian system compiler used to build utilities (including genrecog.c): jurij@debian:~$ sparc-linux-gnu-gcc -v Using built-in specs. COLLECT_GCC=sparc-linux-gnu-gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/sparc-linux-gnu/4.6/lto-wrapper Target: sparc-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Debian 4.6.2-4' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-objc-gc --enable-targets=all --with-long-double-128 --enable-checking=release --build=sparc-linux-gnu --host=sparc-linux-gnu --target=sparc-linux-gnu Thread model: posix gcc version 4.6.2 (Debian 4.6.2-4) 4. Build will fail with the following messages: [...] sparc-linux-gnu-gcc -c -g -O2 -DIN_GCC -DCROSS_DIRECTORY_STRUCTURE -W -Wall -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wmissing-format-attribute -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -Wold-style-definition -Wc++-compat -DHAVE_CONFIG_H -DGENERATOR_FILE -I. -Ibuild -I../.././gcc -I../.././gcc/build -I../.././gcc/../include -I../.././gcc/../libcpp/include -I../.././gcc/../libdecnumber -I../.././gcc/../libdecnumber/dpd -I../libdecnumber -DCLOOG_PPL_BACKEND -I/usr/include/libelf \ -o build/genrecog.o ../.././gcc/genrecog.c sparc-linux-gnu-gcc -g -O2 -DIN_GCC -DCROSS_DIRECTORY_STRUCTURE -W -Wall -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wmissing-format-attribute -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -Wold-style-definition -Wc++-compat -DHAVE_CONFIG_H -DGENERATOR_FILE -o build/genrecog \ build/genrecog.o build/rtl.o build/read-rtl.o build/ggc-none.o build/vec.o build/min-insn-modes.o build/gensupport.o build/print-rtl.o build/errors.o ../../build-sparc-linux-gnu/libiberty/libiberty.a build/genrecog ../.././gcc/config/avr/avr.md \ insn-conditions.md > tmp-recog.c /bin/bash: line 1: 22105 Bus error build/genrecog ../.././gcc/config/avr/avr.md insn-conditions.md > tmp-recog.c make[2]: *** [s-recog] Error 138 make[2]: Leaving directory `/home/jurij/gcc/gcc-4.5-upstream/gcc-4.5.3/host-sparc-linux-gnu/gcc' make[1]: *** [all-gcc] Error 2 make[1]: Leaving directory `/home/jurij/gcc/gcc-4.5-upstream/gcc-4.5.3' make: *** [all] Error 2 The output of the genrecog.c compilation with -v -save-temps added to the above command line: Using built-in specs. COLLECT_GCC=sparc-linux-gnu-gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/sparc-linux-gnu/4.6/lto-wrapper Target: sparc-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Debian 4.6.2-4' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,ob j-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads= posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plug in --enable-objc-gc --enable-targets=all --with-long-double-128 --enable-checking=release --build=sparc-linux-gnu --host=sparc-linux-gnu --target=sparc-linux-gnu Thread model: posix gcc version 4.6.2 (Debian 4.6.2-4) COLLECT_GCC_OPTIONS='-v' '-save-temps' '-c' '-g' '-O2' '-D' 'IN_GCC' '-D' 'CROSS_DIRECTORY_STRUCTURE' '-Wextra' '-Wall' '-Wwrite-strings' '-Wcast-qual' '-Wstrict-protot ypes' '-Wmissing-prototypes' '-Wmissing-format-attribute' '-pedantic' '-Wno-long-long' '-Wno-variadic-macros' '-Wno-overlength-strings' '-Wold-style-definition' '-Wc++- compat' '-D' 'HAVE_CONFIG_H' '-D' 'GENERATOR_FILE' '-I' '.' '-I' 'build' '-I' '../.././gcc' '-I' '../.././gcc/build' '-I' '../.././gcc/../include' '-I' '../.././gcc/../ libcpp/include' '-I' '../.././gcc/../libdecnumber' '-I' '../.././gcc/../libdecnumber/dpd' '-I' '../libdecnumber' '-D' 'CLOOG_PPL_BACKEND' '-I' '/usr/include/libelf' '-o ' 'build/genrecog.o' '-mcpu=ultrasparc' /usr/lib/gcc/sparc-linux-gnu/4.6/cc1 -E -quiet -v -I . -I build -I ../.././gcc -I ../.././gcc/build -I ../.././gcc/../include -I ../.././gcc/../libcpp/include -I ../.. /./gcc/../libdecnumber -I ../.././gcc/../libdecnumber/dpd -I ../libdecnumber -I /usr/include/libelf -imultilib . -imultiarch sparc-linux-gnu -D__sparc_v9__ -D IN_GCC -D CROSS_DIRECTORY_STRUCTURE -D HAVE_CONFIG_H -D GENERATOR_FILE -D CLOOG_PPL_BACKEND ../.././gcc/genrecog.c -mcpu=ultrasparc -Wextra -Wall -Wwrite-strings -Wcast-qual -Ws trict-prototypes -Wmissing-prototypes -Wmissing-format-attribute -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -Wold-style-definition -Wc++-comp at -g -fworking-directory -O2 -fpch-preprocess -o genrecog.i ignoring nonexistent directory "/usr/local/include/sparc-linux-gnu" ignoring nonexistent directory "/usr/lib/gcc/sparc-linux-gnu/4.6/../../../../sparc-linux-gnu/include" ignoring nonexistent directory "../.././gcc/build" #include "..." search starts here: #include <...> search starts here: . build ../.././gcc ../.././gcc/../include ../.././gcc/../libcpp/include ../.././gcc/../libdecnumber ../.././gcc/../libdecnumber/dpd ../libdecnumber /usr/include/libelf /usr/lib/gcc/sparc-linux-gnu/4.6/include /usr/local/include /usr/lib/gcc/sparc-linux-gnu/4.6/include-fixed /usr/include/sparc-linux-gnu /usr/include End of search list. COLLECT_GCC_OPTIONS='-v' '-save-temps' '-c' '-g' '-O2' '-D' 'IN_GCC' '-D' 'CROSS_DIRECTORY_STRUCTURE' '-Wextra' '-Wall' '-Wwrite-strings' '-Wcast-qual' '-Wstrict-prototypes' '-Wmissing-prototypes' '-Wmissing-format-attribute' '-pedantic' '-Wno-long-long' '-Wno-variadic-macros' '-Wno-overlength-strings' '-Wold-style-definition' '-Wc++-compat' '-D' 'HAVE_CONFIG_H' '-D' 'GENERATOR_FILE' '-I' '.' '-I' 'build' '-I' '../.././gcc' '-I' '../.././gcc/build' '-I' '../.././gcc/../include' '-I' '../.././gcc/../libcpp/include' '-I' '../.././gcc/../libdecnumber' '-I' '../.././gcc/../libdecnumber/dpd' '-I' '../libdecnumber' '-D' 'CLOOG_PPL_BACKEND' '-I' '/usr/include/libelf' '-o' 'build/genrecog.o' '-mcpu=ultrasparc' /usr/lib/gcc/sparc-linux-gnu/4.6/cc1 -fpreprocessed genrecog.i -quiet -dumpbase genrecog.c -mcpu=ultrasparc -auxbase-strip build/genrecog.o -g -O2 -Wextra -Wall -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wmissing-format-attribute -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -Wold-style-definition -Wc++-compat -version -o genrecog.s GNU C (Debian 4.6.2-4) version 4.6.2 (sparc-linux-gnu) compiled by GNU C version 4.6.2, GMP version 5.0.2, MPFR version 3.1.0, MPC version 0.9 warning: MPFR header version 3.1.0 differs from library version 3.1.0-p3. GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 GNU C (Debian 4.6.2-4) version 4.6.2 (sparc-linux-gnu) compiled by GNU C version 4.6.2, GMP version 5.0.2, MPFR version 3.1.0, MPC version 0.9 warning: MPFR header version 3.1.0 differs from library version 3.1.0-p3. GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: 9af244203689b6207cc96ca7373030e6 COLLECT_GCC_OPTIONS='-v' '-save-temps' '-c' '-g' '-O2' '-D' 'IN_GCC' '-D' 'CROSS_DIRECTORY_STRUCTURE' '-Wextra' '-Wall' '-Wwrite-strings' '-Wcast-qual' '-Wstrict-prototypes' '-Wmissing-prototypes' '-Wmissing-format-attribute' '-pedantic' '-Wno-long-long' '-Wno-variadic-macros' '-Wno-overlength-strings' '-Wold-style-definition' '-Wc++-compat' '-D' 'HAVE_CONFIG_H' '-D' 'GENERATOR_FILE' '-I' '.' '-I' 'build' '-I' '../.././gcc' '-I' '../.././gcc/build' '-I' '../.././gcc/../include' '-I' '../.././gcc/../libcpp/include' '-I' '../.././gcc/../libdecnumber' '-I' '../.././gcc/../libdecnumber/dpd' '-I' '../libdecnumber' '-D' 'CLOOG_PPL_BACKEND' '-I' '/usr/include/libelf' '-o' 'build/genrecog.o' '-mcpu=ultrasparc' as -s -Av9a -32 -relax -o build/genrecog.o genrecog.s COMPILER_PATH=/usr/lib/gcc/sparc-linux-gnu/4.6/:/usr/lib/gcc/sparc-linux-gnu/4.6/:/usr/lib/gcc/sparc-linux-gnu/:/usr/lib/gcc/sparc-linux-gnu/4.6/:/usr/lib/gcc/sparc-linux-gnu/ LIBRARY_PATH=/usr/lib/gcc/sparc-linux-gnu/4.6/:/usr/lib/gcc/sparc-linux-gnu/4.6/../../../sparc-linux-gnu/:/usr/lib/gcc/sparc-linux-gnu/4.6/../../../../lib/:/lib/sparc-linux-gnu/:/lib/../lib/:/usr/lib/sparc-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/sparc-linux-gnu/4.6/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-v' '-save-temps' '-c' '-g' '-O2' '-D' 'IN_GCC' '-D' 'CROSS_DIRECTORY_STRUCTURE' '-Wextra' '-Wall' '-Wwrite-strings' '-Wcast-qual' '-Wstrict-prototypes' '-Wmissing-prototypes' '-Wmissing-format-attribute' '-pedantic' '-Wno-long-long' '-Wno-variadic-macros' '-Wno-overlength-strings' '-Wold-style-definition' '-Wc++-compat' '-D' 'HAVE_CONFIG_H' '-D' 'GENERATOR_FILE' '-I' '.' '-I' 'build' '-I' '../.././gcc' '-I' '../.././gcc/build' '-I' '../.././gcc/../include' '-I' '../.././gcc/../libcpp/include' '-I' '../.././gcc/../libdecnumber' '-I' '../.././gcc/../libdecnumber/dpd' '-I' '../libdecnumber' '-D' 'CLOOG_PPL_BACKEND' '-I' '/usr/include/libelf' '-o' 'build/genrecog.o' '-mcpu=ultrasparc' I'm attaching genrecog.i produced by that. My analysis indicates that failure happens due to a miscompilation of genrecog.c by gcc 4.6.2. Here's the debugging information I posted to the Debian bug already (note that this was done using gcc-avr Debian source package, so running genrecog in pristine 4.5.3 produces slightly different output, but I believe that it still crashes due to same reason): This bug really is in gcc-4.6, because it is currently the default sid gcc and it is used to (mis)compile src/build/genrecog.c during gcc-avr build, which later crashes. I'm fairly certain that this is gcc problem, because if the binary is compiled with -O0, the problem goes away. All debugging output below was obtained on a sparc machine running up-to-date sid, invoking build/genrecog under gdb with a single argument of '../../src/gcc/config/avr/avr.md'. Tracing the execution is somewhat tricky, since failure happens within write_tree(), and most of the functions write_tree() calls (write_tree_1, write_switch, write_node, write_action, etc) are optimized out. The output generated by build/genrecog ../../src/gcc/config/avr/avr.md is the same as the one produced on an amd64 system until we hit the following code in genrecog.c/write_switch(): else if (type == DT_mode || type == DT_veclen || type == DT_elt_zero_int || type == DT_elt_one_int || type == DT_elt_zero_wide_safe) { const char *indent = ""; /* We cast switch parameter to integer, so we must ensure that the value fits. */ if (type == DT_elt_zero_wide_safe) { indent = " "; printf(" if ((int) XWINT (x%d, 0) == XWINT (x%d, 0))\n", depth, depth); } printf ("%s switch (", indent); switch (type) { case DT_mode: printf ("GET_MODE (x%d)", depth); break; case DT_veclen: printf ("XVECLEN (x%d, 0)", depth); break; case DT_elt_zero_int: printf ("XINT (x%d, 0)", depth); break; case DT_elt_one_int: printf ("XINT (x%d, 1)", depth); break; case DT_elt_zero_wide_safe: /* Convert result of XWINT to int for portability since some C compilers won't do it and some will. */ printf ("(int) XWINT (x%d, 0)", depth); break; default: gcc_unreachable (); } The problem appears after executing the printf ("%s switch (", indent); statetement. It looks like compiler generates a number of small stubs within write_tree() for calling printf with all possible format statements. Here's how the generated assembler code looks for this particular one, starting at 0x00013e60: Dump of assembler code from 0x13e40 to 0x13ea0: 0x00013e40 : ld [ %i5 + 0x1c ], %o2 0x00013e44 : sethi %hi(0x1e800), %o0 0x00013e48 : or %l1, 0x110, %o1 0x00013e4c : call 0x3510c 0x00013e50 : or %o0, 0x258, %o0 0x00013e54 : b %xcc, 0x13bf4 0x00013e58 : ld [ %i0 ], %i5 0x00013e5c : be,pn %icc, 0x13850 => 0x00013e60 : sethi %hi(0x1f400), %i3 0x00013e64 : sethi %hi(0x1e800), %o0 0x00013e68 : or %o0, 0x2b0, %o0 ! 0x1eab0 0x00013e6c : call 0x3510c 0x00013e70 : or %i3, 0xe8, %o1 0x00013e74 : cmp %l7, 7 0x00013e78 : sll %l7, 2, %g1 0x00013e7c : sethi %hi(0x1e800), %o0 0x00013e80 : mov %l6, %o1 0x00013e84 : call 0x3510c 0x00013e88 : or %o0, 0x3e8, %o0 0x00013e8c : b %xcc, 0x13bac 0x00013e90 : ld [ %fp + -192 ], %g3 0x00013e94 : b %xcc, 0x13ad0 0x00013e98 : st %g2, [ %fp + -188 ] 0x00013e9c : cmp %g0, %i3 End of assembler dump. Confirmation that 0x1eab0 contains the correct format statement (passed to printf in %o0): (gdb) printf "%s\n", (char *) 0x1eab0 %s switch ( (gdb) A remarkable feature of this stub is that it does not have a return branch statement, like others do (see 0x00013e54, for example). So, instead of returning to the correct location where the stub was invoked in write_switch(), we fall through to 0x00013e74, and start executing the next stub, which invokes printf with a format statement at 0x1ebe8 (== 0x1e800 | 0x3e8): (gdb) printf "%s\n", (char *) 0x1ebe8 %sreturn gen_split_%d (insn, operands); (gdb) This is completely unrelated code, normally invoked by write_action(), line 2182. Once it's done, we jump back to completely wrong location at 0x00013e8c, eventually causing a crash.