На более низких уровнях оптимизации или с -fno-strict-aliasing компилятором
добавляет инструкцию movsbl (% rsi),% eax внутри тела цикла.
Не на более низких уровнях оптимизации.
Ваш пример неверен, так как функция сконструирована таким образом, чтобы вызывать UB, поскольку вы забыли о побочных эффектах этого наказания. В этом случае - если вы знаете, что значение перфорированного объекта может быть изменено программой невидимым для компилятора способом, вам следует использовать ключевое слово volatile. Вы только что сделали типичную изменчивую ошибку.
Эта функция просто плохо написана. Автор, зная, что он подвержен побочным эффектам - просто проигнорировал это. Это неправильно с указателем или без него.
typedef struct
{
char a;
} my_struct;
my_struct a, b[100];
void foo( int * a, my_struct * b, int count )
{
int i;
for (i=0;i<count;i++)
{
a[i] += b->a;
}
}
void foo1( int * a, volatile my_struct * b, int count )
{
int i;
for (i=0;i<count;i++)
{
a[i] += b->a;
}
}
void call1(void)
{
int *v = (int *)b;
foo(v, &b[0], 100);
}
void call2(void)
{
foo((int *)b, b, 100);
}
void call3(void)
{
int *v = (int *)b;
foo1(v, &b[0], 100);
}
void call4(void)
{
foo1((int *)b, b, 100);
}
И скомпилированный код.
foo: # @foo
test edx, edx
jle .LBB0_3
movsx eax, byte ptr [rsi]
mov ecx, edx
.LBB0_2: # =>This Inner Loop Header: Depth=1
add dword ptr [rdi], eax
add rdi, 4
add rcx, -1
jne .LBB0_2
.LBB0_3:
ret
foo1: # @foo1
test edx, edx
jle .LBB1_3
mov eax, edx
.LBB1_2: # =>This Inner Loop Header: Depth=1
movsx ecx, byte ptr [rsi]
add dword ptr [rdi], ecx
add rdi, 4
add rax, -1
jne .LBB1_2
.LBB1_3:
ret
call1: # @call1
mov rax, -400
movsx ecx, byte ptr [rip + b]
.LBB2_1: # =>This Inner Loop Header: Depth=1
add dword ptr [rax + b+400], ecx
add rax, 4
jne .LBB2_1
ret
call2: # @call2
mov rax, -400
movsx ecx, byte ptr [rip + b]
.LBB3_1: # =>This Inner Loop Header: Depth=1
add dword ptr [rax + b+400], ecx
add rax, 4
jne .LBB3_1
ret
call3: # @call3
mov rax, -400
.LBB4_1: # =>This Inner Loop Header: Depth=1
movsx ecx, byte ptr [rip + b]
add dword ptr [rax + b+400], ecx
add rax, 4
jne .LBB4_1
ret
call4: # @call4
mov rax, -400
.LBB5_1: # =>This Inner Loop Header: Depth=1
movsx ecx, byte ptr [rip + b]
add dword ptr [rax + b+400], ecx
add rax, 4
jne .LBB5_1
ret