I was recompiling the linux kernel on a mips ip32 system (an SGI O2) whith only on change in config. I changed CONFIG_BUILD_ELF64 to 'n'. Then, while rebuilding with sgi:~# gcc -v Using built-in specs. Target: mips-linux-gnu Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --disable-libssp --enable-checking=release mips-linux-gnu Thread model: posix gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21) I got this error: CC [M] net/sched/em_u32.o CC [M] net/sched/em_meta.o net/sched/em_meta.c: In function ‘meta_int_loadavg_0’: net/sched/em_meta.c:127: error: PRINT_OPERAND, invalid operand for relocation (const:DI (plus:DI (symbol_ref:DI ("avenrun") [flags 0x40] <var_decl 0x2b357f50 avenrun>) (const_int 4 [0x4]))) net/sched/em_meta.c:127: internal compiler error: in print_operand_reloc, at config/mips/mips.c:5579 Please submit a full bug report, with preprocessed source if appropriate. See <URL:http://gcc.gnu.org/bugs.html> for instructions. For Debian GNU/Linux specific bug reporting instructions, see <URL:file:///usr/share/doc/gcc-4.1/README.Bugs>. {standard input}: Assembler messages: {standard input}:2436: Warning: end of file not at end of a line; newline inserted {standard input}:2547: Warning: missing .end at end of assembly Preprocessed source stored into /tmp/cc0KjlCH.out file, please attach this to your bugreport. make[3]: *** [net/sched/em_meta.o] Error 1 make[2]: *** [net/sched] Error 2 make[1]: *** [net] Error 2 make[1]: Leaving directory `/usr/local/src/linux-2.6.23-rc3' make: *** [debian/stamp-build-kernel] Error 2 The complete command line used seems to be stored in /tmp/cc0KjlCH.out: /usr/lib/gcc/mips-linux-gnu/4.1.2/cc1 -quiet -nostdinc -Iinclude -Iinclude/asm-mips/mach-ip32 -Iinclude/asm-mips/mach-generic -D__KERNEL__ -DVMLINUX_LOAD_ADDRESS=0xffffffff80004000 -DMODULE -DKBUILD_STR(s)=#s -DKBUILD_BASENAME=KBUILD_STR(em_meta) -DKBUILD_MODNAME=KBUILD_STR(em_meta) -isystem /usr/lib/gcc/mips-linux-gnu/4.1.2/include -include include/linux/autoconf.h -MD net/sched/.em_meta.o.d net/sched/em_meta.c -quiet -dumpbase em_meta.c -mabi=64 -msym32 -mno-abicalls -msoft-float -march=r5000 -mlong-calls -auxbase-strip net/sched/.tmp_em_meta.o -g -O2 -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -Werror-implicit-function-declaration -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-aliasing -fno-common -fno-pic -ffreestanding -fomit-frame-pointer -fno-stack-protector -o - -frandom-seed=0 When I deactivated CONFIG_BUILD_ELF64 I read that it does not work with recent binutils. My binutils version is 2.17. The only change due to this config option in Makefile seems to be: ifdef CONFIG_BUILD_ELF64 cflags-y += $(call cc-option,-mno-explicit-relocs) else cflags-y += $(call cc-option,-msym32) endif Please note that if I compile the kernel with CONFIG_BUILD_ELF64=y then gcc does not crash. The preprocessed file /tmp/cc0KjlCH.out is available at http://eppesuigoccas.homedns.org/~giuseppe/gcc-bug-mips-print_operand_reloc.out.bz2 and it about 110kb.
I can reproduce this with gcc-4.1 -c -mabi=64 -msym32 -mno-abicalls -O using Debian's gcc.
I can confirm this with FSF gcc 4.1.3 20070902
This happens with 4.0 - 4.3. gcc 3.4 didn't have the -msym32 option.
Created attachment 14149 [details] testcase
I just tried this on a mipsel-linux compiler: $ /home/ddaney/gccsvn/trunk-build/gcc/xgcc -B/home/ddaney/gccsvn/trunk-build/gcc/ -v -S -mabi=64 -msym32 -mno-abicalls -O2 pr33256.c Reading specs from /home/ddaney/gccsvn/trunk-build/gcc/specs Target: mipsel-linux Configured with: ../trunk/configure --prefix=/home/ddaney/gccsvn/trunk-install --target=mipsel-linux --build=mipsel-linux --host=mipsel-linux --with-gmp=/home/ddaney/mp --with-mpfr=/home/ddaney/mp --with-arch=sb1 --disable-java-awt --without-x --enable-__cxa_atexit --disable-jvmpi Thread model: posix gcc version 4.3.0 20070903 (experimental) [trunk revision 128061] (GCC) COLLECT_GCC_OPTIONS='-B/home/ddaney/gccsvn/trunk-build/gcc/' '-v' '-S' '-mabi=64' '-msym32' '-mno-abicalls' '-O2' '-march=sb1' '-mno-shared' /home/ddaney/gccsvn/trunk-build/gcc/cc1 -quiet -v -iprefix /home/ddaney/gccsvn/trunk-build/gcc/../lib/gcc/mipsel-linux/4.3.0/ -isystem /home/ddaney/gccsvn/trunk-build/gcc/include -isystem /home/ddaney/gccsvn/trunk-build/gcc/include-fixed pr33256.c -quiet -dumpbase pr33256.c -mabi=64 -msym32 -mno-abicalls -march=sb1 -mno-shared -auxbase pr33256 -O2 -version -o pr33256.s ignoring nonexistent directory "/home/ddaney/gccsvn/trunk-build/gcc/../lib/gcc/mipsel-linux/4.3.0/include" ignoring nonexistent directory "/home/ddaney/gccsvn/trunk-build/gcc/../lib/gcc/mipsel-linux/4.3.0/include-fixed" ignoring nonexistent directory "/home/ddaney/gccsvn/trunk-build/gcc/../lib/gcc/mipsel-linux/4.3.0/../../../../mipsel-linux/include" ignoring nonexistent directory "/home/ddaney/gccsvn/trunk-build/gcc/../lib/gcc/../../include" ignoring nonexistent directory "/home/ddaney/gccsvn/trunk-build/gcc/../lib/gcc/../../lib/gcc/mipsel-linux/4.3.0/include" ignoring nonexistent directory "/home/ddaney/gccsvn/trunk-build/gcc/../lib/gcc/../../lib/gcc/mipsel-linux/4.3.0/include-fixed" ignoring nonexistent directory "/home/ddaney/gccsvn/trunk-build/gcc/../lib/gcc/../../lib/gcc/mipsel-linux/4.3.0/../../../../mipsel-linux/include" #include "..." search starts here: #include <...> search starts here: /home/ddaney/gccsvn/trunk-build/gcc/include /home/ddaney/gccsvn/trunk-build/gcc/include-fixed /usr/local/include /usr/include End of search list. GNU C (GCC) version 4.3.0 20070903 (experimental) [trunk revision 128061] (mipsel-linux) compiled by GNU C version 4.3.0 20070903 (experimental) [trunk revision 128061], GMP version 4.2.1, MPFR version 2.3.0. GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096 Compiler executable checksum: e8d0d3f2f67f4d75657f801573ee0cb0 pr33256.c:23: warning: 'struct tcf_proto' declared inside parameter list pr33256.c:23: warning: its scope is only this definition or declaration, which is probably not what you want pr33256.c:24: warning: 'struct tcf_pkt_info' declared inside parameter list pr33256.c:24: warning: 'struct sk_buff' declared inside parameter list pr33256.c:25: warning: 'struct tcf_proto' declared inside parameter list pr33256.c:26: warning: 'struct sk_buff' declared inside parameter list pr33256.c:46: warning: 'struct tcf_pkt_info' declared inside parameter list pr33256.c:46: warning: 'struct sk_buff' declared inside parameter list pr33256.c:53: warning: 'struct tcf_pkt_info' declared inside parameter list pr33256.c:53: warning: 'struct sk_buff' declared inside parameter list pr33256.c:59: warning: initialization from incompatible pointer type pr33256.c:66: warning: 'struct tcf_pkt_info' declared inside parameter list pr33256.c:66: warning: 'struct sk_buff' declared inside parameter list pr33256.c:70: warning: 'struct tcf_pkt_info' declared inside parameter list pr33256.c:70: warning: 'struct sk_buff' declared inside parameter list pr33256.c: In function 'em_meta_match': pr33256.c:74: warning: passing argument 1 of 'meta_get' from incompatible pointer type pr33256.c:74: warning: passing argument 2 of 'meta_get' from incompatible pointer type pr33256.c:75: warning: passing argument 1 of 'meta_get' from incompatible pointer type pr33256.c:75: warning: passing argument 2 of 'meta_get' from incompatible pointer type pr33256.c: At top level: pr33256.c:79: warning: 'struct tcf_proto' declared inside parameter list pr33256.c:82: warning: 'struct tcf_proto' declared inside parameter list pr33256.c:85: warning: 'struct sk_buff' declared inside parameter list pr33256.c:89: warning: initialization from incompatible pointer type pr33256.c:89: warning: initialization from incompatible pointer type pr33256.c:90: warning: initialization from incompatible pointer type pr33256.c:90: warning: initialization from incompatible pointer type pr33256.c:92: warning: excess elements in struct initializer pr33256.c:92: warning: (near initialization for 'em_meta_ops.link') pr33256.c:94: warning: excess elements in struct initializer pr33256.c:94: warning: (near initialization for 'em_meta_ops.link') COMPILER_PATH=/home/ddaney/gccsvn/trunk-build/gcc/ LIBRARY_PATH=/home/ddaney/gccsvn/trunk-build/gcc/:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-B/home/ddaney/gccsvn/trunk-build/gcc/' '-v' '-S' '-mabi=64' '-msym32' '-mno-abicalls' '-O2' '-march=sb1' '-mno-shared' Same results with -O instead of -O2 gcc version 4.2.0 20060619 (experimental) does not ICE for me with the same command line either. Next I will try it on my mips64-linux cross compiler...
OK I can reproduce with my mips64-linux cross compiler. I wonder if it is big-endian related...
Here is what is happening: The value of avenrun[0] is being passed to a function that takes an 32 bit int parameter. Since avenrun is an array of 64 bit unsigned long, the conversion to int can be done by loading an int from avenrun + 4. In mips_symbolic_constant_p() we call offset_within_block_p(avenrun, 4) which returns false because avenrun is an array of undetermined length. If the length turns out to be zero, then an offset of 4 would fall outside of the array. I don't really know how to fix this. We could get rid of the offset_within_block_p() check all together (which could cause undiagnosed bad code in other circumstances), or we could assume that if symbol is an array, and the offset falls in the first element that it is OK. Perhaps Richard will have some ideas here...
Created attachment 14154 [details] Reduced testcase.
Fixing things up when we are calculating relocations does not seem like it will work. We cannot go adding an offest to a %lo() relocation and expect it not to overflow on occasion. Probably we need to load the value into a register and handle the casting there, as is done at -O0.
Created attachment 14155 [details] Proposed patch David, thanks for the analysis and reduced testcase. Re comment #7: I agree that we can't drop the offset_within_block_p check entirely. However (re comment #9) adjust_address_1 is actually making a legitimate optimisation here. It is given a memory that is known to be 8-byte-aligned, so it knows that adding 4 to the LO_SUM will not induce a carry. The problem is that the mips_classify_address has no access to that information; all it sees is the narrowed MEM. This PR is related to: http://thread.gmane.org/gmane.comp.gcc.patches/139565/focus=140004 I still think the final fix in that thread: http://gcc.gnu.org/viewcvs/trunk/gcc/config/mips/mips.c?r1=124833&r2=124832&pathrev=124833 was the right one for that bug because we always have access to a TLS's decl, so we can apply suitably small offsets to HIGHs as well as LO_SUMs. However, although we do have access to decl in the testcase for this PR, we won't for all (non-TLS) %hi/%los, so a similar fix won't work here. I think we have to trust the creator of the LO_SUM to do something vaguely sane. Target-independent code that creates a LO_SUM should also create and verify the associated HIGH, which must use the same symbol as the LO_SUM. Target-independent code that adds an offset to a LO_SUM should prove that the offset will not induce a carry. Failure to do either of these things would be a bug. And the MIPS backend should only create LO_SUMs for valid symbolic constants, with the high part being either a HIGH or a copy of _gp. So I'm wondering about the attached patch. Note that the lo_sum mips.md patterns are already OK, because they use immediate_operand. Richard
I am bootstrapping the 'Proposed patch' on mipsel-linux with this test case added: ------------------------------------ /* { dg-do compile } */ /* { dg-mips-options "-O2 -EB -mabi=64 -msym32 -mno-abicalls -march=mips64" } */ extern unsigned long a[]; int b(int x); int c() { return b(a[0]); } ------------------------------
Created attachment 14160 [details] 4.2 patch I've now regression-tested the original patch for mipsisa32r2-sde-elf. I've also regression-tested the attached patch for mips64-elf on 4.2 and 4.1. (The 4.2 version includes the testcase I used for all three runs. I've not forced -EB because that fails for -EL multilibs, and we want this test to work for both anyway.) I'll wait for David's results too and commit if all is well.
Subject: Re: internal compiler error: in print_operand_reloc, at config/mips/mips.c:5579 rsandifo at gcc dot gnu dot org wrote: > I've not forced -EB because that fails for -EL > multilibs, and we want this test to work for both anyway.) > Are you sure? On the trunk I tested on mipsel-linux with -EB and it seems to work. For a compile only test it should work on little-endian system. David Daney
Subject: Re: internal compiler error: in print_operand_reloc, at config/mips/mips.c:5579 "ddaney at avtrex dot com" <gcc-bugzilla@gcc.gnu.org> writes: >> I've not forced -EB because that fails for -EL >> multilibs, and we want this test to work for both anyway.) >> > Are you sure? On the trunk I tested on mipsel-linux with -EB and it > seems to work. For a compile only test it should work on little-endian > system. I mean that it fails if you explicitly test -EL multilibs. E.g. on mipsisa64-elf, I normally test "mips-sim{,-msoft-float}{-EB,-EL}", and the compiler will complain at having both -EL and -EB on the command line. We could make mips.exp skip the test when -EL is forced, but it seems more useful to run it regardless. Or we could use target selectors to select between two dg-mips-options lines depending on whether -EL has been added to the multilib flags. However, it seems odd to test big-endian (only) on little-endian systems when -EL is not explicitly given, but test little-endian when -EL _is_ explicitly (and redundantly) given. Richard
Subject: Re: internal compiler error: in print_operand_reloc, at config/mips/mips.c:5579 richard at codesourcery dot com wrote: > ------- Comment #14 from richard at codesourcery dot com 2007-09-05 21:08 ------- > Subject: Re: internal compiler error: in print_operand_reloc, at > config/mips/mips.c:5579 > > "ddaney at avtrex dot com" <gcc-bugzilla@gcc.gnu.org> writes: >>> I've not forced -EB because that fails for -EL >>> multilibs, and we want this test to work for both anyway.) >>> >> Are you sure? On the trunk I tested on mipsel-linux with -EB and it >> seems to work. For a compile only test it should work on little-endian >> system. > > I mean that it fails if you explicitly test -EL multilibs. E.g. on > mipsisa64-elf, I normally test "mips-sim{,-msoft-float}{-EB,-EL}", and > the compiler will complain at having both -EL and -EB on the command line. > We could make mips.exp skip the test when -EL is forced, but it seems > more useful to run it regardless. Or we could use target selectors to > select between two dg-mips-options lines depending on whether -EL has > been added to the multilib flags. However, it seems odd to test > big-endian (only) on little-endian systems when -EL is not explicitly > given, but test little-endian when -EL _is_ explicitly (and redundantly) > given. > My concern was that the bug only occurs for me with -EB, so running the test case with -EL would be pointless. I understand that you do most of your testing on the simulator, but for someone doing testing on little endian hardware there is no coverage without the -EB. David Daney
Subject: Re: internal compiler error: in print_operand_reloc, at config/mips/mips.c:5579 "ddaney at avtrex dot com" <gcc-bugzilla@gcc.gnu.org> writes: > My concern was that the bug only occurs for me with -EB, so running the > test case with -EL would be pointless. I understand that you do most of > your testing on the simulator, but for someone doing testing on little > endian hardware there is no coverage without the -EB. OK. As I said before, I didn't think it would be pointless, because we do want to make sure this continues to work for -EL too. (There's generally very little coverage of -mabi=64 -msym32; the only user I know of is linux.) However, I'll yield and make mips.exp skip the test when running explicitly-EL multilibs. Richard
Subject: Re: internal compiler error: in print_operand_reloc, at config/mips/mips.c:5579 richard at codesourcery dot com wrote: > ------- Comment #16 from richard at codesourcery dot com 2007-09-05 21:22 ------- > Subject: Re: internal compiler error: in print_operand_reloc, at > config/mips/mips.c:5579 > > "ddaney at avtrex dot com" <gcc-bugzilla@gcc.gnu.org> writes: >> My concern was that the bug only occurs for me with -EB, so running the >> test case with -EL would be pointless. I understand that you do most of >> your testing on the simulator, but for someone doing testing on little >> endian hardware there is no coverage without the -EB. > > OK. As I said before, I didn't think it would be pointless, because > we do want to make sure this continues to work for -EL too. The only time loading the low order bits of a word is done at an offset from the base of the word is in big endian. So I don't think it will ever fail on a little endian system, but I may be missing something. > (There's > generally very little coverage of -mabi=64 -msym32; the only user I know > of is linux.) However, I'll yield and make mips.exp skip the test when > running explicitly-EL multilibs. Thanks
Subject: Re: internal compiler error: in print_operand_reloc, at config/mips/mips.c:5579 "ddaney at avtrex dot com" <gcc-bugzilla@gcc.gnu.org> writes: > richard at codesourcery dot com wrote: >> ------- Comment #16 from richard at codesourcery dot com 2007-09-05 21:22 ------- >> Subject: Re: internal compiler error: in print_operand_reloc, at >> config/mips/mips.c:5579 >> >> "ddaney at avtrex dot com" <gcc-bugzilla@gcc.gnu.org> writes: >>> My concern was that the bug only occurs for me with -EB, so running the >>> test case with -EL would be pointless. I understand that you do most of >>> your testing on the simulator, but for someone doing testing on little >>> endian hardware there is no coverage without the -EB. >> >> OK. As I said before, I didn't think it would be pointless, because >> we do want to make sure this continues to work for -EL too. > > The only time loading the low order bits of a word is done at an offset > from the base of the word is in big endian. So I don't think it will > ever fail on a little endian system, but I may be missing something. Yes, I realise that, but I meant that you can't really assume very much about -mabi=64 -msym32 -EL at all from a mips{64,}{,-el}-linux-gnu run. At least allowing the test to be run in little-endian would have provided some coverage, and people were still going to notice if the -EB case regressed. Richard
On the trunk (with the patch) there are no regressions with a full bootstrap all default languages on mipsel-linux. The test cases passes also. I say: Commit it!
Subject: Bug 33256 Author: rsandifo Date: Thu Sep 6 17:46:43 2007 New Revision: 128195 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=128195 Log: gcc/ PR target/33256 * config/mips/mips.c (mips_classify_symbolic_expression): New function. (mips_classify_address): Use it instead of mips_symbolic_constant_p. (print_operand_reloc): Likewise. gcc/testsuite/ 200x-xx-xx David Daney <ddaney@avtrex.com> Richard Sandiford <richard@codesourcery.com> PR target/33256 * gcc.target/mips/mips.exp (setup_mips_tests): Set mips_forced_le. (dg-mips-options): Skip -EB and -meb tests when $mips_forced_le. * gcc.target/mips/pr33256.c: New test. Added: trunk/gcc/testsuite/gcc.target/mips/pr33256.c Modified: trunk/gcc/ChangeLog trunk/gcc/config/mips/mips.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gcc.target/mips/mips.exp
Subject: Bug 33256 Author: rsandifo Date: Thu Sep 6 18:04:51 2007 New Revision: 128197 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=128197 Log: gcc/ PR target/33256 * config/mips/mips.c (mips_classify_symbolic_expression): New function. (mips_classify_address): Use it instead of mips_symbolic_constant_p. (print_operand_reloc): Likewise. gcc/testsuite/ 200x-xx-xx David Daney <ddaney@avtrex.com> Richard Sandiford <richard@codesourcery.com> PR target/33256 * gcc.target/mips/mips.exp (setup_mips_tests): Set mips_forced_le. (dg-mips-options): Skip -EB and -meb tests when $mips_forced_le. * gcc.target/mips/pr33256.c: New test. Added: branches/gcc-4_2-branch/gcc/testsuite/gcc.target/mips/pr33256.c Modified: branches/gcc-4_2-branch/gcc/ChangeLog branches/gcc-4_2-branch/gcc/config/mips/mips.c branches/gcc-4_2-branch/gcc/testsuite/ChangeLog branches/gcc-4_2-branch/gcc/testsuite/gcc.target/mips/mips.exp
Subject: Bug 33256 Author: rsandifo Date: Thu Sep 6 18:06:51 2007 New Revision: 128198 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=128198 Log: gcc/ PR target/33256 * config/mips/mips.c (mips_classify_symbolic_expression): New function. (mips_classify_address): Use it instead of mips_symbolic_constant_p. (print_operand_reloc): Likewise. gcc/testsuite/ 200x-xx-xx David Daney <ddaney@avtrex.com> Richard Sandiford <richard@codesourcery.com> PR target/33256 * gcc.target/mips/mips.exp (setup_mips_tests): Set mips_forced_le. (dg-mips-options): Skip -EB and -meb tests when $mips_forced_le. * gcc.target/mips/pr33256.c: New test. Added: branches/gcc-4_1-branch/gcc/testsuite/gcc.target/mips/pr33256.c Modified: branches/gcc-4_1-branch/gcc/ChangeLog branches/gcc-4_1-branch/gcc/config/mips/mips.c branches/gcc-4_1-branch/gcc/testsuite/ChangeLog branches/gcc-4_1-branch/gcc/testsuite/gcc.target/mips/mips.exp
David, thanks for the testing. Fixed on mainline and both active release branches.