http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49781
--- Comment #11 from H.J. Lu <hjl.tools at gmail dot com> 2011-08-03 15:44:59 UTC --- (In reply to comment #10) > This additional patch prevents zero_extend when we deal with > wider-than-word-size moves. These moves need offsetable_operand, which > zero_extend (...) isn't. > > Index: i386.c > =================================================================== > --- i386.c (revision 177281) > +++ i386.c (working copy) > @@ -11681,6 +11689,10 @@ ix86_legitimate_address_p (enum machine_ > rtx base, index, disp; > HOST_WIDE_INT scale; > > + if (GET_CODE (addr) == ZERO_EXTEND > + && GET_MODE_SIZE (mode) > UNITS_PER_WORD) > + return false; > + > if (ix86_decompose_address (addr, &parts) <= 0) > /* Decomposition failed. */ > return false; gcc.dg/torture/pr47744-2.c compiled with -mx32 -O3 -std=gnu99 -ftree-vectorize -funroll-loops generates codes like leal (%rax,%r9), %r12d leal (%rax,%rdi), %r10d mov %r12d, %edx movq (%r12d), %rbp movq 8(%rdx), %rdx movq (%r12d), %rax Many leal aren't necessary.