https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109609
--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> --- Oh the problem is related to tail calls: strncpy (&dst, ptr_30, 23); [tail call] That should not be marked as a tail call as buf is still alive during the call of strncpy. Simple workaround, add asm("":::"memory"); Right before the end of invert. Or use -fno-optimize-sibling-calls Self contained testcase: ``` #define N 23 #define MAX_LEN 13 char dst[N + 1]; void invert(const char *id) { char buf[MAX_LEN]; char *ptr = buf + sizeof(buf); // start from the end of buf *(--ptr) = '\0'; // terminate string while (*id && ptr > buf) { *(--ptr) = *(id++); // copy id backwards } __builtin_strncpy(dst, ptr, N); // copy ptr/buf to dst // asm("":::"memory"); // This "fixes" the issue. } int main() { invert("abcde"); if (strcmp(dst, "edcba")) __builtin_abort(); } ```