optimizing for loops Disclaimer: I'm not a compiler expert.  I'm simply curious and come seeking enlightenment.
I've seen people claim that -- for efficiency -- for loops should generally use a zero comparison for termination.  So rather than:
void blink1(int n) {
    for (int i=0; i&lt;n; i++) {
        blink_led();
    }
}

you should write:
void blink2(int n) {
    for (int i=n; i&gt;0; i--) {
        blink_led();
    }
}

I thought that was a little silly: why put the burden on the human if a compiler could interpret both cases as &quot;blink_led() n times&quot;?
But using Mr. Godbolt's Compiler Explorer, I now think I'm wrong.  For all the compilers I tried, the &quot;compare against zero&quot; always produced a shorter loop.  For example, x86-64 gcc 10.2 with -O3 optimization produced the following inner loops:
blink1:
    ...
.L3:
        xor     eax, eax
        add     ebx, 1
        call    blink_led
        cmp     ebp, ebx
        jne     .L3

vs
blink2:
    ...
.L12:
        xor     eax, eax
        call    blink_led
        sub     ebx, 1
        jne     .L12

So here's the question
This seems like such a common case.
Why can't (or why doesn't) the compiler notice that the effect of the for loop is simply &quot;do this thing N times&quot; -- whether counting up or counting down -- and optimize for that?
What you read is total nonsense, except for the most primitive of compilers. First, comparison with an integer is as fast, possibly even faster than comparison with a constant. Second, a good optimising compiler will take a loop written using some common pattern and turn it into the best possible code; it may not recognise your obfuscated pattern and produce less good code for it.
And lastly, you shouldn’t replace readable with unreadable code unless there is an actual need for it. If you spend an hour making the change, it needs to produce 20 hours saved CPU time at least. When you are at that level, better algorithms are very likely to give better savings.