I am having a problem with the Keil compiler not performing an optimization that looks trivial. I am using Keil 4.50. The issue can be reproduced with the following simple code:
extern int g(int arg1); extern int extint1; int f( int arg1) { int a; int b; a = g(arg1); b = (int) &extint1 + a - a + 10 -5; return b; }
When compiled with maximum optimization (O2 or O3), I would expect the compiler to optimize away the ‘a-a’ in the computation of b, but it doesn’t. When compiled with –O3 the result is
; generated by ARM C/C++ Compiler, 4.1 [Build 791] ; commandline ArmCC [--list --debug -c --asm --interleave -ocompileroptimization.o --asm_dir=.\ --list_dir=.\ --depend=compileroptimization.d --cpu=Cortex-M3 --apcs=interwork -O3 -IC:\Keil\ARM\CMSIS\Include -IC:\Keil\ARM\INC\STMicroelectronics --omf_browse=compileroptimization.crf CompilerOptimization.c] THUMB AREA ||.text||, CODE, READONLY, ALIGN=2 f PROC ;;;3 ;;;4 int f( int arg1) 000000 b510 PUSH {r4,lr} ;;;5 { ;;;6 int a; ;;;7 int b; ;;;8 ;;;9 a = g(arg1); 000002 f7fffffe BL g ;;;10 b = (int) &extint1 + a - a + 10 -5; 000006 4902 LDR r1,|L1.16| 000008 4401 ADD r1,r1,r0 00000a 1a08 SUBS r0,r1,r0 00000c 1d40 ADDS r0,r0,#5 ;;;11 ;;;12 return b; ;;;13 } 00000e bd10 POP {r4,pc} ENDP |L1.16| DCD extint1
Note the ADD r1,r1,r0 immediately followed by the SUBS r0,r1,r0; not what I expect from an optimizer. Without the presence of extint1, the compiler optimizes correctly. The trivial answer is of course not to write code that does ‘a-a’, but that is not a realistic option in my project. I need to rely on the compiler to optimize this code.
Does anyone have an idea on why the compiler behaves like this and how I can let it optimize this correctly?