The compiler recognizes that the loop does nothing and that deleting it will not change the output of the program, therefore the loop is fully optimized.
Here's the assembly with -O0 :
.L3: .loc 1 4 0 is_stmt 0 discriminator 3 addl $1, -4(%rbp) .L2: .loc 1 4 0 discriminator 1 cmpl $999999999, -4(%rbp) # loop jle .L3 .loc 1 5 0 is_stmt 1 movl -4(%rbp), %eax movl %eax, %esi movl $.LC0, %edi movl $0, %eax call printf movl $0, %eax .loc 1 6 0 leave .cfi_def_cfa 7, 8 ret
And with -O3 :
main: .LFB23: .file 1 "x1.c" .loc 1 2 0 .cfi_startproc .LVL0: subq $8, %rsp .cfi_def_cfa_offset 16 .LBB4: .LBB5: .file 2 "/usr/include/x86_64-linux-gnu/bits/stdio2.h" .loc 2 104 0 movl $1000000000, %edx # stored value, no loop movl $.LC0, %esi movl $1, %edi xorl %eax, %eax call __printf_chk .LVL1: .LBE5: .LBE4: .loc 1 6 0 xorl %eax, %eax addq $8, %rsp .cfi_def_cfa_offset 8 ret
You can see that in the case of -O3 cycle is completely deleted, and the final value of i , 1,000,000,000 is saved directly.
source share