void image_char2double(int num_data, unsigned char data_image_char[][784],
                       double data_image[][784]) {
  int i, j;
  for (i = 0; i < num_data; i++)
    for (j = 0; j < 784; j++)
      data_image[i][j] = (double)data_image_char[i][j] / 255.0;
}


x86 assembly (clang, -O0):
<image_char2double>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
movl   $0x0,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    119c <image_char2double+0x9c>
movl   $0x0,-0x20(%rbp)
cmpl   $0x310,-0x20(%rbp)
jge    1189 <image_char2double+0x89>
mov    -0x10(%rbp),%rcx
movslq -0x1c(%rbp),%rax
imul   $0x310,%rax,%rax
add    %rax,%rcx
movslq -0x20(%rbp),%rax
movzbl (%rax,%rcx,1),%eax
cvtsi2sd %eax,%xmm0
movsd  0xea4(%rip),%xmm1
divsd  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
imul   $0x1880,%rcx,%rcx
add    %rcx,%rax
movslq -0x20(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    1129 <image_char2double+0x29>
jmp    118e <image_char2double+0x8e>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1116 <image_char2double+0x16>
pop    %rbp
ret

x86 assembly (clang, -O2):
<image_char2double>:
push   %r15
push   %r14
push   %rbx
test   %edi,%edi
jle    1242 <image_char2double+0x142>
mov    %edi,%r8d
lea    0x2(%rsi),%r9
lea    0x10(%rdx),%r11
lea    0x1(%rsi),%rax
lea    0x8(%rdx),%rcx
xor    %r10d,%r10d
movsd  0xee5(%rip),%xmm0
pxor   %xmm1,%xmm1
movapd 0xec9(%rip),%xmm2
jmp    1168 <image_char2double+0x68>
nopl   0x0(%rax)
add    $0x1,%r10
add    $0x310,%r9
add    $0x1880,%r11
add    $0x310,%rax
add    $0x1880,%rcx
cmp    %r8,%r10
je     1242 <image_char2double+0x142>
imul   $0x310,%r10,%rdi
lea    (%rsi,%rdi,1),%r14
add    $0x310,%r14
imul   $0x1880,%r10,%r15
lea    (%rdx,%r15,1),%rbx
cmp    %rbx,%r14
jbe    11e0 <image_char2double+0xe0>
add    %rsi,%rdi
lea    (%rdx,%r15,1),%rbx
add    $0x1880,%rbx
cmp    %rbx,%rdi
jae    11e0 <image_char2double+0xe0>
xor    %edi,%edi
nop
movzbl -0x1(%rax,%rdi,1),%ebx
xorps  %xmm3,%xmm3
cvtsi2sd %ebx,%xmm3
divsd  %xmm0,%xmm3
movsd  %xmm3,-0x8(%rcx,%rdi,8)
movzbl (%rax,%rdi,1),%ebx
xorps  %xmm3,%xmm3
cvtsi2sd %ebx,%xmm3
divsd  %xmm0,%xmm3
movsd  %xmm3,(%rcx,%rdi,8)
add    $0x2,%rdi
cmp    $0x310,%rdi
jne    11a0 <image_char2double+0xa0>
jmp    1140 <image_char2double+0x40>
nopl   0x0(%rax)
xor    %edi,%edi
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movzwl -0x2(%r9,%rdi,1),%ebx
movd   %ebx,%xmm3
punpcklbw %xmm1,%xmm3
punpcklwd %xmm1,%xmm3
cvtdq2pd %xmm3,%xmm3
divpd  %xmm2,%xmm3
movupd %xmm3,-0x10(%r11,%rdi,8)
movzwl (%r9,%rdi,1),%ebx
movd   %ebx,%xmm3
punpcklbw %xmm1,%xmm3
punpcklwd %xmm1,%xmm3
cvtdq2pd %xmm3,%xmm3
divpd  %xmm2,%xmm3
movupd %xmm3,(%r11,%rdi,8)
add    $0x4,%rdi
cmp    $0x310,%rdi
jne    11f0 <image_char2double+0xf0>
jmp    1140 <image_char2double+0x40>
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
define void @image_char2double(i32 %0, [784 x i8]* %1, [784 x double]* %2) {
%4 = alloca i32
%5 = alloca [784 x i8]*
%6 = alloca [784 x double]*
%7 = alloca i32
%8 = alloca i32
store i32 %0, i32* %4
store [784 x i8]* %1, [784 x i8]** %5
store [784 x double]* %2, [784 x double]** %6
store i32 0, i32* %7
br label %9
9: ; preds = %39, %3
%10 = load i32, i32* %7
%11 = load i32, i32* %4
%12 = icmp slt i32 %10, %11
br i1 %12, label %13, label %42
13: ; preds = %9
store i32 0, i32* %8
br label %14
14: ; preds = %35, %13
%15 = load i32, i32* %8
%16 = icmp slt i32 %15, 784
br i1 %16, label %17, label %38
17: ; preds = %14
%18 = load [784 x i8]*, [784 x i8]** %5
%19 = load i32, i32* %7
%20 = sext i32 %19 to i64
%21 = getelementptr inbounds [784 x i8], [784 x i8]* %18, i64 %20
%22 = load i32, i32* %8
%23 = sext i32 %22 to i64
%24 = getelementptr inbounds [784 x i8], [784 x i8]* %21, i64 0, i64 %23
%25 = load i8, i8* %24
%26 = uitofp i8 %25 to double
%27 = fdiv double %26, 2.550000e+02
%28 = load [784 x double]*, [784 x double]** %6
%29 = load i32, i32* %7
%30 = sext i32 %29 to i64
%31 = getelementptr inbounds [784 x double], [784 x double]* %28, i64 %30
%32 = load i32, i32* %8
%33 = sext i32 %32 to i64
%34 = getelementptr inbounds [784 x double], [784 x double]* %31, i64 0, i64 %33
store double %27, double* %34
br label %35
35: ; preds = %17
%36 = load i32, i32* %8
%37 = add nsw i32 %36, 1
store i32 %37, i32* %8
br label %14
38: ; preds = %14
br label %39
39: ; preds = %38
%40 = load i32, i32* %7
%41 = add nsw i32 %40, 1
store i32 %41, i32* %7
br label %9
42: ; preds = %9
ret void
}

LLVM IR (-O2):
define void @image_char2double(i32 %0, [784 x i8]* nocapture %1, [784 x double]* nocapture writeonly %2) {
%4 = icmp sgt i32 %0, 0
br i1 %4, label %5, label %56
5: ; preds = %3
%6 = zext i32 %0 to i64
br label %7
7: ; preds = %5, %53
%8 = phi i64 [ 0, %5 ], [ %54, %53 ]
%9 = add nuw i64 %8, 1
%10 = getelementptr [784 x i8], [784 x i8]* %1, i64 %9, i64 0
%11 = getelementptr [784 x i8], [784 x i8]* %1, i64 %8, i64 0
%12 = getelementptr [784 x double], [784 x double]* %2, i64 %9, i64 0
%13 = bitcast double* %12 to i8*
%14 = getelementptr [784 x double], [784 x double]* %2, i64 %8, i64 0
%15 = bitcast double* %14 to i8*
%16 = icmp ugt i8* %10, %15
%17 = icmp ult i8* %11, %13
%18 = and i1 %16, %17
br i1 %18, label %38, label %19
19: ; preds = %7, %19
%20 = phi i64 [ %36, %19 ], [ 0, %7 ]
%21 = getelementptr inbounds [784 x i8], [784 x i8]* %1, i64 %8, i64 %20
%22 = bitcast i8* %21 to <2 x i8>*
%23 = load <2 x i8>, <2 x i8>* %22
%24 = uitofp <2 x i8> %23 to <2 x double>
%25 = fdiv <2 x double> %24, <double 2.550000e+02, double 2.550000e+02>
%26 = getelementptr inbounds [784 x double], [784 x double]* %2, i64 %8, i64 %20
%27 = bitcast double* %26 to <2 x double>*
store <2 x double> %25, <2 x double>* %27
%28 = or i64 %20, 2
%29 = getelementptr inbounds [784 x i8], [784 x i8]* %1, i64 %8, i64 %28
%30 = bitcast i8* %29 to <2 x i8>*
%31 = load <2 x i8>, <2 x i8>* %30
%32 = uitofp <2 x i8> %31 to <2 x double>
%33 = fdiv <2 x double> %32, <double 2.550000e+02, double 2.550000e+02>
%34 = getelementptr inbounds [784 x double], [784 x double]* %2, i64 %8, i64 %28
%35 = bitcast double* %34 to <2 x double>*
store <2 x double> %33, <2 x double>* %35
%36 = add nuw nsw i64 %20, 4
%37 = icmp eq i64 %36, 784
br i1 %37, label %53, label %19
38: ; preds = %7, %38
%39 = phi i64 [ %51, %38 ], [ 0, %7 ]
%40 = getelementptr inbounds [784 x i8], [784 x i8]* %1, i64 %8, i64 %39
%41 = load i8, i8* %40
%42 = uitofp i8 %41 to double
%43 = fdiv double %42, 2.550000e+02
%44 = getelementptr inbounds [784 x double], [784 x double]* %2, i64 %8, i64 %39
store double %43, double* %44
%45 = or i64 %39, 1
%46 = getelementptr inbounds [784 x i8], [784 x i8]* %1, i64 %8, i64 %45
%47 = load i8, i8* %46
%48 = uitofp i8 %47 to double
%49 = fdiv double %48, 2.550000e+02
%50 = getelementptr inbounds [784 x double], [784 x double]* %2, i64 %8, i64 %45
store double %49, double* %50
%51 = add nuw nsw i64 %39, 2
%52 = icmp eq i64 %51, 784
br i1 %52, label %53, label %38
53: ; preds = %19, %38
%54 = add nuw nsw i64 %8, 1
%55 = icmp eq i64 %54, %6
br i1 %55, label %56, label %7
56: ; preds = %53, %3
ret void
}