#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(double);
double int_sim_ad(double a, double b, double tol, double (*f)(double, void *),
                  void *args) {
  int N1 = 4;
  double S = 0.0;
  double T = 0.0;
  double I = 0.0;
  double I1 = 0.0;
  int i, n;
  int N = N1;
  double h = (b - a) / N;
  S = f(a, args) + f(b, args);
  for (i = 2; i < N; i += 2)
    S += 2 * f(a + i * h, args);
  for (i = 1; i < N; i += 2)
    T += f(a + i * h, args);
  S /= 3.0;
  T *= 2.0 / 3.0;
  I1 = h * (S + 2 * T);
  double err = 1.0e10 * tol;
  while (fabs(err) > tol) {
    N *= 2;
    h *= 0.5;
    I = I1;
    S += T;
    T = 0.0;
    for (i = 1; i < N; i += 2)
      T += f(a + i * h, args);
    T *= 2.0 / 3.0;
    I1 = h * (S + 2 * T);
    err = (I1 - I) / 15.0;
  }
  return I1;
}


x86 assembly (clang, -O0):
<int_sim_ad>:
push   %rbp
mov    %rsp,%rbp
sub    $0x80,%rsp
movsd  %xmm0,-0x8(%rbp)
movsd  %xmm1,-0x10(%rbp)
movsd  %xmm2,-0x18(%rbp)
mov    %rdi,-0x20(%rbp)
mov    %rsi,-0x28(%rbp)
movl   $0x4,-0x2c(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x38(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x40(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x48(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    -0x2c(%rbp),%eax
mov    %eax,-0x5c(%rbp)
movsd  -0x10(%rbp),%xmm0
subsd  -0x8(%rbp),%xmm0
cvtsi2sdl -0x5c(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x68(%rbp)
mov    -0x20(%rbp),%rax
movsd  -0x8(%rbp),%xmm0
mov    -0x28(%rbp),%rdi
call   *%rax
movsd  %xmm0,-0x78(%rbp)
mov    -0x20(%rbp),%rax
movsd  -0x10(%rbp),%xmm0
mov    -0x28(%rbp),%rdi
call   *%rax
movaps %xmm0,%xmm1
movsd  -0x78(%rbp),%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
movl   $0x2,-0x54(%rbp)
mov    -0x54(%rbp),%eax
cmp    -0x5c(%rbp),%eax
jge    11ef <int_sim_ad+0xef>
mov    -0x20(%rbp),%rax
movsd  -0x8(%rbp),%xmm1
cvtsi2sdl -0x54(%rbp),%xmm0
movsd  -0x68(%rbp),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x28(%rbp),%rdi
call   *%rax
movsd  -0x38(%rbp),%xmm1
addsd  %xmm0,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
mov    -0x54(%rbp),%eax
add    $0x2,%eax
mov    %eax,-0x54(%rbp)
jmp    11a2 <int_sim_ad+0xa2>
movl   $0x1,-0x54(%rbp)
mov    -0x54(%rbp),%eax
cmp    -0x5c(%rbp),%eax
jge    123b <int_sim_ad+0x13b>
mov    -0x20(%rbp),%rax
movsd  -0x8(%rbp),%xmm1
cvtsi2sdl -0x54(%rbp),%xmm0
movsd  -0x68(%rbp),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x28(%rbp),%rdi
call   *%rax
addsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x54(%rbp),%eax
add    $0x2,%eax
mov    %eax,-0x54(%rbp)
jmp    11f6 <int_sim_ad+0xf6>
movsd  -0x38(%rbp),%xmm0
movsd  0xdc8(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  0xdaf(%rip),%xmm0
mulsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x68(%rbp),%xmm0
movsd  -0x38(%rbp),%xmm2
movsd  -0x40(%rbp),%xmm1
addsd  %xmm1,%xmm1
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  0xd75(%rip),%xmm0
mulsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x70(%rbp)
movsd  -0x70(%rbp),%xmm0
movaps 0xd8f(%rip),%xmm1
pand   %xmm1,%xmm0
ucomisd -0x18(%rbp),%xmm0
jbe    138a <int_sim_ad+0x28a>
mov    -0x5c(%rbp),%eax
shl    $0x1,%eax
mov    %eax,-0x5c(%rbp)
movsd  0xd57(%rip),%xmm0
mulsd  -0x68(%rbp),%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  -0x50(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x40(%rbp),%xmm0
addsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x40(%rbp)
movl   $0x1,-0x54(%rbp)
mov    -0x54(%rbp),%eax
cmp    -0x5c(%rbp),%eax
jge    1338 <int_sim_ad+0x238>
mov    -0x20(%rbp),%rax
movsd  -0x8(%rbp),%xmm1
cvtsi2sdl -0x54(%rbp),%xmm0
movsd  -0x68(%rbp),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x28(%rbp),%rdi
call   *%rax
addsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x54(%rbp),%eax
add    $0x2,%eax
mov    %eax,-0x54(%rbp)
jmp    12f3 <int_sim_ad+0x1f3>
movsd  0xcc8(%rip),%xmm0
mulsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x68(%rbp),%xmm0
movsd  -0x38(%rbp),%xmm2
movsd  -0x40(%rbp),%xmm1
addsd  %xmm1,%xmm1
addsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x50(%rbp),%xmm0
subsd  -0x48(%rbp),%xmm0
movsd  0xca4(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x70(%rbp)
jmp    1295 <int_sim_ad+0x195>
movsd  -0x50(%rbp),%xmm0
add    $0x80,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<int_sim_ad>:
push   %rbp
push   %r15
push   %r14
push   %rbx
sub    $0x48,%rsp
mov    %rsi,%r14
mov    %rdi,%r15
movsd  %xmm2,0x30(%rsp)
movsd  %xmm1,0x8(%rsp)
movsd  %xmm0,0x18(%rsp)
movapd %xmm1,%xmm2
subsd  %xmm0,%xmm2
mulsd  0xece(%rip),%xmm2
movsd  %xmm2,0x10(%rsp)
mov    %rsi,%rdi
call   *%r15
movsd  %xmm0,0x28(%rsp)
movsd  0x8(%rsp),%xmm0
mov    %r14,%rdi
call   *%r15
addsd  0x28(%rsp),%xmm0
movsd  %xmm0,0x8(%rsp)
movsd  0x10(%rsp),%xmm0
addsd  %xmm0,%xmm0
addsd  0x18(%rsp),%xmm0
mov    %r14,%rdi
call   *%r15
addsd  %xmm0,%xmm0
addsd  0x8(%rsp),%xmm0
movsd  %xmm0,0x20(%rsp)
movsd  0x10(%rsp),%xmm0
addsd  0x18(%rsp),%xmm0
mov    %r14,%rdi
call   *%r15
xorpd  %xmm1,%xmm1
addsd  %xmm0,%xmm1
movsd  %xmm1,0x8(%rsp)
movsd  0x10(%rsp),%xmm0
mulsd  0xe58(%rip),%xmm0
addsd  0x18(%rsp),%xmm0
mov    %r14,%rdi
call   *%r15
movsd  0x20(%rsp),%xmm3
movsd  0x10(%rsp),%xmm2
movapd %xmm0,%xmm4
addsd  0x8(%rsp),%xmm4
divsd  0xe2e(%rip),%xmm3
mulsd  0xe2e(%rip),%xmm4
movapd %xmm4,%xmm1
addsd  %xmm4,%xmm1
addsd  %xmm3,%xmm1
mulsd  %xmm2,%xmm1
movsd  0xe1e(%rip),%xmm0
movsd  0x30(%rsp),%xmm5
mulsd  %xmm5,%xmm0
andpd  0xe34(%rip),%xmm0
ucomisd %xmm5,%xmm0
jbe    1300 <int_sim_ad+0x200>
mov    $0x4,%ebp
jmp    126e <int_sim_ad+0x16e>
nopl   (%rax)
movsd  0x20(%rsp),%xmm3
addsd  0x38(%rsp),%xmm3
mulsd  0xddc(%rip),%xmm4
movapd %xmm4,%xmm0
addsd  %xmm4,%xmm0
addsd  %xmm3,%xmm0
mulsd  %xmm2,%xmm0
movapd %xmm0,%xmm1
subsd  0x40(%rsp),%xmm1
divsd  0xde2(%rip),%xmm1
andpd  0xde2(%rip),%xmm1
ucomisd 0x30(%rsp),%xmm1
movapd %xmm0,%xmm1
jbe    1304 <int_sim_ad+0x204>
mov    %ebp,%eax
lea    (%rax,%rax,1),%ebp
mulsd  0xda5(%rip),%xmm2
test   %eax,%eax
movsd  %xmm3,0x20(%rsp)
movsd  %xmm1,0x40(%rsp)
movsd  %xmm4,0x38(%rsp)
xorpd  %xmm4,%xmm4
jle    1220 <int_sim_ad+0x120>
mov    $0x1,%ebx
movsd  0xd86(%rip),%xmm0
movsd  %xmm2,0x10(%rsp)
nopl   0x0(%rax,%rax,1)
movsd  %xmm0,0x8(%rsp)
movsd  %xmm4,0x28(%rsp)
movsd  0x8(%rsp),%xmm0
mulsd  %xmm2,%xmm0
addsd  0x18(%rsp),%xmm0
mov    %r14,%rdi
call   *%r15
movsd  0x28(%rsp),%xmm4
movsd  0xd50(%rip),%xmm1
movsd  0x10(%rsp),%xmm2
addsd  %xmm0,%xmm4
movsd  0x8(%rsp),%xmm0
addsd  %xmm1,%xmm0
add    $0x2,%ebx
cmp    %ebp,%ebx
jl     12b0 <int_sim_ad+0x1b0>
jmp    1220 <int_sim_ad+0x120>
movapd %xmm1,%xmm0
add    $0x48,%rsp
pop    %rbx
pop    %r14
pop    %r15
pop    %rbp
ret

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

LLVM IR (-O2):
define double @int_sim_ad(double %0, double %1, double %2, double (double, i8*)* nocapture %3, i8* %4) {
%6 = fsub double %1, %0
%7 = fmul double %6, 2.500000e-01
%8 = tail call double %3(double %0, i8* %4)
%9 = tail call double %3(double %1, i8* %4)
%10 = fadd double %8, %9
%11 = tail call double @llvm.fmuladd.f64(double %7, double 2.000000e+00, double %0)
%12 = tail call double %3(double %11, i8* %4)
%13 = tail call double @llvm.fmuladd.f64(double %12, double 2.000000e+00, double %10)
%14 = fadd double %7, %0
%15 = tail call double %3(double %14, i8* %4)
%16 = fadd double %15, 0.000000e+00
%17 = tail call double @llvm.fmuladd.f64(double %7, double 3.000000e+00, double %0)
%18 = tail call double %3(double %17, i8* %4)
%19 = fadd double %16, %18
%20 = fdiv double %13, 3.000000e+00
%21 = fmul double %19, 0x3FE5555555555555
%22 = tail call double @llvm.fmuladd.f64(double %21, double 2.000000e+00, double %20)
%23 = fmul double %7, %22
%24 = fmul double %2, 1.000000e+10
%25 = tail call double @llvm.fabs.f64(double %24)
%26 = fcmp ogt double %25, %2
br i1 %26, label %27, label %55
27: ; preds = %5, %46
%28 = phi double [ %34, %46 ], [ %7, %5 ]
%29 = phi i32 [ %33, %46 ], [ 4, %5 ]
%30 = phi double [ %35, %46 ], [ %20, %5 ]
%31 = phi double [ %50, %46 ], [ %23, %5 ]
%32 = phi double [ %48, %46 ], [ %21, %5 ]
%33 = shl nsw i32 %29, 1
%34 = fmul double %28, 5.000000e-01
%35 = fadd double %32, %30
%36 = icmp sgt i32 %29, 0
br i1 %36, label %37, label %46
37: ; preds = %27, %37
%38 = phi i32 [ %44, %37 ], [ 1, %27 ]
%39 = phi double [ %43, %37 ], [ 0.000000e+00, %27 ]
%40 = sitofp i32 %38 to double
%41 = tail call double @llvm.fmuladd.f64(double %40, double %34, double %0)
%42 = tail call double %3(double %41, i8* %4)
%43 = fadd double %39, %42
%44 = add nuw nsw i32 %38, 2
%45 = icmp slt i32 %44, %33
br i1 %45, label %37, label %46
46: ; preds = %37, %27
%47 = phi double [ 0.000000e+00, %27 ], [ %43, %37 ]
%48 = fmul double %47, 0x3FE5555555555555
%49 = tail call double @llvm.fmuladd.f64(double %48, double 2.000000e+00, double %35)
%50 = fmul double %34, %49
%51 = fsub double %50, %31
%52 = fdiv double %51, 1.500000e+01
%53 = tail call double @llvm.fabs.f64(double %52)
%54 = fcmp ogt double %53, %2
br i1 %54, label %27, label %55
55: ; preds = %46, %5
%56 = phi double [ %23, %5 ], [ %50, %46 ]
ret double %56
}