#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 */
scalar_t__ isalpha(char);
int /*<<< orphan*/ strcpy(char *, char *);
char tolower(char);
char toupper(char);
char *soundex(char *in) {
  int code[] = {0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5,
                5, 0, 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2};
  char key[5], ch;
  int last, count;
  strcpy(key, "Z000");
  while (*in != '\0' && !isalpha(*in))
    ++in;
  if (*in == '\0')
    return key;
  key[0] = toupper(*in);
  last = code[key[0] - 'A'];
  ++in;
  for (count = 1; count < 4 && *in != '\0'; ++in) {
    if (isalpha(*in)) {
      ch = tolower(*in);
      if (last != code[ch - 'a']) {
        last = code[ch - 'a'];
        if (last != 0)
          key[count++] = '0' + last;
      }
    }
  }
  return key;
}


x86 assembly (clang, -O0):
<soundex>:
push   %rbp
mov    %rsp,%rbp
sub    $0xa0,%rsp
mov    %rdi,-0x10(%rbp)
lea    -0x80(%rbp),%rdi
lea    0xe96(%rip),%rsi
mov    $0x68,%edx
call   1050 <memcpy@plt>
lea    -0x85(%rbp),%rdi
lea    0xee6(%rip),%rsi
call   1030 <strcpy@plt>
mov    -0x10(%rbp),%rax
movsbl (%rax),%ecx
xor    %eax,%eax
cmp    $0x0,%ecx
mov    %al,-0x91(%rbp)
je     11ba <soundex+0x6a>
mov    -0x10(%rbp),%rax
movsbl (%rax),%edi
call   1070 <isalpha@plt>
cmp    $0x0,%rax
setne  %al
xor    $0xff,%al
mov    %al,-0x91(%rbp)
mov    -0x91(%rbp),%al
test   $0x1,%al
jne    11cd <soundex+0x7d>
jmp    11de <soundex+0x8e>
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
jmp    1187 <soundex+0x37>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x0,%eax
jne    11fe <soundex+0xae>
lea    -0x85(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    132f <soundex+0x1df>
mov    -0x10(%rbp),%rax
movsbl (%rax),%edi
call   1040 <toupper@plt>
mov    %al,-0x85(%rbp)
movsbl -0x85(%rbp),%eax
sub    $0x41,%eax
cltq
mov    -0x80(%rbp,%rax,4),%eax
mov    %eax,-0x8c(%rbp)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
movl   $0x1,-0x90(%rbp)
xor    %eax,%eax
cmpl   $0x4,-0x90(%rbp)
mov    %al,-0x92(%rbp)
jge    1264 <soundex+0x114>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x0,%eax
setne  %al
mov    %al,-0x92(%rbp)
mov    -0x92(%rbp),%al
test   $0x1,%al
jne    1277 <soundex+0x127>
jmp    1324 <soundex+0x1d4>
mov    -0x10(%rbp),%rax
movsbl (%rax),%edi
call   1070 <isalpha@plt>
cmp    $0x0,%rax
je     130e <soundex+0x1be>
mov    -0x10(%rbp),%rax
movsbl (%rax),%edi
call   1060 <tolower@plt>
mov    %al,-0x86(%rbp)
mov    -0x8c(%rbp),%eax
movsbl -0x86(%rbp),%ecx
sub    $0x61,%ecx
movslq %ecx,%rcx
cmp    -0x80(%rbp,%rcx,4),%eax
je     1309 <soundex+0x1b9>
movsbl -0x86(%rbp),%eax
sub    $0x61,%eax
cltq
mov    -0x80(%rbp,%rax,4),%eax
mov    %eax,-0x8c(%rbp)
cmpl   $0x0,-0x8c(%rbp)
je     1304 <soundex+0x1b4>
mov    -0x8c(%rbp),%eax
add    $0x30,%eax
mov    %al,%cl
mov    -0x90(%rbp),%eax
mov    %eax,%edx
add    $0x1,%edx
mov    %edx,-0x90(%rbp)
cltq
mov    %cl,-0x85(%rbp,%rax,1)
jmp    1309 <soundex+0x1b9>
jmp    130e <soundex+0x1be>
jmp    1313 <soundex+0x1c3>
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
jmp    123c <soundex+0xec>
lea    -0x85(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0xa0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<soundex>:
push   %rbp
push   %r15
push   %r14
push   %r12
push   %rbx
sub    $0x10,%rsp
mov    %rdi,%rbx
lea    0xf12(%rip),%rsi
lea    0xb(%rsp),%rdi
call   1030 <strcpy@plt>
mov    (%rbx),%al
test   %al,%al
je     1228 <soundex+0xe8>
add    $0x1,%rbx
xchg   %ax,%ax
movsbl %al,%edi
call   1060 <isalpha@plt>
test   %rax,%rax
jne    118d <soundex+0x4d>
movzbl (%rbx),%eax
add    $0x1,%rbx
test   %al,%al
jne    1170 <soundex+0x30>
jmp    1228 <soundex+0xe8>
mov    -0x1(%rbx),%al
test   %al,%al
je     1228 <soundex+0xe8>
movsbl %al,%edi
call   1040 <toupper@plt>
mov    %al,0xb(%rsp)
movsbq %al,%rax
lea    0xe51(%rip),%r14
mov    -0x104(%r14,%rax,4),%ebp
ff
mov    $0x1,%r12d
mov    $0x1504191,%r15d
jmp    11de <soundex+0x9e>
cs nopw 0x0(%rax,%rax,1)
nop
mov    %ebp,%eax
add    $0x1,%rbx
mov    %eax,%ebp
cmp    $0x4,%r12d
jge    1228 <soundex+0xe8>
movzbl (%rbx),%eax
test   %al,%al
je     1228 <soundex+0xe8>
movsbl %al,%edi
call   1060 <isalpha@plt>
test   %rax,%rax
je     11d0 <soundex+0x90>
movsbl (%rbx),%edi
call   1050 <tolower@plt>
movsbq %al,%rcx
mov    -0x184(%r14,%rcx,4),%eax
ff
cmp    %eax,%ebp
je     11d0 <soundex+0x90>
add    $0xffffffffffffff9f,%rcx
bt     %rcx,%r15
jb     1224 <soundex+0xe4>
lea    0x30(%rax),%ecx
movslq %r12d,%rdx
add    $0x1,%r12d
mov    %cl,0xb(%rsp,%rdx,1)
jmp    11d2 <soundex+0x92>
xor    %eax,%eax
jmp    11d2 <soundex+0x92>
lea    0xb(%rsp),%rax
add    $0x10,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@__const.soundex.code = [26 x i32] [i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 0, i32 0, i32 2, i32 2, i32 4, i32 5, i32 5, i32 0, i32 1, i32 2, i32 6, i32 2, i32 3, i32 0, i32 1, i32 0, i32 2, i32 0, i32 2]
@.str = [5 x i8] c"Z000\00"
define i8* @soundex(i8* %0) {
%2 = alloca i8*
%3 = alloca i8*
%4 = alloca [26 x i32]
%5 = alloca [5 x i8]
%6 = alloca i8
%7 = alloca i32
%8 = alloca i32
store i8* %0, i8** %3
%9 = bitcast [26 x i32]* %4 to i8*
%10 = getelementptr inbounds [5 x i8], [5 x i8]* %5, i64 0, i64 0
%11 = call i32 @strcpy(i8* %10, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0))
br label %12
12: ; preds = %25, %1
%13 = load i8*, i8** %3
%14 = load i8, i8* %13
%15 = sext i8 %14 to i32
%16 = icmp ne i32 %15, 0
br i1 %16, label %17, label %23
17: ; preds = %12
%18 = load i8*, i8** %3
%19 = load i8, i8* %18
%20 = call i64 @isalpha(i8 signext %19)
%21 = icmp ne i64 %20, 0
%22 = xor i1 %21, true
br label %23
23: ; preds = %17, %12
%24 = phi i1 [ false, %12 ], [ %22, %17 ]
br i1 %24, label %25, label %28
25: ; preds = %23
%26 = load i8*, i8** %3
%27 = getelementptr inbounds i8, i8* %26, i32 1
store i8* %27, i8** %3
br label %12
28: ; preds = %23
%29 = load i8*, i8** %3
%30 = load i8, i8* %29
%31 = sext i8 %30 to i32
%32 = icmp eq i32 %31, 0
br i1 %32, label %33, label %35
33: ; preds = %28
%34 = getelementptr inbounds [5 x i8], [5 x i8]* %5, i64 0, i64 0
store i8* %34, i8** %2
br label %101
35: ; preds = %28
%36 = load i8*, i8** %3
%37 = load i8, i8* %36
%38 = call signext i8 @toupper(i8 signext %37)
%39 = getelementptr inbounds [5 x i8], [5 x i8]* %5, i64 0, i64 0
store i8 %38, i8* %39
%40 = getelementptr inbounds [5 x i8], [5 x i8]* %5, i64 0, i64 0
%41 = load i8, i8* %40
%42 = sext i8 %41 to i32
%43 = sub nsw i32 %42, 65
%44 = sext i32 %43 to i64
%45 = getelementptr inbounds [26 x i32], [26 x i32]* %4, i64 0, i64 %44
%46 = load i32, i32* %45
store i32 %46, i32* %7
%47 = load i8*, i8** %3
%48 = getelementptr inbounds i8, i8* %47, i32 1
store i8* %48, i8** %3
store i32 1, i32* %8
br label %49
49: ; preds = %96, %35
%50 = load i32, i32* %8
%51 = icmp slt i32 %50, 4
br i1 %51, label %52, label %57
52: ; preds = %49
%53 = load i8*, i8** %3
%54 = load i8, i8* %53
%55 = sext i8 %54 to i32
%56 = icmp ne i32 %55, 0
br label %57
57: ; preds = %52, %49
%58 = phi i1 [ false, %49 ], [ %56, %52 ]
br i1 %58, label %59, label %99
59: ; preds = %57
%60 = load i8*, i8** %3
%61 = load i8, i8* %60
%62 = call i64 @isalpha(i8 signext %61)
%63 = icmp ne i64 %62, 0
br i1 %63, label %64, label %95
64: ; preds = %59
%65 = load i8*, i8** %3
%66 = load i8, i8* %65
%67 = call signext i8 @tolower(i8 signext %66)
store i8 %67, i8* %6
%68 = load i32, i32* %7
%69 = load i8, i8* %6
%70 = sext i8 %69 to i32
%71 = sub nsw i32 %70, 97
%72 = sext i32 %71 to i64
%73 = getelementptr inbounds [26 x i32], [26 x i32]* %4, i64 0, i64 %72
%74 = load i32, i32* %73
%75 = icmp ne i32 %68, %74
br i1 %75, label %76, label %94
76: ; preds = %64
%77 = load i8, i8* %6
%78 = sext i8 %77 to i32
%79 = sub nsw i32 %78, 97
%80 = sext i32 %79 to i64
%81 = getelementptr inbounds [26 x i32], [26 x i32]* %4, i64 0, i64 %80
%82 = load i32, i32* %81
store i32 %82, i32* %7
%83 = load i32, i32* %7
%84 = icmp ne i32 %83, 0
br i1 %84, label %85, label %93
85: ; preds = %76
%86 = load i32, i32* %7
%87 = add nsw i32 48, %86
%88 = trunc i32 %87 to i8
%89 = load i32, i32* %8
%90 = add nsw i32 %89, 1
store i32 %90, i32* %8
%91 = sext i32 %89 to i64
%92 = getelementptr inbounds [5 x i8], [5 x i8]* %5, i64 0, i64 %91
store i8 %88, i8* %92
br label %93
93: ; preds = %85, %76
br label %94
94: ; preds = %93, %64
br label %95
95: ; preds = %94, %59
br label %96
96: ; preds = %95
%97 = load i8*, i8** %3
%98 = getelementptr inbounds i8, i8* %97, i32 1
store i8* %98, i8** %3
br label %49
99: ; preds = %57
%100 = getelementptr inbounds [5 x i8], [5 x i8]* %5, i64 0, i64 0
store i8* %100, i8** %2
br label %101
101: ; preds = %99, %33
%102 = load i8*, i8** %2
ret i8* %102
}

LLVM IR (-O2):
@__const.soundex.code = [26 x i32] [i32 0, i32 1, i32 2, i32 3, i32 0, i32 1, i32 2, i32 0, i32 0, i32 2, i32 2, i32 4, i32 5, i32 5, i32 0, i32 1, i32 2, i32 6, i32 2, i32 3, i32 0, i32 1, i32 0, i32 2, i32 0, i32 2]
@.str = [5 x i8] c"Z000\00"
define i8* @soundex(i8* nocapture %0) {
%2 = alloca [5 x i8]
%3 = getelementptr inbounds [5 x i8], [5 x i8]* %2, i64 0, i64 0
%4 = call i32 @strcpy(i8* %3, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i64 0, i64 0))
%5 = load i8, i8* %0
%6 = icmp eq i8 %5, 0
br i1 %6, label %57, label %7
7: ; preds = %1, %12
%8 = phi i8 [ %14, %12 ], [ %5, %1 ]
%9 = phi i8* [ %13, %12 ], [ %0, %1 ]
%10 = call i64 @isalpha(i8 signext %8)
%11 = icmp eq i64 %10, 0
br i1 %11, label %12, label %16
12: ; preds = %7
%13 = getelementptr inbounds i8, i8* %9, i64 1
%14 = load i8, i8* %13
%15 = icmp eq i8 %14, 0
br i1 %15, label %57, label %7
16: ; preds = %7
%17 = load i8, i8* %9
%18 = icmp eq i8 %17, 0
br i1 %18, label %57, label %19
19: ; preds = %16
%20 = call signext i8 @toupper(i8 signext %17)
store i8 %20, i8* %3
%21 = sext i8 %20 to i64
%22 = add nsw i64 %21, -65
%23 = getelementptr inbounds [26 x i32], [26 x i32]* @__const.soundex.code, i64 0, i64 %22
%24 = load i32, i32* %23
br label %25
25: ; preds = %19, %53
%26 = phi i8* [ %9, %19 ], [ %29, %53 ]
%27 = phi i32 [ 1, %19 ], [ %55, %53 ]
%28 = phi i32 [ %24, %19 ], [ %54, %53 ]
%29 = getelementptr inbounds i8, i8* %26, i64 1
%30 = load i8, i8* %29
%31 = icmp eq i8 %30, 0
br i1 %31, label %57, label %32
32: ; preds = %25
%33 = call i64 @isalpha(i8 signext %30)
%34 = icmp eq i64 %33, 0
br i1 %34, label %53, label %35
35: ; preds = %32
%36 = load i8, i8* %29
%37 = call signext i8 @tolower(i8 signext %36)
%38 = sext i8 %37 to i64
%39 = add nsw i64 %38, -97
%40 = getelementptr inbounds [26 x i32], [26 x i32]* @__const.soundex.code, i64 0, i64 %39
%41 = load i32, i32* %40
%42 = icmp eq i32 %28, %41
br i1 %42, label %53, label %43
43: ; preds = %35
%44 = lshr i64 22036881, %39
%45 = and i64 %44, 1
%46 = icmp eq i64 %45, 0
br i1 %46, label %47, label %53
47: ; preds = %43
%48 = trunc i32 %41 to i8
%49 = add i8 %48, 48
%50 = add nsw i32 %27, 1
%51 = sext i32 %27 to i64
%52 = getelementptr inbounds [5 x i8], [5 x i8]* %2, i64 0, i64 %51
store i8 %49, i8* %52
br label %53
53: ; preds = %32, %43, %47, %35
%54 = phi i32 [ %41, %47 ], [ 0, %43 ], [ %28, %35 ], [ %28, %32 ]
%55 = phi i32 [ %50, %47 ], [ %27, %43 ], [ %27, %35 ], [ %27, %32 ]
%56 = icmp slt i32 %55, 4
br i1 %56, label %25, label %57
57: ; preds = %12, %25, %53, %1, %16
ret i8* %3
}