#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 /*<<< orphan*/ free(short *);
short *make_pair_table(char const *);
int bp_distance(const char *str1, const char *str2) {
  int dist;
  short i, l;
  short *t1, *t2;
  dist = 0;
  t1 = make_pair_table(str1);
  t2 = make_pair_table(str2);
  l = (t1[0] < t2[0]) ? t1[0] : t2[0];
  for (i = 1; i <= l; i++)
    if (t1[i] != t2[i]) {
      if (t1[i] > i)
        dist++;
      if (t2[i] > i)
        dist++;
    }
  free(t1);
  free(t2);
  return dist;
}


x86 assembly (clang, -O0):
<bp_distance>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movl   $0x0,-0x14(%rbp)
mov    -0x8(%rbp),%rdi
call   1040 <make_pair_table@plt>
mov    %rax,-0x20(%rbp)
mov    -0x10(%rbp),%rdi
call   1040 <make_pair_table@plt>
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rax
movswl (%rax),%eax
mov    -0x28(%rbp),%rcx
movswl (%rcx),%ecx
cmp    %ecx,%eax
jge    1176 <bp_distance+0x56>
mov    -0x20(%rbp),%rax
movswl (%rax),%eax
mov    %eax,-0x2c(%rbp)
jmp    1180 <bp_distance+0x60>
mov    -0x28(%rbp),%rax
movswl (%rax),%eax
mov    %eax,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
mov    %ax,-0x18(%rbp)
movw   $0x1,-0x16(%rbp)
movswl -0x16(%rbp),%eax
movswl -0x18(%rbp),%ecx
cmp    %ecx,%eax
jg     121e <bp_distance+0xfe>
mov    -0x20(%rbp),%rax
movswq -0x16(%rbp),%rcx
movswl (%rax,%rcx,2),%eax
mov    -0x28(%rbp),%rcx
movswq -0x16(%rbp),%rdx
movswl (%rcx,%rdx,2),%ecx
cmp    %ecx,%eax
je     1208 <bp_distance+0xe8>
mov    -0x20(%rbp),%rax
movswq -0x16(%rbp),%rcx
movswl (%rax,%rcx,2),%eax
movswl -0x16(%rbp),%ecx
cmp    %ecx,%eax
jle    11e1 <bp_distance+0xc1>
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
mov    -0x28(%rbp),%rax
movswq -0x16(%rbp),%rcx
movswl (%rax,%rcx,2),%eax
movswl -0x16(%rbp),%ecx
cmp    %ecx,%eax
jle    1203 <bp_distance+0xe3>
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1208 <bp_distance+0xe8>
jmp    120d <bp_distance+0xed>
mov    -0x16(%rbp),%ax
add    $0x1,%ax
mov    %ax,-0x16(%rbp)
jmp    118d <bp_distance+0x6d>
mov    -0x20(%rbp),%rdi
call   1030 <free@plt>
mov    -0x28(%rbp),%rdi
call   1030 <free@plt>
mov    -0x14(%rbp),%eax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<bp_distance>:
push   %rbp
push   %r14
push   %rbx
mov    %rsi,%rbx
call   1040 <make_pair_table@plt>
mov    %rax,%r14
mov    %rbx,%rdi
call   1040 <make_pair_table@plt>
mov    %rax,%rbx
movzwl (%r14),%ecx
movzwl (%rax),%eax
cmp    %ax,%cx
cmovl  %ecx,%eax
test   %ax,%ax
jle    1189 <bp_distance+0x69>
movzwl %ax,%r8d
cmp    $0x1,%ax
jne    11a2 <bp_distance+0x82>
xor    %ebp,%ebp
mov    $0x1,%eax
test   $0x1,%r8b
je     118b <bp_distance+0x6b>
movswq (%r14,%rax,2),%rdx
movswq (%rbx,%rax,2),%rcx
cmp    %cx,%dx
je     118b <bp_distance+0x6b>
xor    %esi,%esi
cmp    %rdx,%rax
setl   %sil
add    %esi,%ebp
xor    %edx,%edx
cmp    %rcx,%rax
setl   %dl
add    %edx,%ebp
jmp    118b <bp_distance+0x6b>
xor    %ebp,%ebp
mov    %r14,%rdi
call   1030 <free@plt>
mov    %rbx,%rdi
call   1030 <free@plt>
mov    %ebp,%eax
pop    %rbx
pop    %r14
pop    %rbp
ret
mov    %r8d,%r9d
and    $0xfffffffe,%r9d
neg    %r9
xor    %ebp,%ebp
mov    $0x1,%eax
jmp    11d2 <bp_distance+0xb2>
cs nopw 0x0(%rax,%rax,1)
nop
lea    (%r9,%rax,1),%rcx
add    $0x2,%rcx
add    $0x2,%rax
cmp    $0x1,%rcx
je     115d <bp_distance+0x3d>
movswq (%r14,%rax,2),%rdi
movswq (%rbx,%rax,2),%rsi
cmp    %si,%di
je     11f5 <bp_distance+0xd5>
xor    %ecx,%ecx
cmp    %rdi,%rax
setl   %cl
add    %ecx,%ebp
xor    %ecx,%ecx
cmp    %rsi,%rax
setl   %cl
add    %ecx,%ebp
movswq 0x2(%r14,%rax,2),%rdi
movswq 0x2(%rbx,%rax,2),%rsi
cmp    %si,%di
je     11c0 <bp_distance+0xa0>
lea    0x1(%rax),%rcx
xor    %edx,%edx
cmp    %rdi,%rcx
setl   %dl
add    %edx,%ebp
xor    %edx,%edx
cmp    %rsi,%rcx
setl   %dl
add    %edx,%ebp
jmp    11c0 <bp_distance+0xa0>

LLVM IR (-O0):
define i32 @bp_distance(i8* %0, i8* %1) {
%3 = alloca i8*
%4 = alloca i8*
%5 = alloca i32
%6 = alloca i16
%7 = alloca i16
%8 = alloca i16*
%9 = alloca i16*
store i8* %0, i8** %3
store i8* %1, i8** %4
store i32 0, i32* %5
%10 = load i8*, i8** %3
%11 = call i16* @make_pair_table(i8* %10)
store i16* %11, i16** %8
%12 = load i8*, i8** %4
%13 = call i16* @make_pair_table(i8* %12)
store i16* %13, i16** %9
%14 = load i16*, i16** %8
%15 = getelementptr inbounds i16, i16* %14, i64 0
%16 = load i16, i16* %15
%17 = sext i16 %16 to i32
%18 = load i16*, i16** %9
%19 = getelementptr inbounds i16, i16* %18, i64 0
%20 = load i16, i16* %19
%21 = sext i16 %20 to i32
%22 = icmp slt i32 %17, %21
br i1 %22, label %23, label %28
23: ; preds = %2
%24 = load i16*, i16** %8
%25 = getelementptr inbounds i16, i16* %24, i64 0
%26 = load i16, i16* %25
%27 = sext i16 %26 to i32
br label %33
28: ; preds = %2
%29 = load i16*, i16** %9
%30 = getelementptr inbounds i16, i16* %29, i64 0
%31 = load i16, i16* %30
%32 = sext i16 %31 to i32
br label %33
33: ; preds = %28, %23
%34 = phi i32 [ %27, %23 ], [ %32, %28 ]
%35 = trunc i32 %34 to i16
store i16 %35, i16* %7
store i16 1, i16* %6
br label %36
36: ; preds = %84, %33
%37 = load i16, i16* %6
%38 = sext i16 %37 to i32
%39 = load i16, i16* %7
%40 = sext i16 %39 to i32
%41 = icmp sle i32 %38, %40
br i1 %41, label %42, label %87
42: ; preds = %36
%43 = load i16*, i16** %8
%44 = load i16, i16* %6
%45 = sext i16 %44 to i64
%46 = getelementptr inbounds i16, i16* %43, i64 %45
%47 = load i16, i16* %46
%48 = sext i16 %47 to i32
%49 = load i16*, i16** %9
%50 = load i16, i16* %6
%51 = sext i16 %50 to i64
%52 = getelementptr inbounds i16, i16* %49, i64 %51
%53 = load i16, i16* %52
%54 = sext i16 %53 to i32
%55 = icmp ne i32 %48, %54
br i1 %55, label %56, label %83
56: ; preds = %42
%57 = load i16*, i16** %8
%58 = load i16, i16* %6
%59 = sext i16 %58 to i64
%60 = getelementptr inbounds i16, i16* %57, i64 %59
%61 = load i16, i16* %60
%62 = sext i16 %61 to i32
%63 = load i16, i16* %6
%64 = sext i16 %63 to i32
%65 = icmp sgt i32 %62, %64
br i1 %65, label %66, label %69
66: ; preds = %56
%67 = load i32, i32* %5
%68 = add nsw i32 %67, 1
store i32 %68, i32* %5
br label %69
69: ; preds = %66, %56
%70 = load i16*, i16** %9
%71 = load i16, i16* %6
%72 = sext i16 %71 to i64
%73 = getelementptr inbounds i16, i16* %70, i64 %72
%74 = load i16, i16* %73
%75 = sext i16 %74 to i32
%76 = load i16, i16* %6
%77 = sext i16 %76 to i32
%78 = icmp sgt i32 %75, %77
br i1 %78, label %79, label %82
79: ; preds = %69
%80 = load i32, i32* %5
%81 = add nsw i32 %80, 1
store i32 %81, i32* %5
br label %82
82: ; preds = %79, %69
br label %83
83: ; preds = %82, %42
br label %84
84: ; preds = %83
%85 = load i16, i16* %6
%86 = add i16 %85, 1
store i16 %86, i16* %6
br label %36
87: ; preds = %36
%88 = load i16*, i16** %8
%89 = call i32 @free(i16* %88)
%90 = load i16*, i16** %9
%91 = call i32 @free(i16* %90)
%92 = load i32, i32* %5
ret i32 %92
}

LLVM IR (-O2):
define i32 @bp_distance(i8* %0, i8* %1) {
%3 = tail call i16* @make_pair_table(i8* %0)
%4 = tail call i16* @make_pair_table(i8* %1)
%5 = load i16, i16* %3
%6 = load i16, i16* %4
%7 = icmp slt i16 %5, %6
%8 = select i1 %7, i16 %5, i16 %6
%9 = icmp slt i16 %8, 1
br i1 %9, label %76, label %10
10: ; preds = %2
%11 = zext i16 %8 to i64
%12 = and i64 %11, 1
%13 = icmp eq i16 %8, 1
br i1 %13, label %56, label %14
14: ; preds = %10
%15 = and i64 %11, 65534
br label %16
16: ; preds = %51, %14
%17 = phi i64 [ 1, %14 ], [ %53, %51 ]
%18 = phi i32 [ 0, %14 ], [ %52, %51 ]
%19 = phi i64 [ 0, %14 ], [ %54, %51 ]
%20 = getelementptr inbounds i16, i16* %3, i64 %17
%21 = load i16, i16* %20
%22 = getelementptr inbounds i16, i16* %4, i64 %17
%23 = load i16, i16* %22
%24 = icmp eq i16 %21, %23
br i1 %24, label %34, label %25
25: ; preds = %16
%26 = sext i16 %21 to i64
%27 = icmp slt i64 %17, %26
%28 = zext i1 %27 to i32
%29 = add nsw i32 %18, %28
%30 = sext i16 %23 to i64
%31 = icmp slt i64 %17, %30
%32 = zext i1 %31 to i32
%33 = add nsw i32 %29, %32
br label %34
34: ; preds = %25, %16
%35 = phi i32 [ %18, %16 ], [ %33, %25 ]
%36 = add nuw nsw i64 %17, 1
%37 = getelementptr inbounds i16, i16* %3, i64 %36
%38 = load i16, i16* %37
%39 = getelementptr inbounds i16, i16* %4, i64 %36
%40 = load i16, i16* %39
%41 = icmp eq i16 %38, %40
br i1 %41, label %51, label %42
42: ; preds = %34
%43 = sext i16 %38 to i64
%44 = icmp slt i64 %36, %43
%45 = zext i1 %44 to i32
%46 = add nsw i32 %35, %45
%47 = sext i16 %40 to i64
%48 = icmp slt i64 %36, %47
%49 = zext i1 %48 to i32
%50 = add nsw i32 %46, %49
br label %51
51: ; preds = %42, %34
%52 = phi i32 [ %35, %34 ], [ %50, %42 ]
%53 = add nuw nsw i64 %17, 2
%54 = add nuw nsw i64 %19, 2
%55 = icmp eq i64 %54, %15
br i1 %55, label %56, label %16
56: ; preds = %51, %10
%57 = phi i32 [ undef, %10 ], [ %52, %51 ]
%58 = phi i64 [ 1, %10 ], [ %53, %51 ]
%59 = phi i32 [ 0, %10 ], [ %52, %51 ]
%60 = icmp eq i64 %12, 0
br i1 %60, label %76, label %61
61: ; preds = %56
%62 = getelementptr inbounds i16, i16* %3, i64 %58
%63 = load i16, i16* %62
%64 = getelementptr inbounds i16, i16* %4, i64 %58
%65 = load i16, i16* %64
%66 = icmp eq i16 %63, %65
br i1 %66, label %76, label %67
67: ; preds = %61
%68 = sext i16 %63 to i64
%69 = icmp slt i64 %58, %68
%70 = zext i1 %69 to i32
%71 = add nsw i32 %59, %70
%72 = sext i16 %65 to i64
%73 = icmp slt i64 %58, %72
%74 = zext i1 %73 to i32
%75 = add nsw i32 %71, %74
br label %76
76: ; preds = %56, %67, %61, %2
%77 = phi i32 [ 0, %2 ], [ %57, %56 ], [ %59, %61 ], [ %75, %67 ]
%78 = tail call i32 @free(i16* %3)
%79 = tail call i32 @free(i16* %4)
ret i32 %77
}