On ARM target when the compiler can deduce that the result of a calculation is a constant, it always substitutes the calculation with the constant, even if loading the constant is more expensive (both in code size and execution time) than the actual calculation.
I attach a file that contains two short C functions. They do exactly the same, but foo() processes a constant while bar() processes its argument. Compiling the code with -Os, -O2 or -O3 results in code where processing the argument is much shorter and faster than processing the constant. In particular, processing the variable argument generates code (the same assembly is generated for -Os and -O3) that is 7 words long and executes in 14 clocks. Using -Os, the function processing a constant generates a 10 word, 25 clock assembly while -O2 or -O3 creates a 17 words, 24 clock code. That is, when a constant is given instead of a variable parameter, the generated code is 40% longer and 79% slower for -Os and 143% longer and 71% slower with -O3. Adding the load of the constant to the beginning of the variable argument version of the code would cost 1 word, 1 clock if the peephole optimiser was clever enough and 2 words, 3 clocks in the worst case. Nowhere near the 3 words, 11 clocks (-Os) or 10 words, 10 clocks (-O2,-O3) cost the compiler generated. The command line used was: arm-aebi-gcc-4.4.0 -S -O[s23] constant.c -- Summary: Calculated values replaced with constants even if he constants cost more than the calculations Product: gcc Version: 4.4.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: zoltan at bendor dot com dot au GCC host triplet: i386-elf-linux GCC target triplet: arm-eabi-unknown http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39469