https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64027
--- Comment #1 from Peter A. Bigot <pab at pabigot dot com> --- The following program: int request(); int release(); unsigned char execute (unsigned char arg); unsigned char safe_execute (unsigned char arg) { int rc; unsigned char rs = 0; rc = request(); if (0 == rc) { do { rs = execute(arg); } while(0); (void)release(); } return rs; } when compiled with msp430-elf-gcc -Os produces: 00000000 <safe_execute>: 0: 0a 15 pushm #1, r10 ;16-bit words 2: 4a 4c mov.b r12, r10 ; 4: 3a f0 ff 00 and #255, r10 ;#0x00ff 8: b0 12 00 00 call #0 ; a: R_MSP430X_ABS16 request c: 0c 93 cmp #0, r12 ;r3 As==00 e: 00 20 jnz $+2 ;abs 0x10 e: R_MSP430X_10_PCREL .L3 10: 4c 4a mov.b r10, r12 ; 12: b0 12 00 00 call #0 ; 14: R_MSP430X_ABS16 execute 16: 4a 4c mov.b r12, r10 ; 18: 3a f0 ff 00 and #255, r10 ;#0x00ff 1c: b0 12 00 00 call #0 ; 1e: R_MSP430X_ABS16 release 20: 30 40 00 00 br #0x0000 ; 22: R_MSP430X_ABS16 .L2 00000024 <.L3>: 24: 0a 43 clr r10 ; 00000026 <.L2>: 26: 4c 4a mov.b r10, r12 ; 28: 0a 17 popm #1, r10 ;16-bit words 2a: 30 41 ret Under mspgcc this produces: 00000000 <safe_execute>: 0: 0b 12 push r11 2: 4b 4f mov.b r15, r11 4: b0 12 00 00 call #0x0000 8: 0f 93 tst r15 a: 07 20 jnz $+16 ;abs 0x1a c: 4f 4b mov.b r11, r15 e: b0 12 00 00 call #0x0000 12: 4b 4f mov.b r15, r11 14: b0 12 00 00 call #0x0000 18: 01 3c jmp $+4 ;abs 0x1c 1a: 4b 43 clr.b r11 1c: 4f 4b mov.b r11, r15 1e: 3b 41 pop r11 20: 30 41 ret There are two things to be fixed here. First, in this code: 2: 4a 4c mov.b r12, r10 ; 4: 3a f0 ff 00 and #255, r10 ;#0x00ff the second instruction is unnecessary, because the mov.b guarantees the upper half of r10 will be zero. In general the msp430 target does not appear to take full advantage of the semantics of byte operands in MSP430. 8 bytes would be saved by eliminating this instruction in two places. Second, this sequence generated by msp430-elf: CALL #release BR #.L2 .L3: MOV.W #0, R10 .L2: should use a "jmp" instruction instead of a "br", saving two bytes.