#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 */
scalar_t__ TOR_ISDIGIT(char const);
int digit_to_num(int /*<<< orphan*/);
int scan_double(const char **bufp, double *out, int width) {
  int neg = 0;
  double result = 0;
  int scanned_so_far = 0;
  if (!bufp || !*bufp || !out)
    return -1;
  if (width < 0)
    width = 9999;
  if (**bufp == '-') {
    neg = 1;
    ++*bufp;
  }
  while (**bufp && TOR_ISDIGIT(**bufp) && scanned_so_far < width) {
    const int digit = digit_to_num(*(*bufp)++);
    result = result * 10 + digit;
    ++scanned_so_far;
  }
  if (**bufp == '.') {
    double fracval = 0, denominator = 1;
    ++*bufp;
    ++scanned_so_far;
    while (**bufp && TOR_ISDIGIT(**bufp) && scanned_so_far < width) {
      const int digit = digit_to_num(*(*bufp)++);
      fracval = fracval * 10 + digit;
      denominator *= 10;
      ++scanned_so_far;
    }
    result += fracval / denominator;
  }
  if (!scanned_so_far)
    return -1;
  *out = neg ? -result : result;
  return 0;
}


x86 assembly (clang, -O0):
<scan_double>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %edx,-0x1c(%rbp)
movl   $0x0,-0x20(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x28(%rbp)
movl   $0x0,-0x2c(%rbp)
cmpq   $0x0,-0x10(%rbp)
je     116d <scan_double+0x4d>
mov    -0x10(%rbp),%rax
cmpq   $0x0,(%rax)
je     116d <scan_double+0x4d>
cmpq   $0x0,-0x18(%rbp)
jne    1179 <scan_double+0x59>
movl   $0xffffffff,-0x4(%rbp)
jmp    13bc <scan_double+0x29c>
cmpl   $0x0,-0x1c(%rbp)
jge    118a <scan_double+0x6a>
movl   $0x270f,-0x1c(%rbp)
mov    -0x10(%rbp),%rax
mov    (%rax),%rax
movsbl (%rax),%eax
cmp    $0x2d,%eax
jne    11b2 <scan_double+0x92>
movl   $0x1,-0x20(%rbp)
mov    -0x10(%rbp),%rax
mov    (%rax),%rcx
add    $0x1,%rcx
mov    %rcx,(%rax)
jmp    11b7 <scan_double+0x97>
mov    -0x10(%rbp),%rax
mov    (%rax),%rax
movsbl (%rax),%ecx
xor    %eax,%eax
cmp    $0x0,%ecx
mov    %al,-0x45(%rbp)
je     11fc <scan_double+0xdc>
mov    -0x10(%rbp),%rax
mov    (%rax),%rax
movsbl (%rax),%edi
call   1040 <TOR_ISDIGIT@plt>
mov    %rax,%rcx
xor    %eax,%eax
cmp    $0x0,%rcx
mov    %al,-0x45(%rbp)
je     11fc <scan_double+0xdc>
mov    -0x2c(%rbp),%eax
cmp    -0x1c(%rbp),%eax
setl   %al
mov    %al,-0x45(%rbp)
mov    -0x45(%rbp),%al
test   $0x1,%al
jne    120c <scan_double+0xec>
jmp    1255 <scan_double+0x135>
mov    -0x10(%rbp),%rcx
mov    (%rcx),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,(%rcx)
movsbl (%rax),%edi
call   1030 <digit_to_num@plt>
mov    %eax,-0x30(%rbp)
movsd  -0x28(%rbp),%xmm0
cvtsi2sdl -0x30(%rbp),%xmm1
movsd  0xdce(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    11b7 <scan_double+0x97>
mov    -0x10(%rbp),%rax
mov    (%rax),%rax
movsbl (%rax),%eax
cmp    $0x2e,%eax
jne    1358 <scan_double+0x238>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  0xd88(%rip),%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x10(%rbp),%rax
mov    (%rax),%rcx
add    $0x1,%rcx
mov    %rcx,(%rax)
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
mov    -0x10(%rbp),%rax
mov    (%rax),%rax
movsbl (%rax),%ecx
xor    %eax,%eax
cmp    $0x0,%ecx
mov    %al,-0x46(%rbp)
je     12d9 <scan_double+0x1b9>
mov    -0x10(%rbp),%rax
mov    (%rax),%rax
movsbl (%rax),%edi
call   1040 <TOR_ISDIGIT@plt>
mov    %rax,%rcx
xor    %eax,%eax
cmp    $0x0,%rcx
mov    %al,-0x46(%rbp)
je     12d9 <scan_double+0x1b9>
mov    -0x2c(%rbp),%eax
cmp    -0x1c(%rbp),%eax
setl   %al
mov    %al,-0x46(%rbp)
mov    -0x46(%rbp),%al
test   $0x1,%al
jne    12e9 <scan_double+0x1c9>
jmp    1344 <scan_double+0x224>
mov    -0x10(%rbp),%rcx
mov    (%rcx),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,(%rcx)
movsbl (%rax),%edi
call   1030 <digit_to_num@plt>
mov    %eax,-0x44(%rbp)
movsd  -0x38(%rbp),%xmm0
cvtsi2sdl -0x44(%rbp),%xmm1
movsd  0xcf1(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  0xcdc(%rip),%xmm0
mulsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    1294 <scan_double+0x174>
movsd  -0x38(%rbp),%xmm0
divsd  -0x40(%rbp),%xmm0
addsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
cmpl   $0x0,-0x2c(%rbp)
jne    136e <scan_double+0x24e>
movl   $0xffffffff,-0x4(%rbp)
jmp    13bc <scan_double+0x29c>
cmpl   $0x0,-0x20(%rbp)
je     139e <scan_double+0x27e>
movsd  -0x28(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  %xmm0,-0x50(%rbp)
jmp    13a8 <scan_double+0x288>
movsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x50(%rbp),%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,(%rax)
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<scan_double>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x28,%rsp
mov    $0xffffffff,%r12d
test   %rdi,%rdi
je     12b4 <scan_double+0x194>
mov    %rsi,%r14
test   %rsi,%rsi
je     12b4 <scan_double+0x194>
mov    %rdi,%rbx
mov    (%rdi),%rcx
test   %rcx,%rcx
je     12b4 <scan_double+0x194>
test   %edx,%edx
mov    $0x270f,%r13d
cmovns %edx,%r13d
mov    (%rcx),%r15b
mov    %r15d,%eax
cmp    $0x2d,%r15b
jne    117a <scan_double+0x5a>
lea    0x1(%rcx),%rax
mov    %rax,(%rbx)
mov    0x1(%rcx),%al
test   %al,%al
je     12b4 <scan_double+0x194>
xorpd  %xmm1,%xmm1
xor    %ebp,%ebp
nopl   0x0(%rax,%rax,1)
movapd %xmm1,0x10(%rsp)
movsbl %al,%edi
call   1040 <TOR_ISDIGIT@plt>
mov    (%rbx),%rcx
test   %rax,%rax
je     11e5 <scan_double+0xc5>
cmp    %r13d,%ebp
jge    11e5 <scan_double+0xc5>
lea    0x1(%rcx),%rax
mov    %rax,(%rbx)
movsbl (%rcx),%edi
call   1030 <digit_to_num@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
movapd 0x10(%rsp),%xmm1
mulsd  0xe39(%rip),%xmm1
addsd  %xmm0,%xmm1
add    $0x1,%ebp
mov    (%rbx),%rax
movzbl (%rax),%eax
test   %al,%al
jne    1190 <scan_double+0x70>
jmp    129e <scan_double+0x17e>
cmpb   $0x2e,(%rcx)
jne    1274 <scan_double+0x154>
lea    0x1(%rcx),%rax
mov    %rax,(%rbx)
mov    0x1(%rcx),%al
test   %al,%al
je     127f <scan_double+0x15f>
add    $0x1,%ebp
xorps  %xmm2,%xmm2
movsd  0xdf2(%rip),%xmm0
xchg   %ax,%ax
movsd  %xmm0,(%rsp)
movsd  %xmm2,0x8(%rsp)
movsbl %al,%edi
call   1040 <TOR_ISDIGIT@plt>
test   %rax,%rax
je     1285 <scan_double+0x165>
cmp    %r13d,%ebp
jge    1285 <scan_double+0x165>
mov    (%rbx),%rax
lea    0x1(%rax),%rcx
mov    %rcx,(%rbx)
movsbl (%rax),%edi
call   1030 <digit_to_num@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
movsd  0xdba(%rip),%xmm1
movsd  0x8(%rsp),%xmm2
mulsd  %xmm1,%xmm2
addsd  %xmm0,%xmm2
movsd  (%rsp),%xmm0
mulsd  %xmm1,%xmm0
mov    (%rbx),%rax
movzbl (%rax),%eax
add    $0x1,%ebp
test   %al,%al
jne    1210 <scan_double+0xf0>
jmp    1290 <scan_double+0x170>
test   %ebp,%ebp
movaps 0x10(%rsp),%xmm1
jne    129e <scan_double+0x17e>
jmp    12b4 <scan_double+0x194>
xorpd  %xmm2,%xmm2
jmp    1294 <scan_double+0x174>
movsd  0x8(%rsp),%xmm2
movsd  (%rsp),%xmm0
divsd  %xmm0,%xmm2
movapd 0x10(%rsp),%xmm1
addsd  %xmm2,%xmm1
cmp    $0x2d,%r15b
jne    12ac <scan_double+0x18c>
xorpd  0xd64(%rip),%xmm1
movsd  %xmm1,(%r14)
xor    %r12d,%r12d
mov    %r12d,%eax
add    $0x28,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

LLVM IR (-O2):
define i32 @scan_double(i8** %0, double* writeonly %1, i32 %2) {
%4 = icmp eq i8** %0, null
br i1 %4, label %83, label %5
5: ; preds = %3
%6 = load i8*, i8** %0
%7 = icmp ne i8* %6, null
%8 = icmp ne double* %1, null
%9 = and i1 %8, %7
br i1 %9, label %10, label %83
10: ; preds = %5
%11 = icmp slt i32 %2, 0
%12 = select i1 %11, i32 9999, i32 %2
%13 = load i8, i8* %6
%14 = icmp eq i8 %13, 45
br i1 %14, label %15, label %18
15: ; preds = %10
%16 = getelementptr inbounds i8, i8* %6, i64 1
store i8* %16, i8** %0
%17 = load i8, i8* %16
br label %18
18: ; preds = %15, %10
%19 = phi i8 [ %17, %15 ], [ %13, %10 ]
%20 = icmp eq i8 %19, 0
br i1 %20, label %83, label %21
21: ; preds = %18, %30
%22 = phi i8 [ %39, %30 ], [ %19, %18 ]
%23 = phi i32 [ %37, %30 ], [ 0, %18 ]
%24 = phi double [ %36, %30 ], [ 0.000000e+00, %18 ]
%25 = tail call i64 @TOR_ISDIGIT(i8 signext %22)
%26 = icmp ne i64 %25, 0
%27 = icmp slt i32 %23, %12
%28 = select i1 %26, i1 %27, i1 false
%29 = load i8*, i8** %0
br i1 %28, label %30, label %41
30: ; preds = %21
%31 = getelementptr inbounds i8, i8* %29, i64 1
store i8* %31, i8** %0
%32 = load i8, i8* %29
%33 = sext i8 %32 to i32
%34 = tail call i32 @digit_to_num(i32 %33)
%35 = sitofp i32 %34 to double
%36 = tail call double @llvm.fmuladd.f64(double %24, double 1.000000e+01, double %35)
%37 = add nuw nsw i32 %23, 1
%38 = load i8*, i8** %0
%39 = load i8, i8* %38
%40 = icmp eq i8 %39, 0
br i1 %40, label %79, label %21
41: ; preds = %21
%42 = load i8, i8* %29
%43 = icmp eq i8 %42, 46
br i1 %43, label %44, label %77
44: ; preds = %41
%45 = getelementptr inbounds i8, i8* %29, i64 1
store i8* %45, i8** %0
%46 = load i8, i8* %45
%47 = icmp eq i8 %46, 0
br i1 %47, label %74, label %48
48: ; preds = %44, %58
%49 = phi i8 [ %68, %58 ], [ %46, %44 ]
%50 = phi i32 [ %53, %58 ], [ %23, %44 ]
%51 = phi double [ %66, %58 ], [ 1.000000e+00, %44 ]
%52 = phi double [ %65, %58 ], [ 0.000000e+00, %44 ]
%53 = add nuw nsw i32 %50, 1
%54 = tail call i64 @TOR_ISDIGIT(i8 signext %49)
%55 = icmp ne i64 %54, 0
%56 = icmp slt i32 %53, %12
%57 = select i1 %55, i1 %56, i1 false
br i1 %57, label %58, label %70
58: ; preds = %48
%59 = load i8*, i8** %0
%60 = getelementptr inbounds i8, i8* %59, i64 1
store i8* %60, i8** %0
%61 = load i8, i8* %59
%62 = sext i8 %61 to i32
%63 = tail call i32 @digit_to_num(i32 %62)
%64 = sitofp i32 %63 to double
%65 = tail call double @llvm.fmuladd.f64(double %52, double 1.000000e+01, double %64)
%66 = fmul double %51, 1.000000e+01
%67 = load i8*, i8** %0
%68 = load i8, i8* %67
%69 = icmp eq i8 %68, 0
br i1 %69, label %70, label %48
70: ; preds = %48, %58
%71 = phi double [ %65, %58 ], [ %52, %48 ]
%72 = phi double [ %66, %58 ], [ %51, %48 ]
%73 = fdiv double %71, %72
br label %74
74: ; preds = %70, %44
%75 = phi double [ %73, %70 ], [ 0.000000e+00, %44 ]
%76 = fadd double %24, %75
br label %79
77: ; preds = %41
%78 = icmp eq i32 %23, 0
br i1 %78, label %83, label %79
79: ; preds = %30, %74, %77
%80 = phi double [ %76, %74 ], [ %24, %77 ], [ %36, %30 ]
%81 = fneg double %80
%82 = select i1 %14, double %81, double %80
store double %82, double* %1
br label %83
83: ; preds = %18, %77, %3, %5, %79
%84 = phi i32 [ 0, %79 ], [ -1, %5 ], [ -1, %3 ], [ -1, %77 ], [ -1, %18 ]
ret i32 %84
}