#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
char get_freqmap_idx(unsigned char);
void freqmap_calc(unsigned char *data, size_t datalen, double *out) {
  size_t i;
  double invdatalen = 1.0 / datalen;
  for (i = 0; i < 27; ++i)
    out[i] = 0.0;
  for (i = 0; i < datalen; ++i) {
    char idx = get_freqmap_idx(data[i]);
    if (idx != -1)
      out[(size_t)idx] += 1;
  }
  for (i = 0; i < 27; ++i)
    out[i] *= invdatalen;
}


x86 assembly (clang, -O0):
<freqmap_calc>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
movaps 0xee5(%rip),%xmm0
movq   -0x10(%rbp),%xmm1
punpckldq %xmm0,%xmm1
movapd 0xee4(%rip),%xmm0
subpd  %xmm0,%xmm1
movaps %xmm1,%xmm0
unpckhpd %xmm1,%xmm1
addsd  %xmm0,%xmm1
movsd  0xead(%rip),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movq   $0x0,-0x20(%rbp)
cmpq   $0x1b,-0x20(%rbp)
jae    1190 <freqmap_calc+0x80>
mov    -0x18(%rbp),%rax
mov    -0x20(%rbp),%rcx
xorps  %xmm0,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
jmp    1164 <freqmap_calc+0x54>
movq   $0x0,-0x20(%rbp)
mov    -0x20(%rbp),%rax
cmp    -0x10(%rbp),%rax
jae    11f8 <freqmap_calc+0xe8>
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%rcx
movzbl (%rax,%rcx,1),%edi
call   1030 <get_freqmap_idx@plt>
mov    %al,-0x29(%rbp)
movsbl -0x29(%rbp),%eax
cmp    $0xffffffff,%eax
je     11e2 <freqmap_calc+0xd2>
mov    -0x18(%rbp),%rax
movsbq -0x29(%rbp),%rcx
movsd  0xe28(%rip),%xmm0
addsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,(%rax,%rcx,8)
jmp    11e7 <freqmap_calc+0xd7>
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
jmp    1198 <freqmap_calc+0x88>
movq   $0x0,-0x20(%rbp)
cmpq   $0x1b,-0x20(%rbp)
jae    1233 <freqmap_calc+0x123>
movsd  -0x28(%rbp),%xmm0
mov    -0x18(%rbp),%rax
mov    -0x20(%rbp),%rcx
mulsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
jmp    1200 <freqmap_calc+0xf0>
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<freqmap_calc>:
push   %r15
push   %r14
push   %r12
push   %rbx
sub    $0x18,%rsp
mov    %rdx,%r12
movq   %rsi,%xmm0
punpckldq 0xed5(%rip),%xmm0
subpd  0xedd(%rip),%xmm0
movapd %xmm0,%xmm2
unpckhpd %xmm0,%xmm2
addsd  %xmm0,%xmm2
xorpd  %xmm1,%xmm1
movupd %xmm1,0xc0(%rdx)
movupd %xmm1,0xb0(%rdx)
movupd %xmm1,0xa0(%rdx)
movupd %xmm1,0x90(%rdx)
movupd %xmm1,0x80(%rdx)
movupd %xmm1,0x70(%rdx)
movupd %xmm1,0x60(%rdx)
movupd %xmm1,0x50(%rdx)
movupd %xmm1,0x40(%rdx)
movupd %xmm1,0x30(%rdx)
movupd %xmm1,0x20(%rdx)
movupd %xmm1,0x10(%rdx)
movupd %xmm1,(%rdx)
movq   $0x0,0xd0(%rdx)
movsd  0xe7b(%rip),%xmm3
divsd  %xmm2,%xmm3
test   %rsi,%rsi
je     1271 <freqmap_calc+0x161>
mov    %rsi,%r14
mov    %rdi,%r15
movapd %xmm3,(%rsp)
xor    %ebx,%ebx
jmp    11d9 <freqmap_calc+0xc9>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
add    $0x1,%rbx
cmp    %rbx,%r14
je     1201 <freqmap_calc+0xf1>
movzbl (%r15,%rbx,1),%edi
call   1030 <get_freqmap_idx@plt>
cmp    $0xff,%al
je     11d0 <freqmap_calc+0xc0>
movsbq %al,%rax
movsd  (%r12,%rax,8),%xmm0
addsd  0xe27(%rip),%xmm0
movsd  %xmm0,(%r12,%rax,8)
jmp    11d0 <freqmap_calc+0xc0>
movupd (%r12),%xmm1
movupd 0x10(%r12),%xmm6
movupd 0x20(%r12),%xmm5
movupd 0x30(%r12),%xmm4
movupd 0x40(%r12),%xmm2
movupd 0x50(%r12),%xmm14
movupd 0x60(%r12),%xmm13
movupd 0x70(%r12),%xmm12
movupd 0x80(%r12),%xmm11
movupd 0x90(%r12),%xmm10
movupd 0xa0(%r12),%xmm9
movupd 0xb0(%r12),%xmm8
movsd  0xc0(%r12),%xmm0
movapd (%rsp),%xmm3
jmp    12a8 <freqmap_calc+0x198>
xorpd  %xmm0,%xmm0
xorpd  %xmm6,%xmm6
xorpd  %xmm5,%xmm5
xorpd  %xmm4,%xmm4
xorpd  %xmm2,%xmm2
xorpd  %xmm14,%xmm14
xorpd  %xmm13,%xmm13
xorpd  %xmm12,%xmm12
xorpd  %xmm11,%xmm11
xorpd  %xmm10,%xmm10
xorpd  %xmm9,%xmm9
xorpd  %xmm8,%xmm8
movapd %xmm3,%xmm7
unpcklpd %xmm3,%xmm7
mulpd  %xmm7,%xmm1
movupd %xmm1,(%r12)
mulpd  %xmm7,%xmm6
movupd %xmm6,0x10(%r12)
mulpd  %xmm7,%xmm5
movupd %xmm5,0x20(%r12)
mulpd  %xmm7,%xmm4
movupd %xmm4,0x30(%r12)
mulpd  %xmm7,%xmm2
movupd %xmm2,0x40(%r12)
mulpd  %xmm7,%xmm14
movupd %xmm14,0x50(%r12)
mulpd  %xmm7,%xmm13
movupd %xmm13,0x60(%r12)
mulpd  %xmm7,%xmm12
movupd %xmm12,0x70(%r12)
mulpd  %xmm7,%xmm11
movupd %xmm11,0x80(%r12)
mulpd  %xmm7,%xmm10
movupd %xmm10,0x90(%r12)
mulpd  %xmm7,%xmm9
movupd %xmm9,0xa0(%r12)
mulpd  %xmm7,%xmm8
movupd %xmm8,0xb0(%r12)
movhpd 0xc8(%r12),%xmm0
mulpd  %xmm7,%xmm0
movupd %xmm0,0xc0(%r12)
mulsd  0xd0(%r12),%xmm3
movsd  %xmm3,0xd0(%r12)
add    $0x18,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
define void @freqmap_calc(i8* %0, i64 %1, double* %2) {
%4 = alloca i8*
%5 = alloca i64
%6 = alloca double*
%7 = alloca i64
%8 = alloca double
%9 = alloca i8
store i8* %0, i8** %4
store i64 %1, i64* %5
store double* %2, double** %6
%10 = load i64, i64* %5
%11 = uitofp i64 %10 to double
%12 = fdiv double 1.000000e+00, %11
store double %12, double* %8
store i64 0, i64* %7
br label %13
13: ; preds = %20, %3
%14 = load i64, i64* %7
%15 = icmp ult i64 %14, 27
br i1 %15, label %16, label %23
16: ; preds = %13
%17 = load double*, double** %6
%18 = load i64, i64* %7
%19 = getelementptr inbounds double, double* %17, i64 %18
store double 0.000000e+00, double* %19
br label %20
20: ; preds = %16
%21 = load i64, i64* %7
%22 = add i64 %21, 1
store i64 %22, i64* %7
br label %13
23: ; preds = %13
store i64 0, i64* %7
br label %24
24: ; preds = %45, %23
%25 = load i64, i64* %7
%26 = load i64, i64* %5
%27 = icmp ult i64 %25, %26
br i1 %27, label %28, label %48
28: ; preds = %24
%29 = load i8*, i8** %4
%30 = load i64, i64* %7
%31 = getelementptr inbounds i8, i8* %29, i64 %30
%32 = load i8, i8* %31
%33 = call signext i8 @get_freqmap_idx(i8 zeroext %32)
store i8 %33, i8* %9
%34 = load i8, i8* %9
%35 = sext i8 %34 to i32
%36 = icmp ne i32 %35, -1
br i1 %36, label %37, label %44
37: ; preds = %28
%38 = load double*, double** %6
%39 = load i8, i8* %9
%40 = sext i8 %39 to i64
%41 = getelementptr inbounds double, double* %38, i64 %40
%42 = load double, double* %41
%43 = fadd double %42, 1.000000e+00
store double %43, double* %41
br label %44
44: ; preds = %37, %28
br label %45
45: ; preds = %44
%46 = load i64, i64* %7
%47 = add i64 %46, 1
store i64 %47, i64* %7
br label %24
48: ; preds = %24
store i64 0, i64* %7
br label %49
49: ; preds = %59, %48
%50 = load i64, i64* %7
%51 = icmp ult i64 %50, 27
br i1 %51, label %52, label %62
52: ; preds = %49
%53 = load double, double* %8
%54 = load double*, double** %6
%55 = load i64, i64* %7
%56 = getelementptr inbounds double, double* %54, i64 %55
%57 = load double, double* %56
%58 = fmul double %57, %53
store double %58, double* %56
br label %59
59: ; preds = %52
%60 = load i64, i64* %7
%61 = add i64 %60, 1
store i64 %61, i64* %7
br label %49
62: ; preds = %49
ret void
}

LLVM IR (-O2):
define void @freqmap_calc(i8* nocapture %0, i64 %1, double* nocapture %2) {
%4 = bitcast double* %2 to i8*
%5 = uitofp i64 %1 to double
%6 = fdiv double 1.000000e+00, %5
%7 = icmp eq i64 %1, 0
br i1 %7, label %46, label %107
8: ; preds = %118
%9 = bitcast double* %2 to <2 x double>*
%10 = load <2 x double>, <2 x double>* %9
%11 = getelementptr inbounds double, double* %2, i64 2
%12 = bitcast double* %11 to <2 x double>*
%13 = load <2 x double>, <2 x double>* %12
%14 = getelementptr inbounds double, double* %2, i64 4
%15 = bitcast double* %14 to <2 x double>*
%16 = load <2 x double>, <2 x double>* %15
%17 = getelementptr inbounds double, double* %2, i64 6
%18 = bitcast double* %17 to <2 x double>*
%19 = load <2 x double>, <2 x double>* %18
%20 = getelementptr inbounds double, double* %2, i64 8
%21 = bitcast double* %20 to <2 x double>*
%22 = load <2 x double>, <2 x double>* %21
%23 = getelementptr inbounds double, double* %2, i64 10
%24 = bitcast double* %23 to <2 x double>*
%25 = load <2 x double>, <2 x double>* %24
%26 = getelementptr inbounds double, double* %2, i64 12
%27 = bitcast double* %26 to <2 x double>*
%28 = load <2 x double>, <2 x double>* %27
%29 = getelementptr inbounds double, double* %2, i64 14
%30 = bitcast double* %29 to <2 x double>*
%31 = load <2 x double>, <2 x double>* %30
%32 = getelementptr inbounds double, double* %2, i64 16
%33 = bitcast double* %32 to <2 x double>*
%34 = load <2 x double>, <2 x double>* %33
%35 = getelementptr inbounds double, double* %2, i64 18
%36 = bitcast double* %35 to <2 x double>*
%37 = load <2 x double>, <2 x double>* %36
%38 = getelementptr inbounds double, double* %2, i64 20
%39 = bitcast double* %38 to <2 x double>*
%40 = load <2 x double>, <2 x double>* %39
%41 = getelementptr inbounds double, double* %2, i64 22
%42 = bitcast double* %41 to <2 x double>*
%43 = load <2 x double>, <2 x double>* %42
%44 = getelementptr inbounds double, double* %2, i64 24
%45 = load double, double* %44
br label %46
46: ; preds = %8, %3
%47 = phi double [ %45, %8 ], [ 0.000000e+00, %3 ]
%48 = phi <2 x double> [ %10, %8 ], [ zeroinitializer, %3 ]
%49 = phi <2 x double> [ %13, %8 ], [ zeroinitializer, %3 ]
%50 = phi <2 x double> [ %16, %8 ], [ zeroinitializer, %3 ]
%51 = phi <2 x double> [ %19, %8 ], [ zeroinitializer, %3 ]
%52 = phi <2 x double> [ %22, %8 ], [ zeroinitializer, %3 ]
%53 = phi <2 x double> [ %25, %8 ], [ zeroinitializer, %3 ]
%54 = phi <2 x double> [ %28, %8 ], [ zeroinitializer, %3 ]
%55 = phi <2 x double> [ %31, %8 ], [ zeroinitializer, %3 ]
%56 = phi <2 x double> [ %34, %8 ], [ zeroinitializer, %3 ]
%57 = phi <2 x double> [ %37, %8 ], [ zeroinitializer, %3 ]
%58 = phi <2 x double> [ %40, %8 ], [ zeroinitializer, %3 ]
%59 = phi <2 x double> [ %43, %8 ], [ zeroinitializer, %3 ]
%60 = insertelement <2 x double> poison, double %6, i64 0
%61 = shufflevector <2 x double> %60, <2 x double> poison, <2 x i32> zeroinitializer
%62 = fmul <2 x double> %61, %48
%63 = bitcast double* %2 to <2 x double>*
store <2 x double> %62, <2 x double>* %63
%64 = getelementptr inbounds double, double* %2, i64 2
%65 = fmul <2 x double> %61, %49
%66 = bitcast double* %64 to <2 x double>*
store <2 x double> %65, <2 x double>* %66
%67 = getelementptr inbounds double, double* %2, i64 4
%68 = fmul <2 x double> %61, %50
%69 = bitcast double* %67 to <2 x double>*
store <2 x double> %68, <2 x double>* %69
%70 = getelementptr inbounds double, double* %2, i64 6
%71 = fmul <2 x double> %61, %51
%72 = bitcast double* %70 to <2 x double>*
store <2 x double> %71, <2 x double>* %72
%73 = getelementptr inbounds double, double* %2, i64 8
%74 = fmul <2 x double> %61, %52
%75 = bitcast double* %73 to <2 x double>*
store <2 x double> %74, <2 x double>* %75
%76 = getelementptr inbounds double, double* %2, i64 10
%77 = fmul <2 x double> %61, %53
%78 = bitcast double* %76 to <2 x double>*
store <2 x double> %77, <2 x double>* %78
%79 = getelementptr inbounds double, double* %2, i64 12
%80 = fmul <2 x double> %61, %54
%81 = bitcast double* %79 to <2 x double>*
store <2 x double> %80, <2 x double>* %81
%82 = getelementptr inbounds double, double* %2, i64 14
%83 = fmul <2 x double> %61, %55
%84 = bitcast double* %82 to <2 x double>*
store <2 x double> %83, <2 x double>* %84
%85 = getelementptr inbounds double, double* %2, i64 16
%86 = fmul <2 x double> %61, %56
%87 = bitcast double* %85 to <2 x double>*
store <2 x double> %86, <2 x double>* %87
%88 = getelementptr inbounds double, double* %2, i64 18
%89 = fmul <2 x double> %61, %57
%90 = bitcast double* %88 to <2 x double>*
store <2 x double> %89, <2 x double>* %90
%91 = getelementptr inbounds double, double* %2, i64 20
%92 = fmul <2 x double> %61, %58
%93 = bitcast double* %91 to <2 x double>*
store <2 x double> %92, <2 x double>* %93
%94 = getelementptr inbounds double, double* %2, i64 22
%95 = fmul <2 x double> %61, %59
%96 = bitcast double* %94 to <2 x double>*
store <2 x double> %95, <2 x double>* %96
%97 = getelementptr inbounds double, double* %2, i64 24
%98 = getelementptr inbounds double, double* %2, i64 25
%99 = load double, double* %98
%100 = insertelement <2 x double> poison, double %47, i64 0
%101 = insertelement <2 x double> %100, double %99, i64 1
%102 = fmul <2 x double> %61, %101
%103 = bitcast double* %97 to <2 x double>*
store <2 x double> %102, <2 x double>* %103
%104 = getelementptr inbounds double, double* %2, i64 26
%105 = load double, double* %104
%106 = fmul double %6, %105
store double %106, double* %104
ret void
107: ; preds = %3, %118
%108 = phi i64 [ %119, %118 ], [ 0, %3 ]
%109 = getelementptr inbounds i8, i8* %0, i64 %108
%110 = load i8, i8* %109
%111 = tail call signext i8 @get_freqmap_idx(i8 zeroext %110)
%112 = icmp eq i8 %111, -1
br i1 %112, label %118, label %113
113: ; preds = %107
%114 = sext i8 %111 to i64
%115 = getelementptr inbounds double, double* %2, i64 %114
%116 = load double, double* %115
%117 = fadd double %116, 1.000000e+00
store double %117, double* %115
br label %118
118: ; preds = %113, %107
%119 = add nuw i64 %108, 1
%120 = icmp eq i64 %119, %1
br i1 %120, label %8, label %107
}