#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 */
void b1cpred(bool *actual, bool *predict, size_t len, float *hit, float *miss,
             void *userdata) {
  size_t i, count;
  bool matched;
  if (len == 0) {
    *hit = 1;
    *miss = 0;
    return;
  }
  count = 0;
  predict[0] = (uintptr_t)userdata;
  for (i = 0; i < len; i++) {
    matched = false;
    if (predict[i] == actual[i]) {
      matched = true;
      count++;
    }
    if (i + 1 < len)
      predict[i + 1] = (matched) ? predict[i] : !predict[i];
  }
  *hit = count * 1.0 / len;
  *miss = 1 - *hit;
}


x86 assembly (clang, -O0):
<b1cpred>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    %r9,-0x30(%rbp)
cmpq   $0x0,-0x18(%rbp)
jne    1147 <b1cpred+0x47>
mov    -0x20(%rbp),%rax
movss  0xecd(%rip),%xmm0
movss  %xmm0,(%rax)
mov    -0x28(%rbp),%rax
xorps  %xmm0,%xmm0
movss  %xmm0,(%rax)
jmp    127b <b1cpred+0x17b>
movq   $0x0,-0x40(%rbp)
mov    -0x30(%rbp),%rax
mov    %eax,%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,(%rax)
movq   $0x0,-0x38(%rbp)
mov    -0x38(%rbp),%rax
cmp    -0x18(%rbp),%rax
jae    1214 <b1cpred+0x114>
movl   $0x0,-0x44(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x38(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
mov    -0x8(%rbp),%rcx
mov    -0x38(%rbp),%rdx
cmp    (%rcx,%rdx,4),%eax
jne    11a7 <b1cpred+0xa7>
movl   $0x1,-0x44(%rbp)
mov    -0x40(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x40(%rbp)
mov    -0x38(%rbp),%rax
add    $0x1,%rax
cmp    -0x18(%rbp),%rax
jae    11fe <b1cpred+0xfe>
cmpl   $0x0,-0x44(%rbp)
je     11d6 <b1cpred+0xd6>
mov    -0x10(%rbp),%rax
mov    -0x38(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
mov    %eax,-0x48(%rbp)
jmp    11ef <b1cpred+0xef>
mov    -0x10(%rbp),%rax
mov    -0x38(%rbp),%rcx
cmpl   $0x0,(%rax,%rcx,4)
setne  %al
xor    $0xff,%al
and    $0x1,%al
movzbl %al,%eax
mov    %eax,-0x48(%rbp)
mov    -0x48(%rbp),%edx
mov    -0x10(%rbp),%rax
mov    -0x38(%rbp),%rcx
mov    %edx,0x4(%rax,%rcx,4)
jmp    1203 <b1cpred+0x103>
mov    -0x38(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x38(%rbp)
jmp    1163 <b1cpred+0x63>
movq   -0x40(%rbp),%xmm0
movaps 0xdf0(%rip),%xmm3
punpckldq %xmm3,%xmm0
movapd 0xdf4(%rip),%xmm2
subpd  %xmm2,%xmm0
movaps %xmm0,%xmm1
unpckhpd %xmm0,%xmm0
addsd  %xmm1,%xmm0
movq   -0x18(%rbp),%xmm1
punpckldq %xmm3,%xmm1
subpd  %xmm2,%xmm1
movaps %xmm1,%xmm2
unpckhpd %xmm1,%xmm1
addsd  %xmm2,%xmm1
divsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x20(%rbp),%rax
movss  %xmm0,(%rax)
mov    -0x20(%rbp),%rax
movss  0xd91(%rip),%xmm0
subss  (%rax),%xmm0
mov    -0x28(%rbp),%rax
movss  %xmm0,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<b1cpred>:
push   %rbp
push   %r14
push   %rbx
test   %rdx,%rdx
je     11b9 <b1cpred+0xb9>
mov    %r9d,(%rsi)
mov    $0x1,%eax
xor    %r10d,%r10d
nopl   0x0(%rax,%rax,1)
mov    -0x4(%rdi,%rax,4),%ebp
xor    %r11d,%r11d
cmp    %ebp,%r9d
sete   %r14b
cmp    %rdx,%rax
jae    1145 <b1cpred+0x45>
xor    %ebx,%ebx
test   %r9d,%r9d
sete   %bl
cmp    %ebp,%r9d
cmove  %r9d,%ebx
mov    %ebx,(%rsi,%rax,4)
mov    %r14b,%r11b
add    %r11,%r10
cmp    %rax,%rdx
je     115a <b1cpred+0x5a>
mov    (%rsi,%rax,4),%r9d
add    $0x1,%rax
jmp    1120 <b1cpred+0x20>
movq   %r10,%xmm0
movdqa 0xe99(%rip),%xmm1
punpckldq %xmm1,%xmm0
movapd 0xe9d(%rip),%xmm2
subpd  %xmm2,%xmm0
movapd %xmm0,%xmm3
unpckhpd %xmm0,%xmm3
addsd  %xmm0,%xmm3
movq   %rdx,%xmm0
punpckldq %xmm1,%xmm0
subpd  %xmm2,%xmm0
movapd %xmm0,%xmm1
unpckhpd %xmm0,%xmm1
addsd  %xmm0,%xmm1
divsd  %xmm1,%xmm3
xorps  %xmm1,%xmm1
cvtsd2ss %xmm3,%xmm1
movss  %xmm1,(%rcx)
movss  0xe6d(%rip),%xmm0
subss  %xmm1,%xmm0
jmp    11c2 <b1cpred+0xc2>
movl   $0x3f800000,(%rcx)
xorps  %xmm0,%xmm0
movss  %xmm0,(%r8)
pop    %rbx
pop    %r14
pop    %rbp
ret

LLVM IR (-O0):
define void @b1cpred(i32* %0, i32* %1, i64 %2, float* %3, float* %4, i8* %5) {
%7 = alloca i32*
%8 = alloca i32*
%9 = alloca i64
%10 = alloca float*
%11 = alloca float*
%12 = alloca i8*
%13 = alloca i64
%14 = alloca i64
%15 = alloca i32
store i32* %0, i32** %7
store i32* %1, i32** %8
store i64 %2, i64* %9
store float* %3, float** %10
store float* %4, float** %11
store i8* %5, i8** %12
%16 = load i64, i64* %9
%17 = icmp eq i64 %16, 0
br i1 %17, label %18, label %21
18: ; preds = %6
%19 = load float*, float** %10
store float 1.000000e+00, float* %19
%20 = load float*, float** %11
store float 0.000000e+00, float* %20
br label %88
21: ; preds = %6
store i64 0, i64* %14
%22 = load i8*, i8** %12
%23 = ptrtoint i8* %22 to i64
%24 = trunc i64 %23 to i32
%25 = load i32*, i32** %8
%26 = getelementptr inbounds i32, i32* %25, i64 0
store i32 %24, i32* %26
store i64 0, i64* %13
br label %27
27: ; preds = %72, %21
%28 = load i64, i64* %13
%29 = load i64, i64* %9
%30 = icmp ult i64 %28, %29
br i1 %30, label %31, label %75
31: ; preds = %27
store i32 0, i32* %15
%32 = load i32*, i32** %8
%33 = load i64, i64* %13
%34 = getelementptr inbounds i32, i32* %32, i64 %33
%35 = load i32, i32* %34
%36 = load i32*, i32** %7
%37 = load i64, i64* %13
%38 = getelementptr inbounds i32, i32* %36, i64 %37
%39 = load i32, i32* %38
%40 = icmp eq i32 %35, %39
br i1 %40, label %41, label %44
41: ; preds = %31
store i32 1, i32* %15
%42 = load i64, i64* %14
%43 = add i64 %42, 1
store i64 %43, i64* %14
br label %44
44: ; preds = %41, %31
%45 = load i64, i64* %13
%46 = add i64 %45, 1
%47 = load i64, i64* %9
%48 = icmp ult i64 %46, %47
br i1 %48, label %49, label %71
49: ; preds = %44
%50 = load i32, i32* %15
%51 = icmp ne i32 %50, 0
br i1 %51, label %52, label %57
52: ; preds = %49
%53 = load i32*, i32** %8
%54 = load i64, i64* %13
%55 = getelementptr inbounds i32, i32* %53, i64 %54
%56 = load i32, i32* %55
br label %65
57: ; preds = %49
%58 = load i32*, i32** %8
%59 = load i64, i64* %13
%60 = getelementptr inbounds i32, i32* %58, i64 %59
%61 = load i32, i32* %60
%62 = icmp ne i32 %61, 0
%63 = xor i1 %62, true
%64 = zext i1 %63 to i32
br label %65
65: ; preds = %57, %52
%66 = phi i32 [ %56, %52 ], [ %64, %57 ]
%67 = load i32*, i32** %8
%68 = load i64, i64* %13
%69 = add i64 %68, 1
%70 = getelementptr inbounds i32, i32* %67, i64 %69
store i32 %66, i32* %70
br label %71
71: ; preds = %65, %44
br label %72
72: ; preds = %71
%73 = load i64, i64* %13
%74 = add i64 %73, 1
store i64 %74, i64* %13
br label %27
75: ; preds = %27
%76 = load i64, i64* %14
%77 = uitofp i64 %76 to double
%78 = fmul double %77, 1.000000e+00
%79 = load i64, i64* %9
%80 = uitofp i64 %79 to double
%81 = fdiv double %78, %80
%82 = fptrunc double %81 to float
%83 = load float*, float** %10
store float %82, float* %83
%84 = load float*, float** %10
%85 = load float, float* %84
%86 = fsub float 1.000000e+00, %85
%87 = load float*, float** %11
store float %86, float* %87
br label %88
88: ; preds = %75, %18
ret void
}

LLVM IR (-O2):
define void @b1cpred(i32* nocapture %0, i32* nocapture %1, i64 %2, float* nocapture writeonly %3, float* nocapture writeonly %4, i8* %5) {
%7 = icmp eq i64 %2, 0
br i1 %7, label %8, label %9
8: ; preds = %6
store float 1.000000e+00, float* %3
br label %39
9: ; preds = %6
%10 = ptrtoint i8* %5 to i64
%11 = trunc i64 %10 to i32
store i32 %11, i32* %1
br label %12
12: ; preds = %30, %9
%13 = phi i32 [ %32, %30 ], [ %11, %9 ]
%14 = phi i64 [ %20, %30 ], [ 0, %9 ]
%15 = phi i64 [ %21, %30 ], [ 0, %9 ]
%16 = getelementptr inbounds i32, i32* %0, i64 %15
%17 = load i32, i32* %16
%18 = icmp eq i32 %13, %17
%19 = zext i1 %18 to i64
%20 = add i64 %14, %19
%21 = add nuw i64 %15, 1
%22 = icmp ult i64 %21, %2
br i1 %22, label %23, label %28
23: ; preds = %12
%24 = icmp eq i32 %13, 0
%25 = zext i1 %24 to i32
%26 = select i1 %18, i32 %13, i32 %25
%27 = getelementptr inbounds i32, i32* %1, i64 %21
store i32 %26, i32* %27
br label %28
28: ; preds = %12, %23
%29 = icmp eq i64 %21, %2
br i1 %29, label %33, label %30
30: ; preds = %28
%31 = getelementptr inbounds i32, i32* %1, i64 %21
%32 = load i32, i32* %31
br label %12
33: ; preds = %28
%34 = uitofp i64 %20 to double
%35 = uitofp i64 %2 to double
%36 = fdiv double %34, %35
%37 = fptrunc double %36 to float
store float %37, float* %3
%38 = fsub float 1.000000e+00, %37
br label %39
39: ; preds = %33, %8
%40 = phi float [ %38, %33 ], [ 0.000000e+00, %8 ]
store float %40, float* %4
ret void
}