long atol(s)
register char *s;
{
  long a;
  unsigned char sign;
  while (*s == ' ' || *s == '\t')
    s++;
  a = 0;
  sign = 0;
  if (*s == '-') {
    sign++;
    s++;
  }
  while (isdigit(*s))
    a = a * 10L + (*s++ - '0');
  if (sign)
    return -a;
  return a;
}


x86 assembly (clang, -O0):
<atol>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x10(%rbp)
mov    -0x10(%rbp),%rax
movsbl (%rax),%ecx
mov    $0x1,%al
cmp    $0x20,%ecx
mov    %al,-0x1a(%rbp)
je     1141 <atol+0x31>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x9,%eax
sete   %al
mov    %al,-0x1a(%rbp)
mov    -0x1a(%rbp),%al
test   $0x1,%al
jne    1151 <atol+0x41>
jmp    1162 <atol+0x52>
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
jmp    111c <atol+0xc>
movq   $0x0,-0x18(%rbp)
movb   $0x0,-0x19(%rbp)
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2d,%eax
jne    1192 <atol+0x82>
mov    -0x19(%rbp),%al
add    $0x1,%al
mov    %al,-0x19(%rbp)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
jmp    1197 <atol+0x87>
mov    -0x10(%rbp),%rax
movsbl (%rax),%edi
call   1030 <isdigit@plt>
cmp    $0x0,%eax
je     11d5 <atol+0xc5>
imul   $0xa,-0x18(%rbp),%rax
mov    -0x10(%rbp),%rcx
mov    %rcx,%rdx
add    $0x1,%rdx
mov    %rdx,-0x10(%rbp)
movsbl (%rcx),%ecx
sub    $0x30,%ecx
movslq %ecx,%rcx
add    %rcx,%rax
mov    %rax,-0x18(%rbp)
jmp    1197 <atol+0x87>
cmpb   $0x0,-0x19(%rbp)
je     11ee <atol+0xde>
xor    %eax,%eax
sub    -0x18(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    11f6 <atol+0xe6>
mov    -0x18(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<atol>:
add    $0x1,%rdi
jmp    1114 <atol+0x14>
cs nopw 0x0(%rax,%rax,1)
add    $0x1,%rdi
movzbl -0x1(%rdi),%ecx
cmp    $0x20,%cl
je     1110 <atol+0x10>
cmp    $0x9,%cl
je     1110 <atol+0x10>
xor    %edx,%edx
cmp    $0x2d,%cl
sete   %dl
movsbl -0x1(%rdi,%rdx,1),%eax
add    $0xffffffd0,%eax
cmp    $0x9,%eax
ja     115b <atol+0x5b>
add    %rdx,%rdi
xor    %edx,%edx
nopl   0x0(%rax)
lea    (%rdx,%rdx,4),%rdx
mov    %eax,%eax
lea    (%rax,%rdx,2),%rdx
movsbl (%rdi),%eax
add    $0xffffffd0,%eax
add    $0x1,%rdi
cmp    $0xa,%eax
jb     1140 <atol+0x40>
jmp    115d <atol+0x5d>
xor    %edx,%edx
mov    %rdx,%rax
neg    %rax
cmp    $0x2d,%cl
cmovne %rdx,%rax
ret

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

LLVM IR (-O2):
define i64 @atol(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 32, label %5
i8 9, 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, 45
%9 = zext i1 %8 to i64
%10 = getelementptr i8, i8* %3, i64 %9
%11 = load i8, i8* %10
%12 = sext i8 %11 to i32
%13 = add nsw i32 %12, -48
%14 = icmp ult i32 %13, 10
br i1 %14, label %15, label %27
15: ; preds = %7, %15
%16 = phi i32 [ %25, %15 ], [ %13, %7 ]
%17 = phi i64 [ %22, %15 ], [ 0, %7 ]
%18 = phi i8* [ %20, %15 ], [ %10, %7 ]
%19 = mul nsw i64 %17, 10
%20 = getelementptr inbounds i8, i8* %18, i64 1
%21 = zext i32 %16 to i64
%22 = add nsw i64 %19, %21
%23 = load i8, i8* %20
%24 = sext i8 %23 to i32
%25 = add nsw i32 %24, -48
%26 = icmp ult i32 %25, 10
br i1 %26, label %15, label %27
27: ; preds = %15, %7
%28 = phi i64 [ 0, %7 ], [ %22, %15 ]
%29 = sub nsw i64 0, %28
%30 = select i1 %8, i64 %29, i64 %28
ret i64 %30
}