------- Comment #5 from guillaume dot melquiond at ens-lyon dot fr 2006-04-16 18:15 ------- I have tried to look at why it fails. Here are my observations. The function gcc/expr.c:emit_block_move tries to expand a movmem pattern. The backend refuses, since a call to memcpy would be a lot more efficient. So emit_block_move tries to generate memcpy but block_move_libcall_safe_for_call_parm says this is not safe. The only thing left is calling emit_block_move_via_loop, and it generates some really dumb code.
Whenever there is -Os or -mtune=i386 or -mregparm=3, the function block_move_libcall_safe_for_call_parm says memcpy is safe. Otherwise it fails because arguments are neither pushed nor passed through registers but stored at the top of the stack. Failing then seems to be the right thing to do, since the call to memcpy will otherwise overwrite its own argument stack. Assuming memcpy is the right thing to do, emit_block_move should allocate a bit of stack space for memcpy instead of refusing to call it (and hence falling back to a loop move). -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27055