int atoi(const char *s) {
  int result = 0;
  int sign = 1;
  while ((*s) && ((*s == ' ') || (*s == '\t'))) {
    s++;
  }
  if ((*s) && (*s == '+')) {
    s++;
  }
  if ((*s) && (*s == '-')) {
    s++;
    sign = -1;
  }
  if ((*s) && (*s == '$')) {
    s++;
    while ((*s) &&
           (((*s >= '0') && (*s <= '9')) || ((*s >= 'a') && (*s <= 'f')) ||
            ((*s >= 'A') && (*s <= 'F')))) {
      if ((*s >= '0') && (*s <= '9'))
        result = 16 * result + (*s - '0');
      else if ((*s >= 'a') && (*s <= 'f'))
        result = 16 * result + (*s - 'a' + 10);
      else if ((*s >= 'A') && (*s <= 'F'))
        result = 16 * result + (*s - 'A' + 10);
      s++;
    }
  } else {
    while ((*s) && (*s >= '0') && (*s <= '9')) {
      result = 10 * result + (*s - '0');
      s++;
    }
  }
  return sign * result;
}


x86 assembly (clang, -O0):
<atoi>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
movl   $0x0,-0xc(%rbp)
movl   $0x1,-0x10(%rbp)
mov    -0x8(%rbp),%rax
movsbl (%rax),%ecx
xor    %eax,%eax
cmp    $0x0,%ecx
mov    %al,-0x11(%rbp)
je     1156 <atoi+0x56>
mov    -0x8(%rbp),%rax
movsbl (%rax),%ecx
mov    $0x1,%al
cmp    $0x20,%ecx
mov    %al,-0x12(%rbp)
je     1150 <atoi+0x50>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x9,%eax
sete   %al
mov    %al,-0x12(%rbp)
mov    -0x12(%rbp),%al
mov    %al,-0x11(%rbp)
mov    -0x11(%rbp),%al
test   $0x1,%al
jne    1166 <atoi+0x66>
jmp    1177 <atoi+0x77>
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
jmp    1116 <atoi+0x16>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x0,%eax
je     11a3 <atoi+0xa3>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2b,%eax
jne    11a3 <atoi+0xa3>
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x0,%eax
je     11d6 <atoi+0xd6>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2d,%eax
jne    11d6 <atoi+0xd6>
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
movl   $0xffffffff,-0x10(%rbp)
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x0,%eax
je     1371 <atoi+0x271>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x24,%eax
jne    1371 <atoi+0x271>
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
movsbl (%rax),%ecx
xor    %eax,%eax
cmp    $0x0,%ecx
mov    %al,-0x13(%rbp)
je     1292 <atoi+0x192>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x30,%eax
jl     123c <atoi+0x13c>
mov    -0x8(%rbp),%rax
movsbl (%rax),%ecx
mov    $0x1,%al
cmp    $0x39,%ecx
mov    %al,-0x14(%rbp)
jle    128c <atoi+0x18c>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x61,%eax
jl     1261 <atoi+0x161>
mov    -0x8(%rbp),%rax
movsbl (%rax),%ecx
mov    $0x1,%al
cmp    $0x66,%ecx
mov    %al,-0x14(%rbp)
jle    128c <atoi+0x18c>
mov    -0x8(%rbp),%rax
movsbl (%rax),%ecx
xor    %eax,%eax
cmp    $0x41,%ecx
mov    %al,-0x15(%rbp)
jl     1286 <atoi+0x186>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x46,%eax
setle  %al
mov    %al,-0x15(%rbp)
mov    -0x15(%rbp),%al
mov    %al,-0x14(%rbp)
mov    -0x14(%rbp),%al
mov    %al,-0x13(%rbp)
mov    -0x13(%rbp),%al
test   $0x1,%al
jne    12a2 <atoi+0x1a2>
jmp    136c <atoi+0x26c>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x30,%eax
jl     12dc <atoi+0x1dc>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x39,%eax
jg     12dc <atoi+0x1dc>
mov    -0xc(%rbp),%eax
shl    $0x4,%eax
mov    -0x8(%rbp),%rcx
movsbl (%rcx),%ecx
sub    $0x30,%ecx
add    %ecx,%eax
mov    %eax,-0xc(%rbp)
jmp    135b <atoi+0x25b>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x61,%eax
jl     1319 <atoi+0x219>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x66,%eax
jg     1319 <atoi+0x219>
mov    -0xc(%rbp),%eax
shl    $0x4,%eax
mov    -0x8(%rbp),%rcx
movsbl (%rcx),%ecx
sub    $0x61,%ecx
add    $0xa,%ecx
add    %ecx,%eax
mov    %eax,-0xc(%rbp)
jmp    1356 <atoi+0x256>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x41,%eax
jl     1351 <atoi+0x251>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x46,%eax
jg     1351 <atoi+0x251>
mov    -0xc(%rbp),%eax
shl    $0x4,%eax
mov    -0x8(%rbp),%rcx
movsbl (%rcx),%ecx
sub    $0x41,%ecx
add    $0xa,%ecx
add    %ecx,%eax
mov    %eax,-0xc(%rbp)
jmp    1356 <atoi+0x256>
jmp    135b <atoi+0x25b>
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
jmp    1202 <atoi+0x102>
jmp    13e9 <atoi+0x2e9>
jmp    1376 <atoi+0x276>
mov    -0x8(%rbp),%rax
movsbl (%rax),%ecx
xor    %eax,%eax
cmp    $0x0,%ecx
mov    %al,-0x16(%rbp)
je     13b0 <atoi+0x2b0>
mov    -0x8(%rbp),%rax
movsbl (%rax),%ecx
xor    %eax,%eax
cmp    $0x30,%ecx
mov    %al,-0x16(%rbp)
jl     13b0 <atoi+0x2b0>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x39,%eax
setle  %al
mov    %al,-0x16(%rbp)
mov    -0x16(%rbp),%al
test   $0x1,%al
jne    13c0 <atoi+0x2c0>
jmp    13e4 <atoi+0x2e4>
imul   $0xa,-0xc(%rbp),%eax
mov    -0x8(%rbp),%rcx
movsbl (%rcx),%ecx
sub    $0x30,%ecx
add    %ecx,%eax
mov    %eax,-0xc(%rbp)
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
jmp    1376 <atoi+0x276>
jmp    13e9 <atoi+0x2e9>
mov    -0x10(%rbp),%eax
imul   -0xc(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<atoi>:
add    $0x1,%rdi
jmp    1114 <atoi+0x14>
cs nopw 0x0(%rax,%rax,1)
add    $0x1,%rdi
movzbl -0x1(%rdi),%eax
cmp    $0x20,%al
je     1110 <atoi+0x10>
cmp    $0x9,%al
je     1110 <atoi+0x10>
xor    %edx,%edx
cmp    $0x2b,%al
sete   %dl
mov    -0x1(%rdi,%rdx,1),%r8b
xor    %ecx,%ecx
cmp    $0x2d,%r8b
sete   %cl
add    %rdx,%rcx
mov    -0x1(%rdi,%rcx,1),%al
cmp    $0x24,%al
jne    11a3 <atoi+0xa3>
mov    (%rdi,%rcx,1),%sil
test   %sil,%sil
je     11dd <atoi+0xdd>
lea    (%rdi,%rcx,1),%rax
add    $0x1,%rax
xor    %edx,%edx
jmp    1177 <atoi+0x77>
nopl   0x0(%rax)
movzbl %sil,%esi
shl    $0x4,%edx
add    %ecx,%edx
add    %esi,%edx
movzbl (%rax),%esi
add    $0x1,%rax
test   %sil,%sil
je     11df <atoi+0xdf>
lea    -0x30(%rsi),%edi
mov    $0xffffffd0,%ecx
cmp    $0xa,%dil
jb     1160 <atoi+0x60>
lea    -0x61(%rsi),%edi
mov    $0xffffffa9,%ecx
cmp    $0x6,%dil
jb     1160 <atoi+0x60>
lea    -0x41(%rsi),%edi
mov    $0xffffffc9,%ecx
cmp    $0x5,%dil
jbe    1160 <atoi+0x60>
jmp    11df <atoi+0xdf>
lea    -0x30(%rax),%esi
xor    %edx,%edx
cmp    $0x9,%sil
ja     11df <atoi+0xdf>
add    %rcx,%rdi
xor    %edx,%edx
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movzbl %al,%eax
lea    (%rdx,%rdx,4),%ecx
lea    (%rax,%rcx,2),%edx
add    $0xffffffd0,%edx
movzbl (%rdi),%eax
lea    -0x30(%rax),%ecx
add    $0x1,%rdi
cmp    $0xa,%cl
jb     11c0 <atoi+0xc0>
jmp    11df <atoi+0xdf>
xor    %edx,%edx
mov    %edx,%eax
neg    %eax
cmp    $0x2d,%r8b
cmovne %edx,%eax
ret

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

LLVM IR (-O2):
define i32 @atoi(i8* nocapture %0) {
br label %2
2: ; preds = %5, %1
%3 = phi i8* [ %0, %1 ], [ %6, %5 ]
%4 = load i8, i8* %3
switch i8 %4, label %7 [
i8 9, label %5
i8 32, label %5
]
5: ; preds = %2, %2
%6 = getelementptr inbounds i8, i8* %3, i64 1
br label %2
7: ; preds = %2
%8 = icmp eq i8 %4, 43
%9 = zext i1 %8 to i64
%10 = getelementptr i8, i8* %3, i64 %9
%11 = load i8, i8* %10
%12 = icmp eq i8 %11, 45
%13 = zext i1 %12 to i64
%14 = getelementptr i8, i8* %10, i64 %13
%15 = load i8, i8* %14
%16 = icmp eq i8 %15, 36
br i1 %16, label %20, label %17
17: ; preds = %7
%18 = add i8 %15, -48
%19 = icmp ult i8 %18, 10
br i1 %19, label %45, label %57
20: ; preds = %7
%21 = getelementptr inbounds i8, i8* %14, i64 1
%22 = load i8, i8* %21
%23 = icmp eq i8 %22, 0
br i1 %23, label %57, label %24
24: ; preds = %20, %36
%25 = phi i8 [ %43, %36 ], [ %22, %20 ]
%26 = phi i8* [ %42, %36 ], [ %21, %20 ]
%27 = phi i32 [ %41, %36 ], [ 0, %20 ]
%28 = add i8 %25, -48
%29 = icmp ult i8 %28, 10
br i1 %29, label %36, label %30
30: ; preds = %24
%31 = add i8 %25, -97
%32 = icmp ult i8 %31, 6
br i1 %32, label %36, label %33
33: ; preds = %30
%34 = add i8 %25, -65
%35 = icmp ult i8 %34, 6
br i1 %35, label %36, label %57
36: ; preds = %33, %30, %24
%37 = phi i32 [ -48, %24 ], [ -87, %30 ], [ -55, %33 ]
%38 = zext i8 %25 to i32
%39 = shl nsw i32 %27, 4
%40 = add i32 %39, %37
%41 = add i32 %40, %38
%42 = getelementptr inbounds i8, i8* %26, i64 1
%43 = load i8, i8* %42
%44 = icmp eq i8 %43, 0
br i1 %44, label %57, label %24
45: ; preds = %17, %45
%46 = phi i8 [ %54, %45 ], [ %15, %17 ]
%47 = phi i32 [ %52, %45 ], [ 0, %17 ]
%48 = phi i8* [ %53, %45 ], [ %14, %17 ]
%49 = zext i8 %46 to i32
%50 = mul nsw i32 %47, 10
%51 = add i32 %50, -48
%52 = add i32 %51, %49
%53 = getelementptr inbounds i8, i8* %48, i64 1
%54 = load i8, i8* %53
%55 = add i8 %54, -48
%56 = icmp ult i8 %55, 10
br i1 %56, label %45, label %57
57: ; preds = %45, %33, %36, %17, %20
%58 = phi i32 [ 0, %20 ], [ 0, %17 ], [ %27, %33 ], [ %41, %36 ], [ %52, %45 ]
%59 = sub nsw i32 0, %58
%60 = select i1 %12, i32 %59, i32 %58
ret i32 %60
}