Original patch: http://gcc.gnu.org/ml/gcc-patches/2012-03/msg01695.html
'Tested' with.. ../gcc-4_7-branch/configure --target=sh-elf --prefix=/usr/local --enable-languages=c,c++ --enable-multilib --disable-libssp --disable-nls --disable-werror --enable-lto --with-newlib --with-gnu-as --with-gnu-ld --with-system-zlib make all OK for 4.7 branch? ChangeLog: Backport from mainline 2012-03-27 Chung-Lin Tang <clt...@codesourcery.com> PR target/52667 * config/sh/sh.c (find_barrier): Add equality check of last_got to avoid going above orig insn. Update comments.
Index: gcc/config/sh/sh.c =================================================================== --- gcc/config/sh/sh.c (revision 188026) +++ gcc/config/sh/sh.c (working copy) @@ -4720,9 +4720,12 @@ /* Don't emit a constant table int the middle of global pointer setting, since that that would move the addressing base GOT into another table. We need the first mov instruction before the _GLOBAL_OFFSET_TABLE_ - in the pool anyway, so just move up the whole constant pool. */ - if (last_got) - from = PREV_INSN (last_got); + in the pool anyway, so just move up the whole constant pool. + However, avoid doing so when the last single GOT mov is the starting + insn itself. Going past above the start insn would create a negative + offset, causing errors. */ + if (last_got && last_got != orig) + from = PREV_INSN (last_got); /* Don't insert the constant pool table at the position which may be the landing pad. */