#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 */
typedef int /*<<< orphan*/ buf;

/* Variables and functions */
scalar_t__ errno;
double strtod(char *, char **);
int toml_rtod(const char *src, double *ret_) {
  if (!src)
    return -1;
  char buf[100];
  char *p = buf;
  char *q = p + sizeof(buf);
  const char *s = src;
  double dummy;
  double *ret = ret_ ? ret_ : &dummy;
  if (s[0] == '+' || s[0] == '-')
    *p++ = *s++;
  if (s[0] == '.')
    return -1;
  if (s[0] == '0') {
    if (s[1] && s[1] != '.')
      return -1;
  }
  while (*s && p < q) {
    int ch = *s++;
    if (ch == '_')
      ;
    else
      *p++ = ch;
  }
  if (*s || p == q)
    return -1;
  if (p != buf && p[-1] == '.')
    return -1;
  *p = 0;
  char *endp;
  errno = 0;
  *ret = strtod(buf, &endp);
  return (errno || *endp) ? -1 : 0;
}


x86 assembly (clang, -O0):
<toml_rtod>:
push   %rbp
mov    %rsp,%rbp
sub    $0xd0,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
cmpq   $0x0,-0x10(%rbp)
jne    113a <toml_rtod+0x2a>
movl   $0xffffffff,-0x4(%rbp)
jmp    13da <toml_rtod+0x2ca>
lea    -0x80(%rbp),%rax
mov    %rax,-0x88(%rbp)
mov    -0x88(%rbp),%rax
add    $0x64,%rax
mov    %rax,-0x90(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x98(%rbp)
cmpq   $0x0,-0x18(%rbp)
je     117d <toml_rtod+0x6d>
mov    -0x18(%rbp),%rax
mov    %rax,-0xc0(%rbp)
jmp    1190 <toml_rtod+0x80>
lea    -0xa0(%rbp),%rax
mov    %rax,-0xc0(%rbp)
jmp    1190 <toml_rtod+0x80>
mov    -0xc0(%rbp),%rax
mov    %rax,-0xa8(%rbp)
mov    -0x98(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2b,%eax
je     11c4 <toml_rtod+0xb4>
mov    -0x98(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2d,%eax
jne    11f2 <toml_rtod+0xe2>
mov    -0x98(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x98(%rbp)
mov    (%rax),%cl
mov    -0x88(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x88(%rbp)
mov    %cl,(%rax)
mov    -0x98(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2e,%eax
jne    1211 <toml_rtod+0x101>
movl   $0xffffffff,-0x4(%rbp)
jmp    13da <toml_rtod+0x2ca>
mov    -0x98(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x30,%eax
jne    125d <toml_rtod+0x14d>
mov    -0x98(%rbp),%rax
movsbl 0x1(%rax),%eax
cmp    $0x0,%eax
je     1258 <toml_rtod+0x148>
mov    -0x98(%rbp),%rax
movsbl 0x1(%rax),%eax
cmp    $0x2e,%eax
je     1258 <toml_rtod+0x148>
movl   $0xffffffff,-0x4(%rbp)
jmp    13da <toml_rtod+0x2ca>
jmp    125d <toml_rtod+0x14d>
jmp    1262 <toml_rtod+0x152>
mov    -0x98(%rbp),%rax
movsbl (%rax),%ecx
xor    %eax,%eax
cmp    $0x0,%ecx
mov    %al,-0xc1(%rbp)
je     1294 <toml_rtod+0x184>
mov    -0x88(%rbp),%rax
cmp    -0x90(%rbp),%rax
setb   %al
mov    %al,-0xc1(%rbp)
mov    -0xc1(%rbp),%al
test   $0x1,%al
jne    12a7 <toml_rtod+0x197>
jmp    12fb <toml_rtod+0x1eb>
mov    -0x98(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x98(%rbp)
movsbl (%rax),%eax
mov    %eax,-0xac(%rbp)
cmpl   $0x5f,-0xac(%rbp)
jne    12d7 <toml_rtod+0x1c7>
jmp    12f6 <toml_rtod+0x1e6>
mov    -0xac(%rbp),%eax
mov    %al,%cl
mov    -0x88(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x88(%rbp)
mov    %cl,(%rax)
jmp    1262 <toml_rtod+0x152>
mov    -0x98(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x0,%eax
jne    1322 <toml_rtod+0x212>
mov    -0x88(%rbp),%rax
cmp    -0x90(%rbp),%rax
jne    132e <toml_rtod+0x21e>
movl   $0xffffffff,-0x4(%rbp)
jmp    13da <toml_rtod+0x2ca>
mov    -0x88(%rbp),%rax
lea    -0x80(%rbp),%rcx
cmp    %rcx,%rax
je     1362 <toml_rtod+0x252>
mov    -0x88(%rbp),%rax
movsbl -0x1(%rax),%eax
cmp    $0x2e,%eax
jne    1362 <toml_rtod+0x252>
movl   $0xffffffff,-0x4(%rbp)
jmp    13da <toml_rtod+0x2ca>
mov    -0x88(%rbp),%rax
movb   $0x0,(%rax)
mov    0x2c6d(%rip),%rax
movq   $0x0,(%rax)
lea    -0x80(%rbp),%rdi
lea    -0xb8(%rbp),%rsi
call   1030 <strtod@plt>
mov    -0xa8(%rbp),%rax
movsd  %xmm0,(%rax)
mov    $0x1,%al
mov    0x2c42(%rip),%rcx
cmpq   $0x0,(%rcx)
mov    %al,-0xc2(%rbp)
jne    13c4 <toml_rtod+0x2b4>
mov    -0xb8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x0,%eax
setne  %al
mov    %al,-0xc2(%rbp)
mov    -0xc2(%rbp),%dl
xor    %eax,%eax
mov    $0xffffffff,%ecx
test   $0x1,%dl
cmovne %ecx,%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0xd0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<toml_rtod>:
test   %rdi,%rdi
je     1146 <toml_rtod+0x36>
push   %r14
push   %rbx
sub    $0x78,%rsp
test   %rsi,%rsi
lea    0x8(%rsp),%r14
cmovne %rsi,%r14
mov    (%rdi),%bl
cmp    $0x2d,%bl
je     1134 <toml_rtod+0x24>
cmp    $0x2b,%bl
jne    114c <toml_rtod+0x3c>
lea    0x11(%rsp),%rcx
mov    %bl,0x10(%rsp)
mov    0x1(%rdi),%bl
add    $0x1,%rdi
jmp    1151 <toml_rtod+0x41>
mov    $0xffffffff,%eax
ret
lea    0x10(%rsp),%rcx
lea    0x74(%rsp),%rdx
mov    $0xffffffff,%eax
test   %bl,%bl
je     11a1 <toml_rtod+0x91>
cmp    $0x2e,%bl
je     11f5 <toml_rtod+0xe5>
cmp    $0x30,%bl
jne    117c <toml_rtod+0x6c>
mov    0x1(%rdi),%sil
cmp    $0x2e,%sil
je     117c <toml_rtod+0x6c>
test   %sil,%sil
jne    11f5 <toml_rtod+0xe5>
add    $0x1,%rdi
cmp    $0x5f,%bl
je     118b <toml_rtod+0x7b>
mov    %bl,(%rcx)
add    $0x1,%rcx
movzbl (%rdi),%ebx
test   %bl,%bl
setne  %sil
je     11a3 <toml_rtod+0x93>
add    $0x1,%rdi
cmp    %rdx,%rcx
jb     1180 <toml_rtod+0x70>
jmp    11a3 <toml_rtod+0x93>
xor    %esi,%esi
test   %sil,%sil
jne    11f5 <toml_rtod+0xe5>
cmp    %rdx,%rcx
je     11f5 <toml_rtod+0xe5>
lea    0x10(%rsp),%rdx
cmp    %rdx,%rcx
je     11bd <toml_rtod+0xad>
cmpb   $0x2e,-0x1(%rcx)
je     11f5 <toml_rtod+0xe5>
movb   $0x0,(%rcx)
mov    0x2e19(%rip),%rbx
movq   $0x0,(%rbx)
lea    0x10(%rsp),%rdi
mov    %rsp,%rsi
call   1030 <strtod@plt>
movsd  %xmm0,(%r14)
mov    $0xffffffff,%eax
cmpq   $0x0,(%rbx)
jne    11f5 <toml_rtod+0xe5>
mov    (%rsp),%rax
xor    %ecx,%ecx
cmp    (%rax),%cl
sbb    %eax,%eax
add    $0x78,%rsp
pop    %rbx
pop    %r14
ret

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

LLVM IR (-O2):
@errno = global i64 0
define i32 @toml_rtod(i8* %0, double* writeonly %1) {
%3 = alloca [100 x i8]
%4 = alloca double
%5 = alloca i8*
%6 = icmp eq i8* %0, null
br i1 %6, label %65, label %7
7: ; preds = %2
%8 = getelementptr inbounds [100 x i8], [100 x i8]* %3, i64 0, i64 0
%9 = getelementptr inbounds [100 x i8], [100 x i8]* %3, i64 0, i64 100
%10 = bitcast double* %4 to i8*
%11 = icmp eq double* %1, null
%12 = select i1 %11, double* %4, double* %1
%13 = load i8, i8* %0
switch i8 %13, label %18 [
i8 43, label %14
i8 45, label %14
]
14: ; preds = %7, %7
%15 = getelementptr inbounds i8, i8* %0, i64 1
%16 = getelementptr inbounds [100 x i8], [100 x i8]* %3, i64 0, i64 1
store i8 %13, i8* %8
%17 = load i8, i8* %15
br label %18
18: ; preds = %7, %14
%19 = phi i8 [ %13, %7 ], [ %17, %14 ]
%20 = phi i8* [ %0, %7 ], [ %15, %14 ]
%21 = phi i8* [ %8, %7 ], [ %16, %14 ]
switch i8 %19, label %25 [
i8 46, label %63
i8 48, label %22
i8 0, label %40
]
22: ; preds = %18
%23 = getelementptr inbounds i8, i8* %20, i64 1
%24 = load i8, i8* %23
switch i8 %24, label %63 [
i8 0, label %25
i8 46, label %25
]
25: ; preds = %18, %22, %22
br label %26
26: ; preds = %25, %34
%27 = phi i8 [ %36, %34 ], [ %19, %25 ]
%28 = phi i8* [ %35, %34 ], [ %21, %25 ]
%29 = phi i8* [ %30, %34 ], [ %20, %25 ]
%30 = getelementptr inbounds i8, i8* %29, i64 1
%31 = icmp eq i8 %27, 95
br i1 %31, label %34, label %32
32: ; preds = %26
%33 = getelementptr inbounds i8, i8* %28, i64 1
store i8 %27, i8* %28
br label %34
34: ; preds = %26, %32
%35 = phi i8* [ %28, %26 ], [ %33, %32 ]
%36 = load i8, i8* %30
%37 = icmp ne i8 %36, 0
%38 = icmp ult i8* %35, %9
%39 = select i1 %37, i1 %38, i1 false
br i1 %39, label %26, label %40
40: ; preds = %34, %18
%41 = phi i8* [ %21, %18 ], [ %35, %34 ]
%42 = phi i1 [ false, %18 ], [ %37, %34 ]
%43 = icmp eq i8* %41, %9
%44 = select i1 %42, i1 true, i1 %43
br i1 %44, label %63, label %45
45: ; preds = %40
%46 = icmp eq i8* %41, %8
br i1 %46, label %51, label %47
47: ; preds = %45
%48 = getelementptr inbounds i8, i8* %41, i64 -1
%49 = load i8, i8* %48
%50 = icmp eq i8 %49, 46
br i1 %50, label %63, label %51
51: ; preds = %47, %45
store i8 0, i8* %41
%52 = bitcast i8** %5 to i8*
store i64 0, i64* @errno
%53 = call double @strtod(i8* %8, i8** %5)
store double %53, double* %12
%54 = load i64, i64* @errno
%55 = icmp eq i64 %54, 0
br i1 %55, label %56, label %61
56: ; preds = %51
%57 = load i8*, i8** %5
%58 = load i8, i8* %57
%59 = icmp ne i8 %58, 0
%60 = sext i1 %59 to i32
br label %61
61: ; preds = %56, %51
%62 = phi i32 [ -1, %51 ], [ %60, %56 ]
br label %63
63: ; preds = %18, %47, %40, %22, %61
%64 = phi i32 [ %62, %61 ], [ -1, %18 ], [ -1, %22 ], [ -1, %40 ], [ -1, %47 ]
br label %65
65: ; preds = %2, %63
%66 = phi i32 [ %64, %63 ], [ -1, %2 ]
ret i32 %66
}