Hi, Attached is a simple testcase from VLC.
At -O0 everything is fine: $ gcc-4.6 -S -O0 x.i $ grep memmove x.s call __memmove_chk At -O1 it incorrectly it is incorrectly changed to memcpy: $ gcc-4.6 -S -O1 x.i $ grep memcpy x.s call memcpy If I change the provided x.i, and remove the extern inline declaration of memmove, then memmove is no longer changed to memcpy! Also all is good with gcc-4.5: $ gcc-4.5 -S -O2 x.i $ grep memmove x.s call memmove Poking around in gcc-4.6 sources this place in gcc/builtins.c seems to be the place where memmove_chk -> memcpy conversion happens, I didn't verify that though: if (fcode == BUILT_IN_MEMMOVE_CHK) { unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT); if (src_align == 0) return NULL_RTX; /* If src is categorized for a readonly section we can use normal __memcpy_chk. */ if (readonly_data_expr (src)) { tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK]; Best regards, --Edwin
typedef long unsigned int size_t; extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__, __artificial__)) void * __attribute__ ((__nothrow__)) memmove (void *__restrict __dest, __const void *__restrict __src, size_t __len) { return __builtin___memmove_chk (__dest, __src, __len, __builtin_object_size (__dest, 0)); } typedef struct aout_instance_t aout_instance_t; typedef struct aout_input_t aout_input_t; struct aout_instance_t { aout_input_t * pp_inputs[5]; int i_nb_inputs; }; int aout_DecDelete( aout_instance_t * p_aout, aout_input_t * p_input ) { int i_input = p_aout->i_nb_inputs; memmove( &p_aout->pp_inputs[i_input], &p_aout->pp_inputs[i_input + 1], (5 - i_input - 1) * sizeof(aout_input_t *) ); }