#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 */
int fmax(int, int);
int fmin(int, int);
float diff(void *done, int donec, void *dtwo, int dtwoc) {
  int max = fmax(donec, dtwoc);
  int min = fmin(donec, dtwoc);
  if (max == 0) {
    return 0.0f;
  }
  float inc = 1 / ((float)max);
  float v = (max - min) * inc;
  int i;
  for (i = 0; i < min; i++) {
    unsigned char cone = *(unsigned char *)(done + i);
    unsigned char ctwo = *(unsigned char *)(dtwo + i);
    if (cone != ctwo) {
      v += inc;
    }
  }
  if (v < inc) {
    return 0;
  }
  return v;
}


x86 assembly (clang, -O0):
<diff>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %ecx,-0x24(%rbp)
mov    -0x14(%rbp),%edi
mov    -0x24(%rbp),%esi
call   1040 <fmax@plt>
mov    %eax,-0x28(%rbp)
mov    -0x14(%rbp),%edi
mov    -0x24(%rbp),%esi
call   1030 <fmin@plt>
mov    %eax,-0x2c(%rbp)
cmpl   $0x0,-0x28(%rbp)
jne    1169 <diff+0x49>
xorps  %xmm0,%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    121e <diff+0xfe>
cvtsi2ssl -0x28(%rbp),%xmm1
movss  0xe8a(%rip),%xmm0
divss  %xmm1,%xmm0
movss  %xmm0,-0x30(%rbp)
mov    -0x28(%rbp),%eax
sub    -0x2c(%rbp),%eax
cvtsi2ss %eax,%xmm0
mulss  -0x30(%rbp),%xmm0
movss  %xmm0,-0x34(%rbp)
movl   $0x0,-0x38(%rbp)
mov    -0x38(%rbp),%eax
cmp    -0x2c(%rbp),%eax
jge    11f4 <diff+0xd4>
mov    -0x10(%rbp),%rax
movslq -0x38(%rbp),%rcx
mov    (%rax,%rcx,1),%al
mov    %al,-0x39(%rbp)
mov    -0x20(%rbp),%rax
movslq -0x38(%rbp),%rcx
mov    (%rax,%rcx,1),%al
mov    %al,-0x3a(%rbp)
movzbl -0x39(%rbp),%eax
movzbl -0x3a(%rbp),%ecx
cmp    %ecx,%eax
je     11e1 <diff+0xc1>
movss  -0x30(%rbp),%xmm0
addss  -0x34(%rbp),%xmm0
movss  %xmm0,-0x34(%rbp)
jmp    11e6 <diff+0xc6>
mov    -0x38(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x38(%rbp)
jmp    119a <diff+0x7a>
movss  -0x34(%rbp),%xmm1
movss  -0x30(%rbp),%xmm0
ucomiss %xmm1,%xmm0
jbe    1214 <diff+0xf4>
xorps  %xmm0,%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    121e <diff+0xfe>
movss  -0x34(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<diff>:
push   %rbp
push   %r15
push   %r14
push   %r12
push   %rbx
mov    %ecx,%r15d
mov    %rdx,%r14
mov    %esi,%r12d
mov    %rdi,%rbx
mov    %esi,%edi
mov    %ecx,%esi
call   1040 <fmax@plt>
mov    %eax,%ebp
mov    %r12d,%edi
mov    %r15d,%esi
call   1030 <fmin@plt>
test   %ebp,%ebp
je     11cc <diff+0xac>
cvtsi2ss %ebp,%xmm0
sub    %eax,%ebp
cvtsi2ss %ebp,%xmm1
movss  0xea0(%rip),%xmm2
divss  %xmm0,%xmm2
mulss  %xmm2,%xmm1
test   %eax,%eax
jle    11bf <diff+0x9f>
mov    %eax,%edx
lea    -0x1(%rdx),%rcx
mov    %edx,%esi
and    $0x3,%esi
cmp    $0x3,%rcx
jae    11d8 <diff+0xb8>
xor    %ecx,%ecx
test   %rsi,%rsi
je     11bf <diff+0x9f>
add    %rcx,%r14
add    %rcx,%rbx
xor    %ecx,%ecx
movss  0xe70(%rip),%xmm0
jmp    11ad <diff+0x8d>
cs nopw 0x0(%rax,%rax,1)
addss  %xmm3,%xmm1
add    $0x1,%rcx
cmp    %rcx,%rsi
je     11bf <diff+0x9f>
movzbl (%rbx,%rcx,1),%eax
movaps %xmm0,%xmm3
cmp    (%r14,%rcx,1),%al
je     11a0 <diff+0x80>
movaps %xmm2,%xmm3
jmp    11a0 <diff+0x80>
movaps %xmm1,%xmm0
cmpltss %xmm2,%xmm0
andnps %xmm1,%xmm0
jmp    11cf <diff+0xaf>
xorps  %xmm0,%xmm0
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
ret
and    $0xfffffffc,%edx
xor    %ecx,%ecx
movss  0xe1f(%rip),%xmm0
jmp    120d <diff+0xed>
nopw   0x0(%rax,%rax,1)
addss  %xmm3,%xmm1
addss  %xmm4,%xmm1
addss  %xmm5,%xmm1
addss  %xmm6,%xmm1
add    $0x4,%rcx
cmp    %rcx,%rdx
je     117f <diff+0x5f>
movzbl (%rbx,%rcx,1),%eax
movaps %xmm0,%xmm3
cmp    (%r14,%rcx,1),%al
je     121d <diff+0xfd>
movaps %xmm2,%xmm3
movzbl 0x1(%rbx,%rcx,1),%eax
movaps %xmm0,%xmm4
cmp    0x1(%r14,%rcx,1),%al
je     122f <diff+0x10f>
movaps %xmm2,%xmm4
movzbl 0x2(%rbx,%rcx,1),%eax
movaps %xmm0,%xmm5
cmp    0x2(%r14,%rcx,1),%al
je     1241 <diff+0x121>
movaps %xmm2,%xmm5
movzbl 0x3(%rbx,%rcx,1),%eax
movaps %xmm0,%xmm6
cmp    0x3(%r14,%rcx,1),%al
je     11f0 <diff+0xd0>
movaps %xmm2,%xmm6
jmp    11f0 <diff+0xd0>

LLVM IR (-O0):
define float @diff(i8* %0, i32 %1, i8* %2, i32 %3) {
%5 = alloca float
%6 = alloca i8*
%7 = alloca i32
%8 = alloca i8*
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32
%12 = alloca float
%13 = alloca float
%14 = alloca i32
%15 = alloca i8
%16 = alloca i8
store i8* %0, i8** %6
store i32 %1, i32* %7
store i8* %2, i8** %8
store i32 %3, i32* %9
%17 = load i32, i32* %7
%18 = load i32, i32* %9
%19 = call i32 @fmax(i32 %17, i32 %18)
store i32 %19, i32* %10
%20 = load i32, i32* %7
%21 = load i32, i32* %9
%22 = call i32 @fmin(i32 %20, i32 %21)
store i32 %22, i32* %11
%23 = load i32, i32* %10
%24 = icmp eq i32 %23, 0
br i1 %24, label %25, label %26
25: ; preds = %4
store float 0.000000e+00, float* %5
br label %71
26: ; preds = %4
%27 = load i32, i32* %10
%28 = sitofp i32 %27 to float
%29 = fdiv float 1.000000e+00, %28
store float %29, float* %12
%30 = load i32, i32* %10
%31 = load i32, i32* %11
%32 = sub nsw i32 %30, %31
%33 = sitofp i32 %32 to float
%34 = load float, float* %12
%35 = fmul float %33, %34
store float %35, float* %13
store i32 0, i32* %14
br label %36
36: ; preds = %61, %26
%37 = load i32, i32* %14
%38 = load i32, i32* %11
%39 = icmp slt i32 %37, %38
br i1 %39, label %40, label %64
40: ; preds = %36
%41 = load i8*, i8** %6
%42 = load i32, i32* %14
%43 = sext i32 %42 to i64
%44 = getelementptr i8, i8* %41, i64 %43
%45 = load i8, i8* %44
store i8 %45, i8* %15
%46 = load i8*, i8** %8
%47 = load i32, i32* %14
%48 = sext i32 %47 to i64
%49 = getelementptr i8, i8* %46, i64 %48
%50 = load i8, i8* %49
store i8 %50, i8* %16
%51 = load i8, i8* %15
%52 = zext i8 %51 to i32
%53 = load i8, i8* %16
%54 = zext i8 %53 to i32
%55 = icmp ne i32 %52, %54
br i1 %55, label %56, label %60
56: ; preds = %40
%57 = load float, float* %12
%58 = load float, float* %13
%59 = fadd float %58, %57
store float %59, float* %13
br label %60
60: ; preds = %56, %40
br label %61
61: ; preds = %60
%62 = load i32, i32* %14
%63 = add nsw i32 %62, 1
store i32 %63, i32* %14
br label %36
64: ; preds = %36
%65 = load float, float* %13
%66 = load float, float* %12
%67 = fcmp olt float %65, %66
br i1 %67, label %68, label %69
68: ; preds = %64
store float 0.000000e+00, float* %5
br label %71
69: ; preds = %64
%70 = load float, float* %13
store float %70, float* %5
br label %71
71: ; preds = %69, %68, %25
%72 = load float, float* %5
ret float %72
}

LLVM IR (-O2):
define float @diff(i8* nocapture %0, i32 %1, i8* nocapture %2, i32 %3) {
%5 = tail call i32 @fmax(i32 %1, i32 %3)
%6 = tail call i32 @fmin(i32 %1, i32 %3)
%7 = icmp eq i32 %5, 0
br i1 %7, label %83, label %8
8: ; preds = %4
%9 = sitofp i32 %5 to float
%10 = fdiv float 1.000000e+00, %9
%11 = sub nsw i32 %5, %6
%12 = sitofp i32 %11 to float
%13 = fmul float %10, %12
%14 = icmp sgt i32 %6, 0
br i1 %14, label %15, label %79
15: ; preds = %8
%16 = zext i32 %6 to i64
%17 = add nsw i64 %16, -1
%18 = and i64 %16, 3
%19 = icmp ult i64 %17, 3
br i1 %19, label %60, label %20
20: ; preds = %15
%21 = and i64 %16, 4294967292
br label %22
22: ; preds = %22, %20
%23 = phi i64 [ 0, %20 ], [ %57, %22 ]
%24 = phi float [ %13, %20 ], [ %56, %22 ]
%25 = phi i64 [ 0, %20 ], [ %58, %22 ]
%26 = getelementptr i8, i8* %0, i64 %23
%27 = load i8, i8* %26
%28 = getelementptr i8, i8* %2, i64 %23
%29 = load i8, i8* %28
%30 = icmp eq i8 %27, %29
%31 = select i1 %30, float -0.000000e+00, float %10
%32 = fadd float %24, %31
%33 = or i64 %23, 1
%34 = getelementptr i8, i8* %0, i64 %33
%35 = load i8, i8* %34
%36 = getelementptr i8, i8* %2, i64 %33
%37 = load i8, i8* %36
%38 = icmp eq i8 %35, %37
%39 = select i1 %38, float -0.000000e+00, float %10
%40 = fadd float %32, %39
%41 = or i64 %23, 2
%42 = getelementptr i8, i8* %0, i64 %41
%43 = load i8, i8* %42
%44 = getelementptr i8, i8* %2, i64 %41
%45 = load i8, i8* %44
%46 = icmp eq i8 %43, %45
%47 = select i1 %46, float -0.000000e+00, float %10
%48 = fadd float %40, %47
%49 = or i64 %23, 3
%50 = getelementptr i8, i8* %0, i64 %49
%51 = load i8, i8* %50
%52 = getelementptr i8, i8* %2, i64 %49
%53 = load i8, i8* %52
%54 = icmp eq i8 %51, %53
%55 = select i1 %54, float -0.000000e+00, float %10
%56 = fadd float %48, %55
%57 = add nuw nsw i64 %23, 4
%58 = add i64 %25, 4
%59 = icmp eq i64 %58, %21
br i1 %59, label %60, label %22
60: ; preds = %22, %15
%61 = phi float [ undef, %15 ], [ %56, %22 ]
%62 = phi i64 [ 0, %15 ], [ %57, %22 ]
%63 = phi float [ %13, %15 ], [ %56, %22 ]
%64 = icmp eq i64 %18, 0
br i1 %64, label %79, label %65
65: ; preds = %60, %65
%66 = phi i64 [ %76, %65 ], [ %62, %60 ]
%67 = phi float [ %75, %65 ], [ %63, %60 ]
%68 = phi i64 [ %77, %65 ], [ 0, %60 ]
%69 = getelementptr i8, i8* %0, i64 %66
%70 = load i8, i8* %69
%71 = getelementptr i8, i8* %2, i64 %66
%72 = load i8, i8* %71
%73 = icmp eq i8 %70, %72
%74 = select i1 %73, float -0.000000e+00, float %10
%75 = fadd float %67, %74
%76 = add nuw nsw i64 %66, 1
%77 = add i64 %68, 1
%78 = icmp eq i64 %77, %18
br i1 %78, label %79, label %65
79: ; preds = %60, %65, %8
%80 = phi float [ %13, %8 ], [ %61, %60 ], [ %75, %65 ]
%81 = fcmp olt float %80, %10
%82 = select i1 %81, float 0.000000e+00, float %80
br label %83
83: ; preds = %4, %79
%84 = phi float [ %82, %79 ], [ 0.000000e+00, %4 ]
ret float %84
}