https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70677
--- Comment #5 from Georg-Johann Lay <gjl at gcc dot gnu.org> --- Maybe -fno-caller-saves is what you are looking for? Here is a C test case guessed from your first code snipped: typedef struct { unsigned char x, y; } point; extern void printSpeed (long, unsigned char); extern long cnvGroundSpeed (void); void panVel (point p) { printSpeed (cnvGroundSpeed(), p.y & 0x40); } compiled with avr-gcc 5.x $ avr-gcc -S -Os we'll get panVel: push r28 push r29 push __zero_reg__ in r28,__SP_L__ in r29,__SP_H__ mov r20,r25 andi r20,lo8(64) std Y+1,r20 rcall cnvGroundSpeed ldd r20,Y+1 pop __tmp_reg__ pop r29 pop r28 rjmp printSpeed Adding -fno-caller-saves: panVel: push r28 mov r28,r25 andi r28,lo8(64) rcall cnvGroundSpeed mov r20,r28 pop r28 rjmp printSpeed I actually don't know whether this is a flaw in the avr backend (like a cost issue) or wrong assumptions in the middle-end. Saving / Restoring in the frame is actually not more costly than saving in a call-saved register; what makes it expensive is the frame setup in prologue and epilogue...