int my_atoi_ltr(char *str) {
  char *start;
  int n = 0, base = 10, exponent = 0;
  if (!str)
    return 0;
  for (start = str; *start; start++) {
    if (*start >= 'A' && *start <= 'F')
      *start += 0x20;
    if (*start >= 'a' && *start <= 'f')
      base = 16;
  }
  for (start = str; *start; start++) {
    if (!((*start >= '0' && *start <= '9') ||
          (base == 16 && *start >= 'a' && *start <= 'f')))
      break;
    else
      exponent = (!exponent ? 1 : exponent * base);
  }
  start = str;
  while (*start && exponent >= 1) {
    if (*start >= '0' && *start <= '9')
      n += (*start - '0') * exponent;
    else if (*start >= 'a' && *start <= 'f' && base == 16)
      n += (0x0A + (*start - 'a')) * exponent;
    else
      break;
    start++;
    exponent /= base;
  }
  return n;
}


x86 assembly (clang, -O0):
<my_atoi_ltr>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
movl   $0x0,-0x1c(%rbp)
movl   $0xa,-0x20(%rbp)
movl   $0x0,-0x24(%rbp)
cmpq   $0x0,-0x10(%rbp)
jne    1134 <my_atoi_ltr+0x34>
movl   $0x0,-0x4(%rbp)
jmp    1336 <my_atoi_ltr+0x236>
mov    -0x10(%rbp),%rax
mov    %rax,-0x18(%rbp)
mov    -0x18(%rbp),%rax
cmpb   $0x0,(%rax)
je     11b2 <my_atoi_ltr+0xb2>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x41,%eax
jl     1175 <my_atoi_ltr+0x75>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x46,%eax
jg     1175 <my_atoi_ltr+0x75>
mov    -0x18(%rbp),%rax
movsbl (%rax),%ecx
add    $0x20,%ecx
mov    %cl,(%rax)
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x61,%eax
jl     119c <my_atoi_ltr+0x9c>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x66,%eax
jg     119c <my_atoi_ltr+0x9c>
movl   $0x10,-0x20(%rbp)
jmp    11a1 <my_atoi_ltr+0xa1>
mov    -0x18(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x18(%rbp)
jmp    113c <my_atoi_ltr+0x3c>
mov    -0x10(%rbp),%rax
mov    %rax,-0x18(%rbp)
mov    -0x18(%rbp),%rax
cmpb   $0x0,(%rax)
je     1253 <my_atoi_ltr+0x153>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x30,%eax
jl     11e7 <my_atoi_ltr+0xe7>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x39,%eax
jle    1216 <my_atoi_ltr+0x116>
cmpl   $0x10,-0x20(%rbp)
jne    1211 <my_atoi_ltr+0x111>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x61,%eax
jl     1211 <my_atoi_ltr+0x111>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x66,%eax
jle    1216 <my_atoi_ltr+0x116>
jmp    1253 <my_atoi_ltr+0x153>
cmpl   $0x0,-0x24(%rbp)
jne    122d <my_atoi_ltr+0x12d>
mov    $0x1,%eax
mov    %eax,-0x28(%rbp)
jmp    1237 <my_atoi_ltr+0x137>
mov    -0x24(%rbp),%eax
imul   -0x20(%rbp),%eax
mov    %eax,-0x28(%rbp)
mov    -0x28(%rbp),%eax
mov    %eax,-0x24(%rbp)
jmp    1242 <my_atoi_ltr+0x142>
mov    -0x18(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x18(%rbp)
jmp    11ba <my_atoi_ltr+0xba>
mov    -0x10(%rbp),%rax
mov    %rax,-0x18(%rbp)
mov    -0x18(%rbp),%rax
movsbl (%rax),%ecx
xor    %eax,%eax
cmp    $0x0,%ecx
mov    %al,-0x29(%rbp)
je     127a <my_atoi_ltr+0x17a>
cmpl   $0x1,-0x24(%rbp)
setge  %al
mov    %al,-0x29(%rbp)
mov    -0x29(%rbp),%al
test   $0x1,%al
jne    128a <my_atoi_ltr+0x18a>
jmp    1330 <my_atoi_ltr+0x230>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x30,%eax
jl     12c3 <my_atoi_ltr+0x1c3>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x39,%eax
jg     12c3 <my_atoi_ltr+0x1c3>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
sub    $0x30,%eax
imul   -0x24(%rbp),%eax
add    -0x1c(%rbp),%eax
mov    %eax,-0x1c(%rbp)
jmp    1313 <my_atoi_ltr+0x213>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x61,%eax
jl     1309 <my_atoi_ltr+0x209>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x66,%eax
jg     1309 <my_atoi_ltr+0x209>
cmpl   $0x10,-0x20(%rbp)
jne    1309 <my_atoi_ltr+0x209>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
sub    $0x61,%eax
add    $0xa,%eax
imul   -0x24(%rbp),%eax
add    -0x1c(%rbp),%eax
mov    %eax,-0x1c(%rbp)
jmp    130e <my_atoi_ltr+0x20e>
jmp    1330 <my_atoi_ltr+0x230>
jmp    1313 <my_atoi_ltr+0x213>
mov    -0x18(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x18(%rbp)
mov    -0x20(%rbp),%ecx
mov    -0x24(%rbp),%eax
cltd
idiv   %ecx
mov    %eax,-0x24(%rbp)
jmp    125b <my_atoi_ltr+0x15b>
mov    -0x1c(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<my_atoi_ltr>:
xor    %r10d,%r10d
test   %rdi,%rdi
je     11f4 <my_atoi_ltr+0xf4>
mov    (%rdi),%al
test   %al,%al
je     11f4 <my_atoi_ltr+0xf4>
lea    0x1(%rdi),%rdx
mov    $0xa,%esi
mov    $0x10,%r8d
jmp    1143 <my_atoi_ltr+0x43>
nopw   0x0(%rax,%rax,1)
add    $0x9f,%al
cmp    $0x6,%al
cmovb  %r8d,%esi
movzbl (%rdx),%eax
add    $0x1,%rdx
test   %al,%al
je     1152 <my_atoi_ltr+0x52>
lea    -0x41(%rax),%ecx
cmp    $0x5,%cl
ja     1130 <my_atoi_ltr+0x30>
add    $0x20,%al
mov    %al,-0x1(%rdx)
jmp    1130 <my_atoi_ltr+0x30>
mov    (%rdi),%r9b
test   %r9b,%r9b
je     11f4 <my_atoi_ltr+0xf4>
lea    0x1(%rdi),%rcx
xor    %r10d,%r10d
mov    $0x1,%r8d
mov    %r9d,%edx
jmp    118b <my_atoi_ltr+0x8b>
mov    %r10d,%eax
imul   %esi,%eax
test   %r10d,%r10d
cmove  %r8d,%eax
movzbl (%rcx),%edx
add    $0x1,%rcx
mov    %eax,%r10d
test   %dl,%dl
je     11a2 <my_atoi_ltr+0xa2>
lea    -0x30(%rdx),%eax
cmp    $0xa,%al
jb     1170 <my_atoi_ltr+0x70>
cmp    $0x10,%esi
jne    11f8 <my_atoi_ltr+0xf8>
add    $0x9f,%dl
cmp    $0x5,%dl
jbe    1170 <my_atoi_ltr+0x70>
mov    %r10d,%eax
test   %eax,%eax
jle    11ff <my_atoi_ltr+0xff>
add    $0x1,%rdi
xor    %r10d,%r10d
nopl   (%rax)
lea    -0x30(%r9),%ecx
mov    $0xffffffd0,%edx
cmp    $0xa,%cl
jb     11d4 <my_atoi_ltr+0xd4>
cmp    $0x61,%r9b
jl     11f4 <my_atoi_ltr+0xf4>
cmp    $0x66,%r9b
ja     11f4 <my_atoi_ltr+0xf4>
mov    $0xffffffa9,%edx
cmp    $0x10,%esi
jne    11f4 <my_atoi_ltr+0xf4>
movsbl %r9b,%ecx
add    %edx,%ecx
imul   %eax,%ecx
add    %ecx,%r10d
cltd
idiv   %esi
movzbl (%rdi),%r9d
test   %r9b,%r9b
je     11f4 <my_atoi_ltr+0xf4>
add    $0x1,%rdi
test   %eax,%eax
jg     11b0 <my_atoi_ltr+0xb0>
mov    %r10d,%eax
ret
mov    %r10d,%eax
test   %eax,%eax
jg     11a6 <my_atoi_ltr+0xa6>
xor    %eax,%eax
ret

LLVM IR (-O0):
define i32 @my_atoi_ltr(i8* %0) {
%2 = alloca i32
%3 = alloca i8*
%4 = alloca i8*
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
store i8* %0, i8** %3
store i32 0, i32* %5
store i32 10, i32* %6
store i32 0, i32* %7
%8 = load i8*, i8** %3
%9 = icmp ne i8* %8, null
br i1 %9, label %11, label %10
10: ; preds = %1
store i32 0, i32* %2
br label %156
11: ; preds = %1
%12 = load i8*, i8** %3
store i8* %12, i8** %4
br label %13
13: ; preds = %45, %11
%14 = load i8*, i8** %4
%15 = load i8, i8* %14
%16 = icmp ne i8 %15, 0
br i1 %16, label %17, label %48
17: ; preds = %13
%18 = load i8*, i8** %4
%19 = load i8, i8* %18
%20 = sext i8 %19 to i32
%21 = icmp sge i32 %20, 65
br i1 %21, label %22, label %33
22: ; preds = %17
%23 = load i8*, i8** %4
%24 = load i8, i8* %23
%25 = sext i8 %24 to i32
%26 = icmp sle i32 %25, 70
br i1 %26, label %27, label %33
27: ; preds = %22
%28 = load i8*, i8** %4
%29 = load i8, i8* %28
%30 = sext i8 %29 to i32
%31 = add nsw i32 %30, 32
%32 = trunc i32 %31 to i8
store i8 %32, i8* %28
br label %33
33: ; preds = %27, %22, %17
%34 = load i8*, i8** %4
%35 = load i8, i8* %34
%36 = sext i8 %35 to i32
%37 = icmp sge i32 %36, 97
br i1 %37, label %38, label %44
38: ; preds = %33
%39 = load i8*, i8** %4
%40 = load i8, i8* %39
%41 = sext i8 %40 to i32
%42 = icmp sle i32 %41, 102
br i1 %42, label %43, label %44
43: ; preds = %38
store i32 16, i32* %6
br label %44
44: ; preds = %43, %38, %33
br label %45
45: ; preds = %44
%46 = load i8*, i8** %4
%47 = getelementptr inbounds i8, i8* %46, i32 1
store i8* %47, i8** %4
br label %13
48: ; preds = %13
%49 = load i8*, i8** %3
store i8* %49, i8** %4
br label %50
50: ; preds = %89, %48
%51 = load i8*, i8** %4
%52 = load i8, i8* %51
%53 = icmp ne i8 %52, 0
br i1 %53, label %54, label %92
54: ; preds = %50
%55 = load i8*, i8** %4
%56 = load i8, i8* %55
%57 = sext i8 %56 to i32
%58 = icmp sge i32 %57, 48
br i1 %58, label %59, label %64
59: ; preds = %54
%60 = load i8*, i8** %4
%61 = load i8, i8* %60
%62 = sext i8 %61 to i32
%63 = icmp sle i32 %62, 57
br i1 %63, label %78, label %64
64: ; preds = %59, %54
%65 = load i32, i32* %6
%66 = icmp eq i32 %65, 16
br i1 %66, label %67, label %77
67: ; preds = %64
%68 = load i8*, i8** %4
%69 = load i8, i8* %68
%70 = sext i8 %69 to i32
%71 = icmp sge i32 %70, 97
br i1 %71, label %72, label %77
72: ; preds = %67
%73 = load i8*, i8** %4
%74 = load i8, i8* %73
%75 = sext i8 %74 to i32
%76 = icmp sle i32 %75, 102
br i1 %76, label %78, label %77
77: ; preds = %72, %67, %64
br label %92
78: ; preds = %72, %59
%79 = load i32, i32* %7
%80 = icmp ne i32 %79, 0
br i1 %80, label %82, label %81
81: ; preds = %78
br label %86
82: ; preds = %78
%83 = load i32, i32* %7
%84 = load i32, i32* %6
%85 = mul nsw i32 %83, %84
br label %86
86: ; preds = %82, %81
%87 = phi i32 [ 1, %81 ], [ %85, %82 ]
store i32 %87, i32* %7
br label %88
88: ; preds = %86
br label %89
89: ; preds = %88
%90 = load i8*, i8** %4
%91 = getelementptr inbounds i8, i8* %90, i32 1
store i8* %91, i8** %4
br label %50
92: ; preds = %77, %50
%93 = load i8*, i8** %3
store i8* %93, i8** %4
br label %94
94: ; preds = %148, %92
%95 = load i8*, i8** %4
%96 = load i8, i8* %95
%97 = sext i8 %96 to i32
%98 = icmp ne i32 %97, 0
br i1 %98, label %99, label %102
99: ; preds = %94
%100 = load i32, i32* %7
%101 = icmp sge i32 %100, 1
br label %102
102: ; preds = %99, %94
%103 = phi i1 [ false, %94 ], [ %101, %99 ]
br i1 %103, label %104, label %154
104: ; preds = %102
%105 = load i8*, i8** %4
%106 = load i8, i8* %105
%107 = sext i8 %106 to i32
%108 = icmp sge i32 %107, 48
br i1 %108, label %109, label %123
109: ; preds = %104
%110 = load i8*, i8** %4
%111 = load i8, i8* %110
%112 = sext i8 %111 to i32
%113 = icmp sle i32 %112, 57
br i1 %113, label %114, label %123
114: ; preds = %109
%115 = load i8*, i8** %4
%116 = load i8, i8* %115
%117 = sext i8 %116 to i32
%118 = sub nsw i32 %117, 48
%119 = load i32, i32* %7
%120 = mul nsw i32 %118, %119
%121 = load i32, i32* %5
%122 = add nsw i32 %121, %120
store i32 %122, i32* %5
br label %148
123: ; preds = %109, %104
%124 = load i8*, i8** %4
%125 = load i8, i8* %124
%126 = sext i8 %125 to i32
%127 = icmp sge i32 %126, 97
br i1 %127, label %128, label %146
128: ; preds = %123
%129 = load i8*, i8** %4
%130 = load i8, i8* %129
%131 = sext i8 %130 to i32
%132 = icmp sle i32 %131, 102
br i1 %132, label %133, label %146
133: ; preds = %128
%134 = load i32, i32* %6
%135 = icmp eq i32 %134, 16
br i1 %135, label %136, label %146
136: ; preds = %133
%137 = load i8*, i8** %4
%138 = load i8, i8* %137
%139 = sext i8 %138 to i32
%140 = sub nsw i32 %139, 97
%141 = add nsw i32 10, %140
%142 = load i32, i32* %7
%143 = mul nsw i32 %141, %142
%144 = load i32, i32* %5
%145 = add nsw i32 %144, %143
store i32 %145, i32* %5
br label %147
146: ; preds = %133, %128, %123
br label %154
147: ; preds = %136
br label %148
148: ; preds = %147, %114
%149 = load i8*, i8** %4
%150 = getelementptr inbounds i8, i8* %149, i32 1
store i8* %150, i8** %4
%151 = load i32, i32* %6
%152 = load i32, i32* %7
%153 = sdiv i32 %152, %151
store i32 %153, i32* %7
br label %94
154: ; preds = %146, %102
%155 = load i32, i32* %5
store i32 %155, i32* %2
br label %156
156: ; preds = %154, %10
%157 = load i32, i32* %2
ret i32 %157
}

LLVM IR (-O2):
define i32 @my_atoi_ltr(i8* %0) {
%2 = icmp eq i8* %0, null
br i1 %2, label %73, label %3
3: ; preds = %1
%4 = load i8, i8* %0
%5 = icmp eq i8 %4, 0
br i1 %5, label %73, label %11
6: ; preds = %19
%7 = load i8, i8* %0
%8 = icmp eq i8 %7, 0
br i1 %8, label %73, label %9
9: ; preds = %6
%10 = icmp eq i32 %23, 16
br label %27
11: ; preds = %3, %19
%12 = phi i8 [ %25, %19 ], [ %4, %3 ]
%13 = phi i32 [ %23, %19 ], [ 10, %3 ]
%14 = phi i8* [ %24, %19 ], [ %0, %3 ]
%15 = add i8 %12, -65
%16 = icmp ult i8 %15, 6
br i1 %16, label %17, label %19
17: ; preds = %11
%18 = add nuw nsw i8 %12, 32
store i8 %18, i8* %14
br label %19
19: ; preds = %17, %11
%20 = phi i8 [ %18, %17 ], [ %12, %11 ]
%21 = add i8 %20, -97
%22 = icmp ult i8 %21, 6
%23 = select i1 %22, i32 16, i32 %13
%24 = getelementptr inbounds i8, i8* %14, i64 1
%25 = load i8, i8* %24
%26 = icmp eq i8 %25, 0
br i1 %26, label %6, label %11
27: ; preds = %9, %37
%28 = phi i8 [ %7, %9 ], [ %42, %37 ]
%29 = phi i32 [ 0, %9 ], [ %40, %37 ]
%30 = phi i8* [ %0, %9 ], [ %41, %37 ]
%31 = add i8 %28, -48
%32 = icmp ult i8 %31, 10
br i1 %32, label %37, label %33
33: ; preds = %27
%34 = add i8 %28, -97
%35 = icmp ult i8 %34, 6
%36 = select i1 %10, i1 %35, i1 false
br i1 %36, label %37, label %44
37: ; preds = %33, %27
%38 = icmp eq i32 %29, 0
%39 = mul nsw i32 %29, %23
%40 = select i1 %38, i32 1, i32 %39
%41 = getelementptr inbounds i8, i8* %30, i64 1
%42 = load i8, i8* %41
%43 = icmp eq i8 %42, 0
br i1 %43, label %44, label %27
44: ; preds = %37, %33
%45 = phi i32 [ %40, %37 ], [ %29, %33 ]
%46 = icmp sgt i32 %45, 0
br i1 %46, label %47, label %73
47: ; preds = %44
%48 = icmp eq i32 %23, 16
br label %49
49: ; preds = %47, %62
%50 = phi i8 [ %7, %47 ], [ %69, %62 ]
%51 = phi i32 [ %45, %47 ], [ %68, %62 ]
%52 = phi i32 [ 0, %47 ], [ %66, %62 ]
%53 = phi i8* [ %0, %47 ], [ %67, %62 ]
%54 = sext i8 %50 to i32
%55 = add i8 %50, -48
%56 = icmp ult i8 %55, 10
br i1 %56, label %62, label %57
57: ; preds = %49
%58 = icmp sgt i8 %50, 96
br i1 %58, label %59, label %73
59: ; preds = %57
%60 = icmp ult i8 %50, 103
%61 = select i1 %60, i1 %48, i1 false
br i1 %61, label %62, label %73
62: ; preds = %59, %49
%63 = phi i32 [ -48, %49 ], [ -87, %59 ]
%64 = add nsw i32 %63, %54
%65 = mul nsw i32 %64, %51
%66 = add nsw i32 %65, %52
%67 = getelementptr inbounds i8, i8* %53, i64 1
%68 = sdiv i32 %51, %23
%69 = load i8, i8* %67
%70 = icmp ne i8 %69, 0
%71 = icmp sgt i32 %68, 0
%72 = select i1 %70, i1 %71, i1 false
br i1 %72, label %49, label %73
73: ; preds = %57, %59, %62, %3, %6, %44, %1
%74 = phi i32 [ 0, %1 ], [ 0, %44 ], [ 0, %6 ], [ 0, %3 ], [ %52, %57 ], [ %52, %59 ], [ %66, %62 ]
ret i32 %74
}