https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116677
Bug ID: 116677 Summary: ARM: Incorrect code generated when testing value of returned struct Product: gcc Version: 13.3.0 URL: https://gcc.godbolt.org/z/j3e51Y3TW Status: UNCONFIRMED Keywords: wrong-code Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: wvangulik at xs4all dot nl Target Milestone: --- Target: arm Given the following code: struct sockaddr_storage { char offset[4]; int sin_addr; }; struct sockaddr_in { char offset[4]; int sin_addr; }; struct a { char offset[8]; struct sockaddr_storage c; }; struct sockaddr_storage str_to_ip(); static inline int isany(const struct sockaddr_storage *ip_addr) { return (((struct sockaddr_in*)ip_addr)->sin_addr == 0); } static inline int isany_nocast(const struct sockaddr_storage *ip_addr) { return ip_addr->sin_addr == 0; } int failing(struct a *p) { // inline function isany is mixedup with the return of str_to_ip p->c = str_to_ip(); return isany(&p->c); } int correct(struct a *p) { // Using a local stack variable forces the compiler to use the returned structure struct sockaddr_storage c = str_to_ip(); p->c = c; return isany(&c); } Compiled on Godbolt ARM GCC 13.3.0 and -O2. Tried several other version on Godbolt GCC 5 (!) is the last one that is correct. It generates: failing: push {r4, r5, lr} mov r4, r0 sub sp, sp, #12 mov r5, sp mov r0, r5 <= Setup r0 for the returned struct bl str_to_ip add r3, r4, #8 <= setup r3 to 'p->c' ldr r2, [r4, #12] <==== Incorrect!! 'p->c' is not yet updated ldm r5, {r0, r1} <= copy struct-on-stack to registers stm r3, {r0, r1} <= copy registers back to 'p->c'. 'p->c' is now updated clz r0, r2 lsrs r0, r0, #5 add sp, sp, #12 pop {r4, r5, pc} correct: push {r4, r5, lr} mov r4, r0 sub sp, sp, #12 mov r5, sp mov r0, r5 bl str_to_ip add r3, r4, #8 ldr r2, [sp, #4] <== this is correct, sp+4 contains returned object ldm r5, {r0, r1} stm r3, {r0, r1} clz r0, r2 lsrs r0, r0, #5 add sp, sp, #12 pop {r4, r5, pc} Some additional info: The cast is part of the problem. Removing the cast fixes the problem. It is very fragile. In our production code it compiles some places correct and at least one incorrect.