http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49781
--- Comment #16 from Uros Bizjak <ubizjak at gmail dot com> 2011-08-04 18:49:32 UTC --- (In reply to comment #14) > /export/build/gnu/gcc-x32-test/release/usr/gcc-4.7.0-x32/bin/gcc -mx32 > -std=gnu99 -fgnu89-inline -O2 -S testcase.c > .... > testcase.c:634:2: internal compiler error: Segmentation fault > Please submit a full bug report, > with preprocessed source if appropriate. > See <http://gcc.gnu.org/bugs.html> for instructions. Sometimes, a subreg is returned as base or index register. This patch strips subregs and fixes ICE (I wonder, why the ICE didn't show earlier): Index: i386.c =================================================================== --- i386.c (revision 177411) +++ i386.c (working copy) @@ -14088,6 +14101,20 @@ gcc_assert (ok); + if (parts.base && GET_CODE (parts.base) == SUBREG) + { + rtx tmp = SUBREG_REG (parts.base); + parts.base = simplify_subreg (GET_MODE (parts.base), + tmp, GET_MODE (tmp), 0); + } + + if (parts.index && GET_CODE (parts.index) == SUBREG) + { + rtx tmp = SUBREG_REG (parts.index); + parts.index = simplify_subreg (GET_MODE (parts.index), + tmp, GET_MODE (tmp), 0); + } + base = parts.base; index = parts.index; disp = parts.disp; However, I think we should hanlde plus (zero_extend (...addr...)(const_int)) offsetable operands, too. Otherwise there will be no benefit for SSE operands...