https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93487
Bug ID: 93487 Summary: Missed tail-call optimizations Product: gcc Version: 9.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: pskocik at gmail dot com Target Milestone: --- Given, for example: #include <stdint.h> typedef union lp_tp { long l; void *p; } lp_tp ; typedef union ilp_tp{ int i; long l; void *p; lp_tp lp; } ilp_tp; long lcallee(void); int icallee(void); void *pcallee(void); lp_tp lpcallee(void); //tail calls on clang but not on gcc int l2i(void){ return lcallee(); } ilp_tp l_caller(void) { long rc = lcallee(); return (ilp_tp){.l=rc}; } ilp_tp p_caller(void) { void *rc= pcallee(); return (ilp_tp){.p=rc}; } ilp_tp lp_caller(void) { lp_tp rc = lpcallee(); return (ilp_tp){.lp = rc}; } ilp_tp lp_caller2(void) { lp_tp rc = lpcallee(); return (ilp_tp){.p = rc.p}; } struct foo* p2p_caller(void) { return pcallee(); } //optimized on both uintptr_t p2up_caller(void) { return (uintptr_t)pcallee(); } //optimized on both //not optimized by either ilp_tp i_caller(void) { int rc = icallee(); ilp_tp r; r.i=rc; return r; } clang (x86_64) is able to turn all of these calls except the last one into tail calls but gcc tailcall-optimizes only the pointer-to-pointer conversions. https://gcc.godbolt.org/z/Lw9-D2