I also confirmed this behavior with disassembly, and now I'm wondering what the basis of this optimization is. Can anyone explain the logic that gcc would have used to do this?
As a human, I can see that the loop has no effects except to increase s by 1 each of NUMBER times, and that the result of doing so would increase s by 1 * NUMBER, and that s started as 0, so s ends up as NUMBER. (Also the loop variable i is incremented NUMBER times so it ends up as NUMBER too, but its value is never referred to again.)
I'm wondering how the optimizer observed and represented these facts, and how much more general its attempts at optimizing this loop were.