#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 */
double dkiss();
double sexp(void) {
  static double q[] = {
      0.6931471805599453, 0.9333736875190459, 0.9888777961838675,
      0.9984959252914960, 0.9998292811061389, 0.9999833164100727,
      0.9999985691438767, 0.9999998906925558, 0.9999999924734159,
      0.9999999995283275, 0.9999999999728814, 0.9999999999985598,
      0.9999999999999289, 0.9999999999999968, 0.9999999999999999,
      1.0000000000000000};
  double a, u, ustar, umin;
  int i;
  a = 0.0;
  u = dkiss();
  for (;;) {
    u = u + u;
    if (u > 1.0)
      break;
    a = a + q[0];
  }
  u = u - 1.0;
  if (u <= q[0])
    return a + u;
  i = 0;
  ustar = dkiss();
  umin = ustar;
  do {
    ustar = dkiss();
    if (ustar < umin)
      umin = ustar;
    i = i + 1;
  } while (u > q[i]);
  return a + umin * q[0];
}


x86 assembly (clang, -O0):
<sexp>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x10(%rbp)
mov    $0x0,%al
call   1030 <dkiss@plt>
movsd  %xmm0,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm0
addsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  0xeb8(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    1157 <sexp+0x47>
jmp    116e <sexp+0x5e>
movsd  -0x10(%rbp),%xmm0
addsd  0x2ecc(%rip),%xmm0
movsd  %xmm0,-0x10(%rbp)
jmp    112c <sexp+0x1c>
movsd  -0x18(%rbp),%xmm0
movsd  0xe85(%rip),%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  -0x18(%rbp),%xmm1
movsd  0x2e9f(%rip),%xmm0
ucomisd %xmm1,%xmm0
jb     11af <sexp+0x9f>
movsd  -0x10(%rbp),%xmm0
addsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1239 <sexp+0x129>
movl   $0x0,-0x2c(%rbp)
mov    $0x0,%al
call   1030 <dkiss@plt>
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
mov    $0x0,%al
call   1030 <dkiss@plt>
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm1
movsd  -0x28(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    11f6 <sexp+0xe6>
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
movsd  -0x18(%rbp),%xmm0
movslq -0x2c(%rbp),%rcx
lea    0x2e21(%rip),%rax
ucomisd (%rax,%rcx,8),%xmm0
ja     11cc <sexp+0xbc>
movsd  -0x10(%rbp),%xmm1
movsd  -0x28(%rbp),%xmm0
movsd  0x2e04(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<sexp>:
push   %rbx
sub    $0x20,%rsp
xor    %eax,%eax
call   1030 <dkiss@plt>
movapd %xmm0,%xmm3
addsd  %xmm0,%xmm3
xorpd  %xmm0,%xmm0
ucomisd 0xed0(%rip),%xmm3
ja     115e <sexp+0x4e>
xorpd  %xmm0,%xmm0
movsd  0xeca(%rip),%xmm2
movsd  0xeba(%rip),%xmm1
cs nopw 0x0(%rax,%rax,1)
addsd  %xmm2,%xmm0
addsd  %xmm3,%xmm3
ucomisd %xmm1,%xmm3
jbe    1150 <sexp+0x40>
addsd  0xeaa(%rip),%xmm3
movsd  0xe9a(%rip),%xmm1
ucomisd %xmm3,%xmm1
jae    11c3 <sexp+0xb3>
movsd  %xmm0,0x8(%rsp)
xor    %eax,%eax
movsd  %xmm3,0x10(%rsp)
call   1030 <dkiss@plt>
lea    0xe9a(%rip),%rbx
xchg   %ax,%ax
movsd  %xmm0,0x18(%rsp)
xor    %eax,%eax
call   1030 <dkiss@plt>
minsd  0x18(%rsp),%xmm0
movsd  0x10(%rsp),%xmm1
ucomisd (%rbx),%xmm1
lea    0x8(%rbx),%rbx
ja     1190 <sexp+0x80>
mulsd  0xe4d(%rip),%xmm0
addsd  0x8(%rsp),%xmm0
jmp    11c7 <sexp+0xb7>
addsd  %xmm3,%xmm0
add    $0x20,%rsp
pop    %rbx
ret

LLVM IR (-O0):
@sexp.q = internal global [16 x double] [double 0x3FE62E42FEFA39EF, double 0x3FEDDE327EDAEB52, double 0x3FEFA4E30C4B355E, double 0x3FEFF3ADBA0A1E98, double 0x3FEFFE99F9FDE3CC, double 0x3FEFFFDD0310DC38, double 0x3FEFFFFCFFD0A1C1, double 0x3FEFFFFFC550E636, double 0x3FEFFFFFFBF58DDD, double 0x3FEFFFFFFFBF2C80, double 0x3FEFFFFFFFFC45D9, double 0x3FEFFFFFFFFFCD54, double 0x3FEFFFFFFFFFFD80, double 0x3FEFFFFFFFFFFFE3, double 0x3FEFFFFFFFFFFFFF, double 1.000000e+00]
define double @sexp() {
%1 = alloca double
%2 = alloca double
%3 = alloca double
%4 = alloca double
%5 = alloca double
%6 = alloca i32
store double 0.000000e+00, double* %2
%7 = call double (...) @dkiss()
store double %7, double* %3
br label %8
8: ; preds = %15, %0
%9 = load double, double* %3
%10 = load double, double* %3
%11 = fadd double %9, %10
store double %11, double* %3
%12 = load double, double* %3
%13 = fcmp ogt double %12, 1.000000e+00
br i1 %13, label %14, label %15
14: ; preds = %8
br label %19
15: ; preds = %8
%16 = load double, double* %2
%17 = load double, double* getelementptr inbounds ([16 x double], [16 x double]* @sexp.q, i64 0, i64 0)
%18 = fadd double %16, %17
store double %18, double* %2
br label %8
19: ; preds = %14
%20 = load double, double* %3
%21 = fsub double %20, 1.000000e+00
store double %21, double* %3
%22 = load double, double* %3
%23 = load double, double* getelementptr inbounds ([16 x double], [16 x double]* @sexp.q, i64 0, i64 0)
%24 = fcmp ole double %22, %23
br i1 %24, label %25, label %29
25: ; preds = %19
%26 = load double, double* %2
%27 = load double, double* %3
%28 = fadd double %26, %27
store double %28, double* %1
br label %54
29: ; preds = %19
store i32 0, i32* %6
%30 = call double (...) @dkiss()
store double %30, double* %4
%31 = load double, double* %4
store double %31, double* %5
br label %32
32: ; preds = %42, %29
%33 = call double (...) @dkiss()
store double %33, double* %4
%34 = load double, double* %4
%35 = load double, double* %5
%36 = fcmp olt double %34, %35
br i1 %36, label %37, label %39
37: ; preds = %32
%38 = load double, double* %4
store double %38, double* %5
br label %39
39: ; preds = %37, %32
%40 = load i32, i32* %6
%41 = add nsw i32 %40, 1
store i32 %41, i32* %6
br label %42
42: ; preds = %39
%43 = load double, double* %3
%44 = load i32, i32* %6
%45 = sext i32 %44 to i64
%46 = getelementptr inbounds [16 x double], [16 x double]* @sexp.q, i64 0, i64 %45
%47 = load double, double* %46
%48 = fcmp ogt double %43, %47
br i1 %48, label %32, label %49
49: ; preds = %42
%50 = load double, double* %2
%51 = load double, double* %5
%52 = load double, double* getelementptr inbounds ([16 x double], [16 x double]* @sexp.q, i64 0, i64 0)
%53 = call double @llvm.fmuladd.f64(double %51, double %52, double %50)
store double %53, double* %1
br label %54
54: ; preds = %49, %25
%55 = load double, double* %1
ret double %55
}

LLVM IR (-O2):
@sexp.q = internal unnamed_addr constant [16 x double] [double 0x3FE62E42FEFA39EF, double 0x3FEDDE327EDAEB52, double 0x3FEFA4E30C4B355E, double 0x3FEFF3ADBA0A1E98, double 0x3FEFFE99F9FDE3CC, double 0x3FEFFFDD0310DC38, double 0x3FEFFFFCFFD0A1C1, double 0x3FEFFFFFC550E636, double 0x3FEFFFFFFBF58DDD, double 0x3FEFFFFFFFBF2C80, double 0x3FEFFFFFFFFC45D9, double 0x3FEFFFFFFFFFCD54, double 0x3FEFFFFFFFFFFD80, double 0x3FEFFFFFFFFFFFE3, double 0x3FEFFFFFFFFFFFFF, double 1.000000e+00]
define double @sexp() {
%1 = tail call double (...) @dkiss()
%2 = fadd double %1, %1
%3 = fcmp ogt double %2, 1.000000e+00
br i1 %3, label %10, label %4
4: ; preds = %0, %4
%5 = phi double [ %8, %4 ], [ %2, %0 ]
%6 = phi double [ %7, %4 ], [ 0.000000e+00, %0 ]
%7 = fadd double %6, 0x3FE62E42FEFA39EF
%8 = fadd double %5, %5
%9 = fcmp ogt double %8, 1.000000e+00
br i1 %9, label %10, label %4
10: ; preds = %4, %0
%11 = phi double [ 0.000000e+00, %0 ], [ %7, %4 ]
%12 = phi double [ %2, %0 ], [ %8, %4 ]
%13 = fadd double %12, -1.000000e+00
%14 = fcmp ugt double %13, 0x3FE62E42FEFA39EF
br i1 %14, label %17, label %15
15: ; preds = %10
%16 = fadd double %11, %13
br label %31
17: ; preds = %10
%18 = tail call double (...) @dkiss()
br label %19
19: ; preds = %19, %17
%20 = phi i64 [ %25, %19 ], [ 0, %17 ]
%21 = phi double [ %24, %19 ], [ %18, %17 ]
%22 = tail call double (...) @dkiss()
%23 = fcmp olt double %22, %21
%24 = select i1 %23, double %22, double %21
%25 = add nuw i64 %20, 1
%26 = getelementptr inbounds [16 x double], [16 x double]* @sexp.q, i64 0, i64 %25
%27 = load double, double* %26
%28 = fcmp ogt double %13, %27
br i1 %28, label %19, label %29
29: ; preds = %19
%30 = tail call double @llvm.fmuladd.f64(double %24, double 0x3FE62E42FEFA39EF, double %11)
br label %31
31: ; preds = %29, %15
%32 = phi double [ %16, %15 ], [ %30, %29 ]
ret double %32
}