double apser(double a, double b, double x, double eps) {
  static double g = .577215664901533;
  double ret_val;
  double c__, j, s, t, aj, bx;
  double tol;
  bx = b * x;
  t = x - bx;
  if (b * eps > .02f) {
    goto L10;
  }
  c__ = log(x) + psi(b) + g + t;
  goto L20;
L10:
  c__ = log(bx) + g + t;
L20:
  tol = eps * 5.0 * fabs(c__);
  j = 1.0;
  s = 0.0;
L30:
  j += 1.0;
  t *= x - bx / j;
  aj = t / j;
  s += aj;
  if (fabs(aj) > tol) {
    goto L30;
  }
  ret_val = -(a) * (c__ + s);
  return ret_val;
}


x86 assembly (clang, -O0):
<apser>:
push   %rbp
mov    %rsp,%rbp
sub    $0x70,%rsp
movsd  %xmm0,-0x8(%rbp)
movsd  %xmm1,-0x10(%rbp)
movsd  %xmm2,-0x18(%rbp)
movsd  %xmm3,-0x20(%rbp)
movsd  -0x10(%rbp),%xmm0
mulsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x18(%rbp),%xmm0
subsd  -0x58(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x10(%rbp),%xmm0
mulsd  -0x20(%rbp),%xmm0
movsd  0xe94(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    117b <apser+0x5b>
jmp    11ba <apser+0x9a>
movsd  -0x18(%rbp),%xmm0
call   1040 <log@plt>
movsd  %xmm0,-0x68(%rbp)
movsd  -0x10(%rbp),%xmm0
mov    $0x1,%al
call   1030 <psi@plt>
movsd  -0x68(%rbp),%xmm0
cvtsi2sd %eax,%xmm1
addsd  %xmm1,%xmm0
addsd  0x2e85(%rip),%xmm0
addsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
jmp    11d6 <apser+0xb6>
movsd  -0x58(%rbp),%xmm0
call   1040 <log@plt>
addsd  0x2e64(%rip),%xmm0
addsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  0xe32(%rip),%xmm0
mulsd  -0x20(%rbp),%xmm0
movsd  -0x30(%rbp),%xmm1
movaps 0xe31(%rip),%xmm2
pand   %xmm2,%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  0xe04(%rip),%xmm0
movsd  %xmm0,-0x38(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  0xdef(%rip),%xmm0
addsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  -0x58(%rbp),%xmm1
divsd  -0x38(%rbp),%xmm1
subsd  %xmm1,%xmm0
mulsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x48(%rbp),%xmm0
divsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x50(%rbp),%xmm0
addsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x50(%rbp),%xmm0
movaps 0xdb6(%rip),%xmm1
pand   %xmm1,%xmm0
ucomisd -0x60(%rbp),%xmm0
jbe    127e <apser+0x15e>
jmp    1211 <apser+0xf1>
movsd  -0x8(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  -0x30(%rbp),%xmm1
addsd  -0x40(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
add    $0x70,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<apser>:
sub    $0x48,%rsp
movaps %xmm0,0x30(%rsp)
movapd %xmm1,%xmm0
mulsd  %xmm2,%xmm0
movapd %xmm2,%xmm4
subsd  %xmm0,%xmm4
movsd  %xmm4,0x18(%rsp)
movapd %xmm1,%xmm4
movsd  %xmm3,0x10(%rsp)
mulsd  %xmm3,%xmm4
ucomisd 0xeab(%rip),%xmm4
movsd  %xmm2,0x28(%rsp)
movsd  %xmm0,0x20(%rsp)
jbe    116a <apser+0x4a>
call   1040 <log@plt>
jmp    1197 <apser+0x77>
movapd %xmm2,%xmm0
movsd  %xmm1,(%rsp)
call   1040 <log@plt>
movsd  %xmm0,0x8(%rsp)
movsd  (%rsp),%xmm0
mov    $0x1,%al
call   1030 <psi@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
addsd  0x8(%rsp),%xmm0
addsd  0xe69(%rip),%xmm0
movsd  0x18(%rsp),%xmm1
addsd  %xmm1,%xmm0
movsd  0x10(%rsp),%xmm2
mulsd  0xe59(%rip),%xmm2
movapd 0xe60(%rip),%xmm10
andpd  %xmm0,%xmm10
mulsd  %xmm2,%xmm10
movsd  0xe45(%rip),%xmm9
xorpd  %xmm2,%xmm2
movapd 0xe40(%rip),%xmm8
movapd %xmm9,%xmm5
movsd  0x28(%rsp),%xmm4
movsd  0x20(%rsp),%xmm3
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
addsd  %xmm9,%xmm5
movapd %xmm3,%xmm6
divsd  %xmm5,%xmm6
movapd %xmm4,%xmm7
subsd  %xmm6,%xmm7
mulsd  %xmm7,%xmm1
movapd %xmm1,%xmm6
divsd  %xmm5,%xmm6
addsd  %xmm6,%xmm2
andpd  %xmm8,%xmm6
ucomisd %xmm10,%xmm6
ja     1200 <apser+0xe0>
movapd 0x30(%rsp),%xmm1
xorpd  0xdf1(%rip),%xmm1
addsd  %xmm2,%xmm0
mulsd  %xmm1,%xmm0
add    $0x48,%rsp
ret

LLVM IR (-O0):
@apser.g = internal global double 0x3FE2788CFC6FB61A
define double @apser(double %0, double %1, double %2, double %3) {
%5 = alloca double
%6 = alloca double
%7 = alloca double
%8 = alloca double
%9 = alloca double
%10 = alloca double
%11 = alloca double
%12 = alloca double
%13 = alloca double
%14 = alloca double
%15 = alloca double
%16 = alloca double
store double %0, double* %5
store double %1, double* %6
store double %2, double* %7
store double %3, double* %8
%17 = load double, double* %6
%18 = load double, double* %7
%19 = fmul double %17, %18
store double %19, double* %15
%20 = load double, double* %7
%21 = load double, double* %15
%22 = fsub double %20, %21
store double %22, double* %13
%23 = load double, double* %6
%24 = load double, double* %8
%25 = fmul double %23, %24
%26 = fcmp ogt double %25, 0x3F947AE140000000
br i1 %26, label %27, label %28
27: ; preds = %4
br label %39
28: ; preds = %4
%29 = load double, double* %7
%30 = call double @log(double %29)
%31 = load double, double* %6
%32 = call i32 (double, ...) bitcast (i32 (...)* @psi to i32 (double, ...)*)(double %31)
%33 = sitofp i32 %32 to double
%34 = fadd double %30, %33
%35 = load double, double* @apser.g
%36 = fadd double %34, %35
%37 = load double, double* %13
%38 = fadd double %36, %37
store double %38, double* %10
br label %46
39: ; preds = %27
%40 = load double, double* %15
%41 = call double @log(double %40)
%42 = load double, double* @apser.g
%43 = fadd double %41, %42
%44 = load double, double* %13
%45 = fadd double %43, %44
store double %45, double* %10
br label %46
46: ; preds = %39, %28
%47 = load double, double* %8
%48 = fmul double %47, 5.000000e+00
%49 = load double, double* %10
%50 = call double @llvm.fabs.f64(double %49)
%51 = fmul double %48, %50
store double %51, double* %16
store double 1.000000e+00, double* %11
store double 0.000000e+00, double* %12
br label %52
52: ; preds = %72, %46
%53 = load double, double* %11
%54 = fadd double %53, 1.000000e+00
store double %54, double* %11
%55 = load double, double* %7
%56 = load double, double* %15
%57 = load double, double* %11
%58 = fdiv double %56, %57
%59 = fsub double %55, %58
%60 = load double, double* %13
%61 = fmul double %60, %59
store double %61, double* %13
%62 = load double, double* %13
%63 = load double, double* %11
%64 = fdiv double %62, %63
store double %64, double* %14
%65 = load double, double* %14
%66 = load double, double* %12
%67 = fadd double %66, %65
store double %67, double* %12
%68 = load double, double* %14
%69 = call double @llvm.fabs.f64(double %68)
%70 = load double, double* %16
%71 = fcmp ogt double %69, %70
br i1 %71, label %72, label %73
72: ; preds = %52
br label %52
73: ; preds = %52
%74 = load double, double* %5
%75 = fneg double %74
%76 = load double, double* %10
%77 = load double, double* %12
%78 = fadd double %76, %77
%79 = fmul double %75, %78
store double %79, double* %9
%80 = load double, double* %9
ret double %80
}

LLVM IR (-O2):
define double @apser(double %0, double %1, double %2, double %3) {
%5 = fmul double %1, %2
%6 = fsub double %2, %5
%7 = fmul double %1, %3
%8 = fcmp ogt double %7, 0x3F947AE140000000
br i1 %8, label %14, label %9
9: ; preds = %4
%10 = tail call double @log(double %2)
%11 = tail call i32 (double, ...) bitcast (i32 (...)* @psi to i32 (double, ...)*)(double %1)
%12 = sitofp i32 %11 to double
%13 = fadd double %10, %12
br label %16
14: ; preds = %4
%15 = tail call double @log(double %5)
br label %16
16: ; preds = %14, %9
%17 = phi double [ %15, %14 ], [ %13, %9 ]
%18 = fadd double %17, 0x3FE2788CFC6FB61A
%19 = fadd double %6, %18
%20 = fmul double %3, 5.000000e+00
%21 = tail call double @llvm.fabs.f64(double %19)
%22 = fmul double %20, %21
br label %23
23: ; preds = %23, %16
%24 = phi double [ %6, %16 ], [ %30, %23 ]
%25 = phi double [ 0.000000e+00, %16 ], [ %32, %23 ]
%26 = phi double [ 1.000000e+00, %16 ], [ %27, %23 ]
%27 = fadd double %26, 1.000000e+00
%28 = fdiv double %5, %27
%29 = fsub double %2, %28
%30 = fmul double %24, %29
%31 = fdiv double %30, %27
%32 = fadd double %25, %31
%33 = tail call double @llvm.fabs.f64(double %31)
%34 = fcmp ogt double %33, %22
br i1 %34, label %23, label %35
35: ; preds = %23
%36 = fneg double %0
%37 = fadd double %19, %32
%38 = fmul double %37, %36
ret double %38
}