Hi, expand_set_or_movmem_prologue_epilogue_by_misaligned has
rtx saveddest = *destptr; gcc_assert (desired_align <= size); /* Align destptr up, place it to new register. */ *destptr = expand_simple_binop (GET_MODE (*destptr), PLUS, *destptr, GEN_INT (prolog_size), NULL_RTX, 1, OPTAB_DIRECT); *destptr = expand_simple_binop (GET_MODE (*destptr), AND, *destptr, GEN_INT (-desired_align), *destptr, 1, OPTAB_DIRECT); /* See how many bytes we skipped. */ saveddest = expand_simple_binop (GET_MODE (*destptr), MINUS, saveddest, *destptr, saveddest, 1, OPTAB_DIRECT); /* Adjust srcptr and count. */ if (!issetmem) *srcptr = expand_simple_binop (GET_MODE (*srcptr), MINUS, *srcptr, saveddest, *srcptr, 1, OPTAB_DIRECT); *count = expand_simple_binop (GET_MODE (saveddest), PLUS, *count, saveddest, *count, 1, OPTAB_DIRECT); For x32, adddress may be in SImode and count may be in DImode: (gdb) call debug_rtx (saveddest) (reg:SI 101) (gdb) call debug_rtx (*count) (reg:DI 100) (gdb) saveddest is a negative number and saveddest + count leads to overflow. Instead, we should use mode of saveddest. It is OK since count must be less than the size of address. Tested on x32. OK to install? Thanks x32. OK to install? Thanks. H.J. 2013-11-03 H.J. Lu <hongjiu...@intel.com> PR target/58981 * config/i386/i386.c (expand_set_or_movmem_prologue_epilogue_by_misaligned): Update count with mode of address. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 902e169..b27bfb6 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -23139,7 +23139,7 @@ expand_set_or_movmem_prologue_epilogue_by_misaligned_moves (rtx destmem, rtx src if (!issetmem) *srcptr = expand_simple_binop (GET_MODE (*srcptr), MINUS, *srcptr, saveddest, *srcptr, 1, OPTAB_DIRECT); - *count = expand_simple_binop (GET_MODE (*count), PLUS, *count, + *count = expand_simple_binop (GET_MODE (saveddest), PLUS, *count, saveddest, *count, 1, OPTAB_DIRECT); /* We copied at most size + prolog_size. */ if (*min_size > (unsigned HOST_WIDE_INT)(size + prolog_size))