#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 */
int digitval(char const);
scalar_t__ isspace(unsigned char);
unsigned long strtoul(const char *nptr, char **endptr, int base) {
  int minus = 0;
  unsigned long v = 0;
  int d;
  while (isspace((unsigned char)*nptr)) {
    nptr++;
  }
  {
    char c = *nptr;
    if (c == '-' || c == '+') {
      minus = (c == '-');
      nptr++;
    }
  }
  if (base == 0) {
    if (nptr[0] == '0' && (nptr[1] == 'x' || nptr[1] == 'X')) {
      nptr += 2;
      base = 16;
    } else if (nptr[0] == '0') {
      nptr++;
      base = 8;
    } else {
      base = 10;
    }
  } else if (base == 16) {
    if (nptr[0] == '0' && (nptr[1] == 'x' || nptr[1] == 'X')) {
      nptr += 2;
    }
  }
  while ((d = digitval(*nptr)) >= 0 && d < base) {
    v = v * base + d;
    nptr++;
  }
  if (endptr)
    *endptr = (char *)nptr;
  return minus ? -v : v;
}


x86 assembly (clang, -O0):
<strtoul>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
movl   $0x0,-0x18(%rbp)
movq   $0x0,-0x20(%rbp)
mov    -0x8(%rbp),%rax
movzbl (%rax),%edi
call   1040 <isspace@plt>
cmp    $0x0,%rax
je     1169 <strtoul+0x49>
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
jmp    1142 <strtoul+0x22>
mov    -0x8(%rbp),%rax
mov    (%rax),%al
mov    %al,-0x25(%rbp)
movsbl -0x25(%rbp),%eax
cmp    $0x2d,%eax
je     118c <strtoul+0x6c>
movsbl -0x25(%rbp),%eax
cmp    $0x2b,%eax
jne    11aa <strtoul+0x8a>
movsbl -0x25(%rbp),%eax
cmp    $0x2d,%eax
sete   %al
and    $0x1,%al
movzbl %al,%eax
mov    %eax,-0x18(%rbp)
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
cmpl   $0x0,-0x14(%rbp)
jne    1237 <strtoul+0x117>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x30,%eax
jne    11fe <strtoul+0xde>
mov    -0x8(%rbp),%rax
movsbl 0x1(%rax),%eax
cmp    $0x78,%eax
je     11e6 <strtoul+0xc6>
mov    -0x8(%rbp),%rax
movsbl 0x1(%rax),%eax
cmp    $0x58,%eax
jne    11fe <strtoul+0xde>
mov    -0x8(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x8(%rbp)
movl   $0x10,-0x14(%rbp)
jmp    1232 <strtoul+0x112>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x30,%eax
jne    1226 <strtoul+0x106>
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
movl   $0x8,-0x14(%rbp)
jmp    122d <strtoul+0x10d>
movl   $0xa,-0x14(%rbp)
jmp    1232 <strtoul+0x112>
jmp    1289 <strtoul+0x169>
cmpl   $0x10,-0x14(%rbp)
jne    1284 <strtoul+0x164>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x30,%eax
jne    127f <strtoul+0x15f>
mov    -0x8(%rbp),%rax
movsbl 0x1(%rax),%eax
cmp    $0x78,%eax
je     1273 <strtoul+0x153>
mov    -0x8(%rbp),%rax
movsbl 0x1(%rax),%eax
cmp    $0x58,%eax
jne    127f <strtoul+0x15f>
mov    -0x8(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x8(%rbp)
jmp    1284 <strtoul+0x164>
jmp    1289 <strtoul+0x169>
jmp    128e <strtoul+0x16e>
mov    -0x8(%rbp),%rax
movsbl (%rax),%edi
call   1030 <digitval@plt>
mov    %eax,%ecx
mov    %ecx,-0x24(%rbp)
xor    %eax,%eax
cmp    $0x0,%ecx
mov    %al,-0x26(%rbp)
jl     12b9 <strtoul+0x199>
mov    -0x24(%rbp),%eax
cmp    -0x14(%rbp),%eax
setl   %al
mov    %al,-0x26(%rbp)
mov    -0x26(%rbp),%al
test   $0x1,%al
jne    12c9 <strtoul+0x1a9>
jmp    12f1 <strtoul+0x1d1>
mov    -0x20(%rbp),%rax
movslq -0x14(%rbp),%rcx
imul   %rcx,%rax
movslq -0x24(%rbp),%rcx
add    %rcx,%rax
mov    %rax,-0x20(%rbp)
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
jmp    128e <strtoul+0x16e>
cmpq   $0x0,-0x10(%rbp)
je     1307 <strtoul+0x1e7>
mov    -0x8(%rbp),%rcx
mov    -0x10(%rbp),%rax
mov    %rcx,(%rax)
cmpl   $0x0,-0x18(%rbp)
je     1320 <strtoul+0x200>
xor    %eax,%eax
sub    -0x20(%rbp),%rax
mov    %rax,-0x30(%rbp)
jmp    1328 <strtoul+0x208>
mov    -0x20(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<strtoul>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
push   %rax
mov    %edx,%r12d
mov    %rsi,%r14
mov    %rdi,%rbx
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movzbl (%rbx),%edi
call   1040 <isspace@plt>
add    $0x1,%rbx
test   %rax,%rax
jne    1140 <strtoul+0x20>
mov    -0x1(%rbx),%al
cmp    $0x2b,%al
je     115c <strtoul+0x3c>
cmp    $0x2d,%al
jne    1193 <strtoul+0x73>
xor    %r15d,%r15d
cmp    $0x2d,%al
sete   %r15b
cmp    $0x10,%r12d
je     11a0 <strtoul+0x80>
test   %r12d,%r12d
jne    11ca <strtoul+0xaa>
mov    (%rbx),%al
mov    $0xa,%r12d
cmp    $0x30,%al
jne    11c0 <strtoul+0xa0>
mov    0x1(%rbx),%cl
or     $0x20,%cl
cmp    $0x78,%cl
jne    11ba <strtoul+0x9a>
add    $0x2,%rbx
mov    $0x10,%r12d
jmp    11ca <strtoul+0xaa>
add    $0xffffffffffffffff,%rbx
xor    %r15d,%r15d
cmp    $0x10,%r12d
jne    116b <strtoul+0x4b>
mov    $0x10,%r12d
cmpb   $0x30,(%rbx)
jne    11ca <strtoul+0xaa>
mov    0x1(%rbx),%al
or     $0x20,%al
cmp    $0x78,%al
jne    11ca <strtoul+0xaa>
add    $0x2,%rbx
jmp    11ca <strtoul+0xaa>
mov    $0x8,%r12d
xor    %ecx,%ecx
cmp    $0x30,%al
sete   %cl
add    %rcx,%rbx
movsbl (%rbx),%edi
call   1030 <digitval@plt>
xor    %ebp,%ebp
test   %eax,%eax
js     1212 <strtoul+0xf2>
cmp    %r12d,%eax
jge    1212 <strtoul+0xf2>
movslq %r12d,%r13
xor    %ebp,%ebp
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
mov    %rbp,%rcx
imul   %r13,%rcx
mov    %eax,%ebp
add    %rcx,%rbp
movsbl 0x1(%rbx),%edi
add    $0x1,%rbx
call   1030 <digitval@plt>
test   %eax,%eax
js     1212 <strtoul+0xf2>
cmp    %r12d,%eax
jl     11f0 <strtoul+0xd0>
test   %r14,%r14
je     121a <strtoul+0xfa>
mov    %rbx,(%r14)
mov    %rbp,%rax
neg    %rax
test   %r15d,%r15d
cmove  %rbp,%rax
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

LLVM IR (-O2):
define i64 @strtoul(i8* %0, i8** writeonly %1, i32 %2) {
br label %4
4: ; preds = %4, %3
%5 = phi i8* [ %0, %3 ], [ %9, %4 ]
%6 = load i8, i8* %5
%7 = tail call i64 @isspace(i8 zeroext %6)
%8 = icmp eq i64 %7, 0
%9 = getelementptr inbounds i8, i8* %5, i64 1
br i1 %8, label %10, label %4
10: ; preds = %4
%11 = load i8, i8* %5
switch i8 %11, label %15 [
i8 45, label %12
i8 43, label %12
]
12: ; preds = %10, %10
%13 = icmp eq i8 %11, 45
%14 = zext i1 %13 to i32
br label %15
15: ; preds = %10, %12
%16 = phi i32 [ %14, %12 ], [ 0, %10 ]
%17 = phi i8* [ %9, %12 ], [ %5, %10 ]
switch i32 %2, label %38 [
i32 0, label %18
i32 16, label %30
]
18: ; preds = %15
%19 = load i8, i8* %17
%20 = icmp eq i8 %19, 48
br i1 %20, label %21, label %26
21: ; preds = %18
%22 = getelementptr inbounds i8, i8* %17, i64 1
%23 = load i8, i8* %22
switch i8 %23, label %26 [
i8 120, label %24
i8 88, label %24
]
24: ; preds = %21, %21
%25 = getelementptr inbounds i8, i8* %17, i64 2
br label %38
26: ; preds = %21, %18
%27 = phi i32 [ 8, %21 ], [ 10, %18 ]
%28 = zext i1 %20 to i64
%29 = getelementptr i8, i8* %17, i64 %28
br label %38
30: ; preds = %15
%31 = load i8, i8* %17
%32 = icmp eq i8 %31, 48
br i1 %32, label %33, label %38
33: ; preds = %30
%34 = getelementptr inbounds i8, i8* %17, i64 1
%35 = load i8, i8* %34
switch i8 %35, label %38 [
i8 120, label %36
i8 88, label %36
]
36: ; preds = %33, %33
%37 = getelementptr inbounds i8, i8* %17, i64 2
br label %38
38: ; preds = %26, %33, %15, %36, %30, %24
%39 = phi i32 [ 16, %24 ], [ 16, %36 ], [ 16, %30 ], [ %2, %15 ], [ 16, %33 ], [ %27, %26 ]
%40 = phi i8* [ %25, %24 ], [ %37, %36 ], [ %17, %30 ], [ %17, %15 ], [ %17, %33 ], [ %29, %26 ]
%41 = load i8, i8* %40
%42 = tail call i32 @digitval(i8 signext %41)
%43 = icmp sgt i32 %42, -1
%44 = icmp slt i32 %42, %39
%45 = and i1 %43, %44
br i1 %45, label %46, label %61
46: ; preds = %38
%47 = sext i32 %39 to i64
br label %48
48: ; preds = %46, %48
%49 = phi i32 [ %42, %46 ], [ %57, %48 ]
%50 = phi i8* [ %40, %46 ], [ %55, %48 ]
%51 = phi i64 [ 0, %46 ], [ %54, %48 ]
%52 = mul i64 %51, %47
%53 = zext i32 %49 to i64
%54 = add i64 %52, %53
%55 = getelementptr inbounds i8, i8* %50, i64 1
%56 = load i8, i8* %55
%57 = tail call i32 @digitval(i8 signext %56)
%58 = icmp sgt i32 %57, -1
%59 = icmp slt i32 %57, %39
%60 = and i1 %58, %59
br i1 %60, label %48, label %61
61: ; preds = %48, %38
%62 = phi i64 [ 0, %38 ], [ %54, %48 ]
%63 = phi i8* [ %40, %38 ], [ %55, %48 ]
%64 = icmp eq i8** %1, null
br i1 %64, label %66, label %65
65: ; preds = %61
store i8* %63, i8** %1
br label %66
66: ; preds = %65, %61
%67 = icmp eq i32 %16, 0
%68 = sub i64 0, %62
%69 = select i1 %67, i64 %62, i64 %68
ret i64 %69
}