https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113293
Bug ID: 113293 Summary: Incorrect code after inlining function containing extended asm Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: ipa Assignee: unassigned at gcc dot gnu.org Reporter: dories.spirits_0p at icloud dot com CC: marxin at gcc dot gnu.org Target Milestone: --- GCC compiles the following code (with -O3 -std=gnu2x): #include <stdint.h> #define SYSCALL_GETCHAR 1 #define SYSCALL_THREAD_CREATE 2 typedef void (*thread_func)(void *); static inline char getc() { register char r0 asm("r0"); asm volatile ("svc %[syscall]" : "=r" (r0) : [syscall] "i" (SYSCALL_GETCHAR) : "r1", "r2", "r3"); return r0; } static inline void thread_create(thread_func func, const void * args, uint32_t args_size) { register uint32_t r0 asm("r0") = (uint32_t) func; register uint32_t r1 asm("r1") = (uint32_t) args; register uint32_t r2 asm("r2") = args_size; asm volatile ("svc %[syscall]" : "+r" (r0), "+r" (r1), "+r" (r2) : [syscall] "i" (SYSCALL_THREAD_CREATE), "r" (r0), "r" (r1), "r" (r2) : "r3"); } void worker([[maybe_unused]] void *x) {} void main() { while (true) { char arg = getc(); thread_create(worker, &arg, sizeof(arg)); } } into something like main: movw ip, #:lower16:worker sub sp, sp, #8 movt ip, #:upper16:worker .L4: svc #1 //char getc() mov r2, #1 mov r0, ip //return value of 'getc' svc call overwritten add r1, sp, #7 //nothing in the stack here! svc #2 b .L4 The return value of 'getc' is overwritten/not stored on the stack with -O1 and higher (-Og and -O0 are not affected). I've tested on a local copy of arm-none-eabi-gcc 10.2.0 as well as arm gcc trunk (arm-unknown-linux-gnueabihf 14.0.0 20240108) on compiler explorer. I've also tested clang 17 targeting arm-none-eabi, which correctly stores the result of the 'getc' svc call on the stack in all optimization levels: .LBB1_1: svc #1 strb r0, [sp, #3] [...] ARM GCC trunk and Clang trunk: https://godbolt.org/z/ercEYfacM If 'getc' is marked noinline, r0 is correctly saved to the stack: .L5: bl getc strb r0, [sp, #7] //saved to stack add r1, sp, #7 [...] svc #2 b .L5 With [[gnu::noinline]] https://godbolt.org/z/ETManW1hY This is my first bug, so please let me know if there's anything else I need to provide.