#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 fabs(long double);
int /*<<< orphan*/ fprintf(int /*<<< orphan*/, char *);
int /*<<< orphan*/ stderr;
long double trapzd(double (*)(double), double, double, int);
double qsimp(double (*func)(double), double a, double b) {
  int j;
  long double s, st, ost, os;
  ost = os = -1.0e30;
  for (j = 1; j <= 16; j++) {
    st = trapzd(func, a, b, j);
    s = (4.0 * st - ost) / 3.0;
    if (fabs(s - os) < (1.0e-5) * fabs(os))
      return s;
    os = s;
    ost = st;
  }
  fprintf(stderr, "Too many steps in routine QSIMP\n");
  return s;
}


x86 assembly (clang, -O0):
<qsimp>:
push   %rbp
mov    %rsp,%rbp
sub    $0xa0,%rsp
mov    %rdi,-0x10(%rbp)
movsd  %xmm0,-0x18(%rbp)
movsd  %xmm1,-0x20(%rbp)
fldl   0xeb1(%rip)
fld    %st(0)
fstpt  -0x70(%rbp)
fstpt  -0x60(%rbp)
movl   $0x1,-0x24(%rbp)
cmpl   $0x10,-0x24(%rbp)
jg     1213 <qsimp+0xe3>
mov    -0x10(%rbp),%rdi
movsd  -0x18(%rbp),%xmm0
movsd  -0x20(%rbp),%xmm1
mov    -0x24(%rbp),%esi
call   1030 <trapzd@plt>
fstpt  -0x50(%rbp)
fldt   -0x50(%rbp)
fldt   -0x60(%rbp)
flds   0xe83(%rip)
fmulp  %st,%st(2)
fsubrp %st,%st(1)
flds   0xe7d(%rip)
fdivrp %st,%st(1)
fstpt  -0x40(%rbp)
fldt   -0x40(%rbp)
fldt   -0x70(%rbp)
fsubrp %st,%st(1)
mov    %rsp,%rax
fstpt  (%rax)
call   1040 <fabs@plt>
movsd  %xmm0,-0x88(%rbp)
ff
fldt   -0x70(%rbp)
mov    %rsp,%rax
fstpt  (%rax)
call   1040 <fabs@plt>
movsd  -0x88(%rbp),%xmm1
ff
movaps %xmm0,%xmm2
movsd  0xe32(%rip),%xmm0
mulsd  %xmm2,%xmm0
ucomisd %xmm1,%xmm0
jbe    11f9 <qsimp+0xc9>
fldt   -0x40(%rbp)
fstpl  -0x80(%rbp)
movsd  -0x80(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1238 <qsimp+0x108>
fldt   -0x40(%rbp)
fstpt  -0x70(%rbp)
fldt   -0x50(%rbp)
fstpt  -0x60(%rbp)
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    115e <qsimp+0x2e>
mov    0x2dc6(%rip),%rax
mov    (%rax),%edi
lea    0xdf5(%rip),%rsi
call   1050 <fprintf@plt>
fldt   -0x40(%rbp)
fstpl  -0x78(%rbp)
movsd  -0x78(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0xa0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<qsimp>:
push   %rbp
push   %rbx
sub    $0x58,%rsp
movsd  %xmm1,0x30(%rsp)
movsd  %xmm0,0x28(%rsp)
mov    %rdi,%rbx
mov    $0x1,%ebp
fldl   0xeb0(%rip)
fld    %st(0)
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
fstpt  0x10(%rsp)
fstpt  0x1c(%rsp)
mov    %rbx,%rdi
movsd  0x28(%rsp),%xmm0
movsd  0x30(%rsp),%xmm1
mov    %ebp,%esi
call   1030 <trapzd@plt>
fld    %st(0)
fstpt  0x4c(%rsp)
fmuls  0xe86(%rip)
fldt   0x10(%rsp)
fsubrp %st,%st(1)
fdivs  0xe7e(%rip)
fld    %st(0)
fstpt  0x10(%rsp)
fldt   0x1c(%rsp)
fsubrp %st,%st(1)
fstpt  (%rsp)
call   1040 <fabs@plt>
movsd  %xmm0,0x38(%rsp)
fldt   0x1c(%rsp)
fstpt  (%rsp)
call   1040 <fabs@plt>
mulsd  0xe44(%rip),%xmm0
ucomisd 0x38(%rsp),%xmm0
ja     11f5 <qsimp+0xc5>
add    $0x1,%ebp
cmp    $0x11,%ebp
fldt   0x10(%rsp)
fldt   0x4c(%rsp)
jne    1160 <qsimp+0x30>
fstp   %st(1)
fstp   %st(0)
mov    0x2df9(%rip),%rax
mov    (%rax),%edi
lea    0xe28(%rip),%rsi
call   1050 <fprintf@plt>
fldt   0x10(%rsp)
fstpl  0x40(%rsp)
movsd  0x40(%rsp),%xmm0
add    $0x58,%rsp
pop    %rbx
pop    %rbp
ret

LLVM IR (-O0):
@stderr = global i32 0
@.str = [33 x i8] c"Too many steps in routine QSIMP\0A\00"
define double @qsimp(double (double)* %0, double %1, double %2) {
%4 = alloca double
%5 = alloca double (double)*
%6 = alloca double
%7 = alloca double
%8 = alloca i32
%9 = alloca x86_fp80
%10 = alloca x86_fp80
%11 = alloca x86_fp80
%12 = alloca x86_fp80
store double (double)* %0, double (double)** %5
store double %1, double* %6
store double %2, double* %7
store x86_fp80 0xKC062C9F2C9CD04675000, x86_fp80* %12
store x86_fp80 0xKC062C9F2C9CD04675000, x86_fp80* %11
store i32 1, i32* %8
br label %13
13: ; preds = %41, %3
%14 = load i32, i32* %8
%15 = icmp sle i32 %14, 16
br i1 %15, label %16, label %44
16: ; preds = %13
%17 = load double (double)*, double (double)** %5
%18 = load double, double* %6
%19 = load double, double* %7
%20 = load i32, i32* %8
%21 = call x86_fp80 @trapzd(double (double)* %17, double %18, double %19, i32 %20)
store x86_fp80 %21, x86_fp80* %10
%22 = load x86_fp80, x86_fp80* %10
%23 = load x86_fp80, x86_fp80* %11
%24 = fneg x86_fp80 %23
%25 = call x86_fp80 @llvm.fmuladd.f80(x86_fp80 0xK40018000000000000000, x86_fp80 %22, x86_fp80 %24)
%26 = fdiv x86_fp80 %25, 0xK4000C000000000000000
store x86_fp80 %26, x86_fp80* %9
%27 = load x86_fp80, x86_fp80* %9
%28 = load x86_fp80, x86_fp80* %12
%29 = fsub x86_fp80 %27, %28
%30 = call double @fabs(x86_fp80 %29)
%31 = load x86_fp80, x86_fp80* %12
%32 = call double @fabs(x86_fp80 %31)
%33 = fmul double 1.000000e-05, %32
%34 = fcmp olt double %30, %33
br i1 %34, label %35, label %38
35: ; preds = %16
%36 = load x86_fp80, x86_fp80* %9
%37 = fptrunc x86_fp80 %36 to double
store double %37, double* %4
br label %49
38: ; preds = %16
%39 = load x86_fp80, x86_fp80* %9
store x86_fp80 %39, x86_fp80* %12
%40 = load x86_fp80, x86_fp80* %10
store x86_fp80 %40, x86_fp80* %11
br label %41
41: ; preds = %38
%42 = load i32, i32* %8
%43 = add nsw i32 %42, 1
store i32 %43, i32* %8
br label %13
44: ; preds = %13
%45 = load i32, i32* @stderr
%46 = call i32 @fprintf(i32 %45, i8* getelementptr inbounds ([33 x i8], [33 x i8]* @.str, i64 0, i64 0))
%47 = load x86_fp80, x86_fp80* %9
%48 = fptrunc x86_fp80 %47 to double
store double %48, double* %4
br label %49
49: ; preds = %44, %35
%50 = load double, double* %4
ret double %50
}

LLVM IR (-O2):
@stderr = global i32 0
@.str = [33 x i8] c"Too many steps in routine QSIMP\0A\00"
define double @qsimp(double (double)* %0, double %1, double %2) {
br label %4
4: ; preds = %3, %17
%5 = phi x86_fp80 [ 0xKC062C9F2C9CD04675000, %3 ], [ %11, %17 ]
%6 = phi x86_fp80 [ 0xKC062C9F2C9CD04675000, %3 ], [ %8, %17 ]
%7 = phi i32 [ 1, %3 ], [ %18, %17 ]
%8 = tail call x86_fp80 @trapzd(double (double)* %0, double %1, double %2, i32 %7)
%9 = fneg x86_fp80 %6
%10 = tail call x86_fp80 @llvm.fmuladd.f80(x86_fp80 %8, x86_fp80 0xK40018000000000000000, x86_fp80 %9)
%11 = fdiv x86_fp80 %10, 0xK4000C000000000000000
%12 = fsub x86_fp80 %11, %5
%13 = tail call double @fabs(x86_fp80 %12)
%14 = tail call double @fabs(x86_fp80 %5)
%15 = fmul double %14, 1.000000e-05
%16 = fcmp olt double %13, %15
br i1 %16, label %23, label %17
17: ; preds = %4
%18 = add nuw nsw i32 %7, 1
%19 = icmp eq i32 %18, 17
br i1 %19, label %20, label %4
20: ; preds = %17
%21 = load i32, i32* @stderr
%22 = tail call i32 @fprintf(i32 %21, i8* getelementptr inbounds ([33 x i8], [33 x i8]* @.str, i64 0, i64 0))
br label %23
23: ; preds = %4, %20
%24 = fptrunc x86_fp80 %11 to double
ret double %24
}