I’ve fiddled a bit with GCC and read some code. No success yet, but here’s a status update.
AIUI, ‘strcpy’ declarations are immediately (in the front-end) recognized as “built-ins” as they are read (IOW, there’s no explicit conversion from function call to built-in call.) ‘__builtin_strcpy’ calls are then converted to ‘__builtin_memcpy’ calls (‘handle_builtin_strcpy’ in tree-ssa-strlen.c), which in turn leads to code that uses the ‘movabs’ instruction that’s causing us problems on x86: --8<---------------cut here---------------start------------->8--- $ echo 'extern char *strcpy(char*,const char*);void foo(char*x){ strcpy(x, "foo"); }'> t.c $ gcc -c -fdump-tree-optimized t.c $ cat t.c.211t.optimized ;; Function foo (foo, funcdef_no=0, decl_uid=1759, cgraph_uid=0, symbol_order=0) foo (char * x) { <bb 2>: __builtin_memcpy (x_2(D), "foo", 4); return; } --8<---------------cut here---------------end--------------->8--- (Strangely, when using ‘memcpy’ in the source, the ‘movabs’ optimization does not take place at -O0, unlike for ‘strcpy’.) So it seems there’s no place on the front-end side where we could do what I tried to do in my initial patch, which is to test the contents of the literal string passed to strcpy/memcpy and turn off the ‘movabs’-producing optimization. Instead, the knobs we have are (1) global flag to enable/disable each built-in function (like -fno-builtin-… does), and (2) an x86-specific knob to determine whether to use ‘movabs’ or not (‘-mmemcpy-strategy’ supposedly controls that, but ‘-mmemcpy-strategy=libcall:-1:noalign’ doesn’t seem to have any effect for instance.) These knobs are not great because that would lead us to disable the optimization wholesale, which is not desirable. Other than that, I’ve also looked at all the movabs-related things in gcc/config/i386/*.md, but to no avail. To be continued… Ludo’.