#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 libc_strlen(char *);
double libc_stod(char *s) {
  int i = 0;
  double sign = 0, is = 0, si = 0;
  char *sdt = s;
  sign = (s[0] == '-') ? -1.0 : 1.0;
  int len = libc_strlen(s);
  int k = len;
  while (s[i] != '.') {
    if (sdt[i] == '-') {
      i++;
    }
    is = is * 10. + (sdt[i] - '0');
    i++;
  }
  k--;
  while (s[k] != '.') {
    if (s[0] == '-') {
      si = si * .1 - (sdt[k] - '0');
    } else {
      si = si * .1 + (sdt[k] - '0');
    }
    k--;
  }
  si = si * .1;
  return sign * is + si;
}


x86 assembly (clang, -O0):
<libc_stod>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %rdi,-0x8(%rbp)
movl   $0x0,-0xc(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x18(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x20(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x28(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
movsd  0xeae(%rip),%xmm0
movsd  0xeae(%rip),%xmm1
movsd  %xmm1,-0x48(%rbp)
cmp    $0x2d,%eax
movsd  %xmm0,-0x40(%rbp)
je     1177 <libc_stod+0x67>
movsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
mov    -0x8(%rbp),%rdi
call   1030 <libc_strlen@plt>
mov    %eax,-0x34(%rbp)
mov    -0x34(%rbp),%eax
mov    %eax,-0x38(%rbp)
mov    -0x8(%rbp),%rax
movslq -0xc(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x2e,%eax
je     1201 <libc_stod+0xf1>
mov    -0x30(%rbp),%rax
movslq -0xc(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x2d,%eax
jne    11c6 <libc_stod+0xb6>
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
movsd  -0x20(%rbp),%xmm0
mov    -0x30(%rbp),%rax
movslq -0xc(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
sub    $0x30,%eax
cvtsi2sd %eax,%xmm1
movsd  0xe32(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    1193 <libc_stod+0x83>
mov    -0x38(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x38(%rbp)
mov    -0x8(%rbp),%rax
movslq -0x38(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x2e,%eax
je     12b3 <libc_stod+0x1a3>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2d,%eax
jne    1278 <libc_stod+0x168>
movsd  -0x28(%rbp),%xmm0
mov    -0x30(%rbp),%rax
movslq -0x38(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
sub    $0x30,%eax
cvtsi2sd %eax,%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
movsd  0xdaa(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
jmp    12a5 <libc_stod+0x195>
movsd  -0x28(%rbp),%xmm0
mov    -0x30(%rbp),%rax
movslq -0x38(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
sub    $0x30,%eax
cvtsi2sd %eax,%xmm1
movsd  0xd78(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
mov    -0x38(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x38(%rbp)
jmp    120a <libc_stod+0xfa>
movsd  0xd55(%rip),%xmm0
mulsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  -0x20(%rbp),%xmm2
movsd  -0x28(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<libc_stod>:
push   %rbp
push   %rbx
push   %rax
mov    %rdi,%rbx
mov    (%rdi),%bpl
call   1030 <libc_strlen@plt>
xor    %ecx,%ecx
xorpd  %xmm0,%xmm0
movsd  0xefc(%rip),%xmm1
jmp    1153 <libc_stod+0x43>
xchg   %ax,%ax
movzbl 0x1(%rbx,%rsi,1),%edx
add    $0x1,%rsi
mov    %esi,%ecx
movsbl %dl,%edx
add    $0xffffffd0,%edx
xorps  %xmm2,%xmm2
cvtsi2sd %edx,%xmm2
mulsd  %xmm1,%xmm0
addsd  %xmm2,%xmm0
add    $0x1,%ecx
movslq %ecx,%rsi
movzbl (%rbx,%rsi,1),%edx
cmp    $0x2d,%dl
je     1130 <libc_stod+0x20>
cmp    $0x2e,%dl
jne    113b <libc_stod+0x2b>
movslq %eax,%rcx
mov    -0x1(%rbx,%rcx,1),%dl
xorpd  %xmm1,%xmm1
cmp    $0x2e,%dl
je     11d3 <libc_stod+0xc3>
add    $0xffffffffffffffff,%rcx
mov    (%rbx),%al
add    %rbx,%rcx
add    $0xffffffffffffffff,%rcx
xorpd  %xmm1,%xmm1
movapd 0xe73(%rip),%xmm2
movsd  0xe8b(%rip),%xmm3
jmp    11b4 <libc_stod+0xa4>
nopw   0x0(%rax,%rax,1)
mulsd  %xmm3,%xmm1
addsd  %xmm4,%xmm1
movzbl (%rcx),%edx
add    $0xffffffffffffffff,%rcx
cmp    $0x2e,%dl
je     11cb <libc_stod+0xbb>
movsbl %dl,%edx
add    $0xffffffd0,%edx
xorps  %xmm4,%xmm4
cvtsi2sd %edx,%xmm4
cmp    $0x2d,%al
jne    11a0 <libc_stod+0x90>
xorpd  %xmm2,%xmm4
jmp    11a0 <libc_stod+0x90>
mulsd  0xe4d(%rip),%xmm1
xor    %eax,%eax
cmp    $0x2d,%bpl
sete   %al
lea    0xe2d(%rip),%rcx
mulsd  (%rcx,%rax,8),%xmm0
addsd  %xmm1,%xmm0
add    $0x8,%rsp
pop    %rbx
pop    %rbp
ret

LLVM IR (-O0):
define double @libc_stod(i8* %0) {
%2 = alloca i8*
%3 = alloca i32
%4 = alloca double
%5 = alloca double
%6 = alloca double
%7 = alloca i8*
%8 = alloca i32
%9 = alloca i32
store i8* %0, i8** %2
store i32 0, i32* %3
store double 0.000000e+00, double* %4
store double 0.000000e+00, double* %5
store double 0.000000e+00, double* %6
%10 = load i8*, i8** %2
store i8* %10, i8** %7
%11 = load i8*, i8** %2
%12 = getelementptr inbounds i8, i8* %11, i64 0
%13 = load i8, i8* %12
%14 = sext i8 %13 to i32
%15 = icmp eq i32 %14, 45
%16 = zext i1 %15 to i64
%17 = select i1 %15, double -1.000000e+00, double 1.000000e+00
store double %17, double* %4
%18 = load i8*, i8** %2
%19 = call i32 @libc_strlen(i8* %18)
store i32 %19, i32* %8
%20 = load i32, i32* %8
store i32 %20, i32* %9
br label %21
21: ; preds = %40, %1
%22 = load i8*, i8** %2
%23 = load i32, i32* %3
%24 = sext i32 %23 to i64
%25 = getelementptr inbounds i8, i8* %22, i64 %24
%26 = load i8, i8* %25
%27 = sext i8 %26 to i32
%28 = icmp ne i32 %27, 46
br i1 %28, label %29, label %53
29: ; preds = %21
%30 = load i8*, i8** %7
%31 = load i32, i32* %3
%32 = sext i32 %31 to i64
%33 = getelementptr inbounds i8, i8* %30, i64 %32
%34 = load i8, i8* %33
%35 = sext i8 %34 to i32
%36 = icmp eq i32 %35, 45
br i1 %36, label %37, label %40
37: ; preds = %29
%38 = load i32, i32* %3
%39 = add nsw i32 %38, 1
store i32 %39, i32* %3
br label %40
40: ; preds = %37, %29
%41 = load double, double* %5
%42 = load i8*, i8** %7
%43 = load i32, i32* %3
%44 = sext i32 %43 to i64
%45 = getelementptr inbounds i8, i8* %42, i64 %44
%46 = load i8, i8* %45
%47 = sext i8 %46 to i32
%48 = sub nsw i32 %47, 48
%49 = sitofp i32 %48 to double
%50 = call double @llvm.fmuladd.f64(double %41, double 1.000000e+01, double %49)
store double %50, double* %5
%51 = load i32, i32* %3
%52 = add nsw i32 %51, 1
store i32 %52, i32* %3
br label %21
53: ; preds = %21
%54 = load i32, i32* %9
%55 = add nsw i32 %54, -1
store i32 %55, i32* %9
br label %56
56: ; preds = %93, %53
%57 = load i8*, i8** %2
%58 = load i32, i32* %9
%59 = sext i32 %58 to i64
%60 = getelementptr inbounds i8, i8* %57, i64 %59
%61 = load i8, i8* %60
%62 = sext i8 %61 to i32
%63 = icmp ne i32 %62, 46
br i1 %63, label %64, label %96
64: ; preds = %56
%65 = load i8*, i8** %2
%66 = getelementptr inbounds i8, i8* %65, i64 0
%67 = load i8, i8* %66
%68 = sext i8 %67 to i32
%69 = icmp eq i32 %68, 45
br i1 %69, label %70, label %82
70: ; preds = %64
%71 = load double, double* %6
%72 = load i8*, i8** %7
%73 = load i32, i32* %9
%74 = sext i32 %73 to i64
%75 = getelementptr inbounds i8, i8* %72, i64 %74
%76 = load i8, i8* %75
%77 = sext i8 %76 to i32
%78 = sub nsw i32 %77, 48
%79 = sitofp i32 %78 to double
%80 = fneg double %79
%81 = call double @llvm.fmuladd.f64(double %71, double 1.000000e-01, double %80)
store double %81, double* %6
br label %93
82: ; preds = %64
%83 = load double, double* %6
%84 = load i8*, i8** %7
%85 = load i32, i32* %9
%86 = sext i32 %85 to i64
%87 = getelementptr inbounds i8, i8* %84, i64 %86
%88 = load i8, i8* %87
%89 = sext i8 %88 to i32
%90 = sub nsw i32 %89, 48
%91 = sitofp i32 %90 to double
%92 = call double @llvm.fmuladd.f64(double %83, double 1.000000e-01, double %91)
store double %92, double* %6
br label %93
93: ; preds = %82, %70
%94 = load i32, i32* %9
%95 = add nsw i32 %94, -1
store i32 %95, i32* %9
br label %56
96: ; preds = %56
%97 = load double, double* %6
%98 = fmul double %97, 1.000000e-01
store double %98, double* %6
%99 = load double, double* %4
%100 = load double, double* %5
%101 = load double, double* %6
%102 = call double @llvm.fmuladd.f64(double %99, double %100, double %101)
ret double %102
}

LLVM IR (-O2):
define double @libc_stod(i8* %0) {
%2 = load i8, i8* %0
%3 = tail call i32 @libc_strlen(i8* %0)
br label %4
4: ; preds = %24, %1
%5 = phi double [ 0.000000e+00, %1 ], [ %30, %24 ]
%6 = phi i32 [ 0, %1 ], [ %31, %24 ]
%7 = sext i32 %6 to i64
%8 = getelementptr inbounds i8, i8* %0, i64 %7
%9 = load i8, i8* %8
switch i8 %9, label %24 [
i8 46, label %10
i8 45, label %19
]
10: ; preds = %4
%11 = add nsw i32 %3, -1
%12 = sext i32 %11 to i64
%13 = getelementptr inbounds i8, i8* %0, i64 %12
%14 = load i8, i8* %13
%15 = icmp eq i8 %14, 46
br i1 %15, label %48, label %16
16: ; preds = %10
%17 = load i8, i8* %0
%18 = icmp eq i8 %17, 45
br label %32
19: ; preds = %4
%20 = add nsw i32 %6, 1
%21 = sext i32 %20 to i64
%22 = getelementptr inbounds i8, i8* %0, i64 %21
%23 = load i8, i8* %22
br label %24
24: ; preds = %4, %19
%25 = phi i8 [ %9, %4 ], [ %23, %19 ]
%26 = phi i32 [ %6, %4 ], [ %20, %19 ]
%27 = sext i8 %25 to i32
%28 = add nsw i32 %27, -48
%29 = sitofp i32 %28 to double
%30 = tail call double @llvm.fmuladd.f64(double %5, double 1.000000e+01, double %29)
%31 = add nsw i32 %26, 1
br label %4
32: ; preds = %16, %32
%33 = phi i64 [ %12, %16 ], [ %42, %32 ]
%34 = phi i8 [ %14, %16 ], [ %44, %32 ]
%35 = phi double [ 0.000000e+00, %16 ], [ %41, %32 ]
%36 = sext i8 %34 to i32
%37 = add nsw i32 %36, -48
%38 = sitofp i32 %37 to double
%39 = fneg double %38
%40 = select i1 %18, double %39, double %38
%41 = tail call double @llvm.fmuladd.f64(double %35, double 1.000000e-01, double %40)
%42 = add i64 %33, -1
%43 = getelementptr inbounds i8, i8* %0, i64 %42
%44 = load i8, i8* %43
%45 = icmp eq i8 %44, 46
br i1 %45, label %46, label %32
46: ; preds = %32
%47 = fmul double %41, 1.000000e-01
br label %48
48: ; preds = %46, %10
%49 = phi double [ 0.000000e+00, %10 ], [ %47, %46 ]
%50 = icmp eq i8 %2, 45
%51 = select i1 %50, double -1.000000e+00, double 1.000000e+00
%52 = tail call double @llvm.fmuladd.f64(double %51, double %5, double %49)
ret double %52
}