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.