int convert(char tel[]) {
  static int letter[] = {2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6,
                         6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9};
  int num = 0;
  char c;
  while ((c = *(tel++)) != '\0')
    if ('A' <= c && c < 'Z' && c != 'Q')
      num = num * 10 + letter[c - 'A'];
    else if ('0' <= c && c <= '9')
      num = num * 10 + c - '0';
  return num;
}


x86 assembly (clang, -O0):
<convert>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
movl   $0x0,-0xc(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x8(%rbp)
mov    (%rax),%al
mov    %al,-0xd(%rbp)
movsbl %al,%eax
cmp    $0x0,%eax
je     11b2 <convert+0xb2>
movsbl -0xd(%rbp),%ecx
mov    $0x41,%eax
cmp    %ecx,%eax
jg     117a <convert+0x7a>
movsbl -0xd(%rbp),%eax
cmp    $0x5a,%eax
jge    117a <convert+0x7a>
movsbl -0xd(%rbp),%eax
cmp    $0x51,%eax
je     117a <convert+0x7a>
imul   $0xa,-0xc(%rbp),%eax
movsbl -0xd(%rbp),%ecx
sub    $0x41,%ecx
movslq %ecx,%rdx
lea    0x2ec1(%rip),%rcx
add    (%rcx,%rdx,4),%eax
mov    %eax,-0xc(%rbp)
jmp    11ad <convert+0xad>
movsbl -0xd(%rbp),%ecx
mov    $0x30,%eax
cmp    %ecx,%eax
jg     11a8 <convert+0xa8>
movsbl -0xd(%rbp),%eax
cmp    $0x39,%eax
jg     11a8 <convert+0xa8>
imul   $0xa,-0xc(%rbp),%eax
movsbl -0xd(%rbp),%ecx
add    %ecx,%eax
sub    $0x30,%eax
mov    %eax,-0xc(%rbp)
jmp    11ad <convert+0xad>
jmp    110f <convert+0xf>
mov    -0xc(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<convert>:
mov    (%rdi),%dl
test   %dl,%dl
je     115b <convert+0x5b>
add    $0x1,%rdi
xor    %eax,%eax
lea    0xeed(%rip),%r8
jmp    1137 <convert+0x37>
cs nopw 0x0(%rax,%rax,1)
nop
lea    (%rax,%rax,4),%eax
add    %eax,%eax
add    $0xffffffbf,%esi
add    (%r8,%rsi,4),%eax
movzbl (%rdi),%edx
add    $0x1,%rdi
test   %dl,%dl
je     115a <convert+0x5a>
movsbl %dl,%esi
cmp    $0x51,%dl
je     1147 <convert+0x47>
lea    -0x41(%rdx),%ecx
cmp    $0x18,%cl
jbe    1120 <convert+0x20>
add    $0xd0,%dl
cmp    $0x9,%dl
ja     112c <convert+0x2c>
lea    (%rax,%rax,4),%eax
lea    (%rsi,%rax,2),%eax
add    $0xffffffd0,%eax
jmp    112c <convert+0x2c>
ret
xor    %eax,%eax
ret

LLVM IR (-O0):
@convert.letter = internal global [26 x i32] [i32 2, i32 2, i32 2, i32 3, i32 3, i32 3, i32 4, i32 4, i32 4, i32 5, i32 5, i32 5, i32 6, i32 6, i32 6, i32 7, i32 7, i32 7, i32 7, i32 8, i32 8, i32 8, i32 9, i32 9, i32 9, i32 9]
define i32 @convert(i8* %0) {
%2 = alloca i8*
%3 = alloca i32
%4 = alloca i8
store i8* %0, i8** %2
store i32 0, i32* %3
br label %5
5: ; preds = %49, %1
%6 = load i8*, i8** %2
%7 = getelementptr inbounds i8, i8* %6, i32 1
store i8* %7, i8** %2
%8 = load i8, i8* %6
store i8 %8, i8* %4
%9 = sext i8 %8 to i32
%10 = icmp ne i32 %9, 0
br i1 %10, label %11, label %50
11: ; preds = %5
%12 = load i8, i8* %4
%13 = sext i8 %12 to i32
%14 = icmp sle i32 65, %13
br i1 %14, label %15, label %33
15: ; preds = %11
%16 = load i8, i8* %4
%17 = sext i8 %16 to i32
%18 = icmp slt i32 %17, 90
br i1 %18, label %19, label %33
19: ; preds = %15
%20 = load i8, i8* %4
%21 = sext i8 %20 to i32
%22 = icmp ne i32 %21, 81
br i1 %22, label %23, label %33
23: ; preds = %19
%24 = load i32, i32* %3
%25 = mul nsw i32 %24, 10
%26 = load i8, i8* %4
%27 = sext i8 %26 to i32
%28 = sub nsw i32 %27, 65
%29 = sext i32 %28 to i64
%30 = getelementptr inbounds [26 x i32], [26 x i32]* @convert.letter, i64 0, i64 %29
%31 = load i32, i32* %30
%32 = add nsw i32 %25, %31
store i32 %32, i32* %3
br label %49
33: ; preds = %19, %15, %11
%34 = load i8, i8* %4
%35 = sext i8 %34 to i32
%36 = icmp sle i32 48, %35
br i1 %36, label %37, label %48
37: ; preds = %33
%38 = load i8, i8* %4
%39 = sext i8 %38 to i32
%40 = icmp sle i32 %39, 57
br i1 %40, label %41, label %48
41: ; preds = %37
%42 = load i32, i32* %3
%43 = mul nsw i32 %42, 10
%44 = load i8, i8* %4
%45 = sext i8 %44 to i32
%46 = add nsw i32 %43, %45
%47 = sub nsw i32 %46, 48
store i32 %47, i32* %3
br label %48
48: ; preds = %41, %37, %33
br label %49
49: ; preds = %48, %23
br label %5
50: ; preds = %5
%51 = load i32, i32* %3
ret i32 %51
}

LLVM IR (-O2):
@convert.letter = internal unnamed_addr constant [26 x i32] [i32 2, i32 2, i32 2, i32 3, i32 3, i32 3, i32 4, i32 4, i32 4, i32 5, i32 5, i32 5, i32 6, i32 6, i32 6, i32 7, i32 7, i32 7, i32 7, i32 8, i32 8, i32 8, i32 9, i32 9, i32 9, i32 9]
define i32 @convert(i8* nocapture %0) {
%2 = load i8, i8* %0
%3 = icmp eq i8 %2, 0
br i1 %3, label %32, label %4
4: ; preds = %1, %28
%5 = phi i8 [ %30, %28 ], [ %2, %1 ]
%6 = phi i8* [ %8, %28 ], [ %0, %1 ]
%7 = phi i32 [ %29, %28 ], [ 0, %1 ]
%8 = getelementptr inbounds i8, i8* %6, i64 1
%9 = sext i8 %5 to i32
%10 = add i8 %5, -65
%11 = icmp ult i8 %10, 25
%12 = icmp ne i8 %5, 81
%13 = and i1 %12, %11
br i1 %13, label %14, label %21
14: ; preds = %4
%15 = mul nsw i32 %7, 10
%16 = add nsw i32 %9, -65
%17 = zext i32 %16 to i64
%18 = getelementptr inbounds [26 x i32], [26 x i32]* @convert.letter, i64 0, i64 %17
%19 = load i32, i32* %18
%20 = add nsw i32 %19, %15
br label %28
21: ; preds = %4
%22 = add i8 %5, -48
%23 = icmp ult i8 %22, 10
br i1 %23, label %24, label %28
24: ; preds = %21
%25 = mul nsw i32 %7, 10
%26 = add i32 %25, -48
%27 = add i32 %26, %9
br label %28
28: ; preds = %21, %24, %14
%29 = phi i32 [ %20, %14 ], [ %27, %24 ], [ %7, %21 ]
%30 = load i8, i8* %8
%31 = icmp eq i8 %30, 0
br i1 %31, label %32, label %4
32: ; preds = %28, %1
%33 = phi i32 [ 0, %1 ], [ %29, %28 ]
ret i32 %33
}