I compile this with gcc -O1
:
#include <stdint.h>struct mystruct{ uint32_t arr[1]; uint32_t something_after_arr;};uint32_t sum1(const struct mystruct *s,uintptr_t n){ uint32_t result=0; for(uintptr_t i=0;i<n;++i)result+=s->arr[i]; return result;}uint32_t sum2(const struct mystruct *s,uintptr_t n){ uint32_t result=0; for(uintptr_t i=0;i<n;++i)result+=i[s->arr]; return result;}uint32_t sum3(const struct mystruct *s,uintptr_t n){ uint32_t result=0; for(uintptr_t i=0;i<n;++i)result+=*(s->arr+i); return result;}
compiler (https://godbolt.org/#…) generated this x86_64 assembly (assembler directives removed):
sum1: mov eax, 0 test rsi, rsi je .L1 mov eax, DWORD PTR [rdi].L1: retsum2: mov eax, 0 test rsi, rsi je .L4 mov eax, DWORD PTR [rdi].L4: retsum3: test rsi, rsi je .L10 mov eax, 0 mov edx, 0.L9: add edx, DWORD PTR [rdi+rax*4] add rax, 1 cmp rsi, rax jne .L9.L7: mov eax, edx ret.L10: mov edx, 0 jmp .L7
Only sum3
has backwards jumps. sum1
and sum2
only have forward jump (which means no looping).
Why are sum3
and sum1
different and why no loop in sum1
?
I expected sum1
and sum2
and sum3
have same code with loop (like clang (https://godbolt.org/#…)).