#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 INFINITY;
double M_PI;
float TH_polevlf(float, float *, int);
float floorf(float);
float logf(float);
double tan(double);
double TH_digammaf(float x) {
  static float PSI_10 = 2.25175258906672110764f;
  if (x == 0) {
    return INFINITY;
  }
  int x_is_integer = x == floorf(x);
  if (x < 0) {
    if (x_is_integer) {
      return INFINITY;
    }
    float pi_over_tan_pi_x = (float)(M_PI / tan(M_PI * (double)x));
    return TH_digammaf(1 - x) - pi_over_tan_pi_x;
  }
  float result = 0;
  while (x < 10) {
    result -= 1 / x;
    x += 1;
  }
  if (x == 10) {
    return result + PSI_10;
  }
  static float A[] = {
      8.33333333333333333333E-2f, -2.10927960927960927961E-2f,
      7.57575757575757575758E-3f, -4.16666666666666666667E-3f,
      3.96825396825396825397E-3f, -8.33333333333333333333E-3f,
      8.33333333333333333333E-2f,
  };
  float y = 0;
  if (x < 1.0e17) {
    float z = 1 / (x * x);
    y = z * TH_polevlf(z, A, 6);
  }
  return result + logf(x) - (0.5 / x) - y;
}


x86 assembly (clang, -O0):
<TH_digammaf>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
movss  %xmm0,-0xc(%rbp)
movss  -0xc(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomiss %xmm1,%xmm0
jne    1189 <TH_digammaf+0x39>
jp     1189 <TH_digammaf+0x39>
mov    0x2e6d(%rip),%rax
movsd  (%rax),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1390 <TH_digammaf+0x240>
movss  -0xc(%rbp),%xmm0
movss  %xmm0,-0x24(%rbp)
movss  -0xc(%rbp),%xmm0
call   1050 <floorf@plt>
movaps %xmm0,%xmm1
movss  -0x24(%rbp),%xmm0
ucomiss %xmm1,%xmm0
sete   %al
setnp  %cl
and    %cl,%al
and    $0x1,%al
movzbl %al,%eax
mov    %eax,-0x10(%rbp)
xorps  %xmm0,%xmm0
ucomiss -0xc(%rbp),%xmm0
jbe    124f <TH_digammaf+0xff>
cmpl   $0x0,-0x10(%rbp)
je     11e4 <TH_digammaf+0x94>
mov    0x2e12(%rip),%rax
movsd  (%rax),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1390 <TH_digammaf+0x240>
mov    0x2df5(%rip),%rax
movsd  (%rax),%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    0x2de5(%rip),%rax
movsd  (%rax),%xmm0
movss  -0xc(%rbp),%xmm1
cvtss2sd %xmm1,%xmm1
mulsd  %xmm1,%xmm0
call   1060 <tan@plt>
movaps %xmm0,%xmm1
movsd  -0x30(%rbp),%xmm0
divsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x14(%rbp)
movss  0xdd6(%rip),%xmm0
subss  -0xc(%rbp),%xmm0
call   1030 <TH_digammaf@plt>
movss  -0x14(%rbp),%xmm1
cvtss2sd %xmm1,%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1390 <TH_digammaf+0x240>
xorps  %xmm0,%xmm0
movss  %xmm0,-0x18(%rbp)
movss  0xda1(%rip),%xmm0
ucomiss -0xc(%rbp),%xmm0
jbe    129b <TH_digammaf+0x14b>
movss  0xd93(%rip),%xmm1
divss  -0xc(%rbp),%xmm1
movss  -0x18(%rbp),%xmm0
subss  %xmm1,%xmm0
movss  %xmm0,-0x18(%rbp)
movss  0xd78(%rip),%xmm0
addss  -0xc(%rbp),%xmm0
movss  %xmm0,-0xc(%rbp)
jmp    1257 <TH_digammaf+0x107>
movss  -0xc(%rbp),%xmm0
movss  0xd58(%rip),%xmm1
ucomiss %xmm1,%xmm0
jne    12d2 <TH_digammaf+0x182>
jp     12d2 <TH_digammaf+0x182>
movss  -0x18(%rbp),%xmm0
addss  0x2d8c(%rip),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1390 <TH_digammaf+0x240>
xorps  %xmm0,%xmm0
movss  %xmm0,-0x1c(%rbp)
movss  -0xc(%rbp),%xmm0
cvtss2sd %xmm0,%xmm1
movsd  0xd1d(%rip),%xmm0
ucomisd %xmm1,%xmm0
jbe    1341 <TH_digammaf+0x1f1>
movss  -0xc(%rbp),%xmm1
mulss  -0xc(%rbp),%xmm1
movss  0xcfd(%rip),%xmm0
divss  %xmm1,%xmm0
movss  %xmm0,-0x20(%rbp)
movss  -0x20(%rbp),%xmm0
movss  %xmm0,-0x34(%rbp)
movss  -0x20(%rbp),%xmm0
lea    0x2d3a(%rip),%rdi
mov    $0x6,%esi
call   1070 <TH_polevlf@plt>
movaps %xmm0,%xmm1
movss  -0x34(%rbp),%xmm0
mulss  %xmm1,%xmm0
movss  %xmm0,-0x1c(%rbp)
movss  -0x18(%rbp),%xmm0
movss  %xmm0,-0x38(%rbp)
movss  -0xc(%rbp),%xmm0
call   1040 <logf@plt>
movaps %xmm0,%xmm1
movss  -0x38(%rbp),%xmm0
addss  %xmm1,%xmm0
cvtss2sd %xmm0,%xmm0
movss  -0xc(%rbp),%xmm1
cvtss2sd %xmm1,%xmm2
movsd  0xc9a(%rip),%xmm1
divsd  %xmm2,%xmm1
subsd  %xmm1,%xmm0
movss  -0x1c(%rbp),%xmm1
cvtss2sd %xmm1,%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<TH_digammaf>:
sub    $0x28,%rsp
movaps %xmm0,%xmm3
xorps  %xmm0,%xmm0
ucomiss %xmm0,%xmm3
jne    1171 <TH_digammaf+0x21>
jp     1171 <TH_digammaf+0x21>
mov    0x2e80(%rip),%rax
movsd  (%rax),%xmm0
add    $0x28,%rsp
ret
ucomiss %xmm3,%xmm0
jbe    11ef <TH_digammaf+0x9f>
movaps %xmm3,%xmm0
movss  %xmm3,0x8(%rsp)
call   1050 <floorf@plt>
movss  0x8(%rsp),%xmm1
ucomiss %xmm1,%xmm0
jne    1191 <TH_digammaf+0x41>
jnp    1161 <TH_digammaf+0x11>
mov    0x2e48(%rip),%rax
movsd  (%rax),%xmm2
movsd  %xmm2,0x10(%rsp)
xorps  %xmm0,%xmm0
cvtss2sd %xmm1,%xmm0
mulsd  %xmm2,%xmm0
call   1060 <tan@plt>
movsd  0x10(%rsp),%xmm1
divsd  %xmm0,%xmm1
xorps  %xmm0,%xmm0
cvtsd2ss %xmm1,%xmm0
movss  %xmm0,0x10(%rsp)
movss  0xe33(%rip),%xmm0
subss  0x8(%rsp),%xmm0
call   1030 <TH_digammaf@plt>
movss  0x10(%rsp),%xmm1
cvtss2sd %xmm1,%xmm1
subsd  %xmm1,%xmm0
add    $0x28,%rsp
ret
xorps  %xmm4,%xmm4
movss  0xe06(%rip),%xmm0
ucomiss %xmm3,%xmm0
jbe    1224 <TH_digammaf+0xd4>
xorps  %xmm4,%xmm4
movss  0xdfa(%rip),%xmm1
nopw   0x0(%rax,%rax,1)
movaps %xmm1,%xmm2
divss  %xmm3,%xmm2
subss  %xmm2,%xmm4
addss  %xmm1,%xmm3
ucomiss %xmm3,%xmm0
ja     1210 <TH_digammaf+0xc0>
ucomiss 0xdd5(%rip),%xmm3
jne    1243 <TH_digammaf+0xf3>
jp     1243 <TH_digammaf+0xf3>
addss  0xdd1(%rip),%xmm4
xorps  %xmm0,%xmm0
cvtss2sd %xmm4,%xmm0
add    $0x28,%rsp
ret
movss  %xmm4,0x10(%rsp)
xorps  %xmm1,%xmm1
cvtss2sd %xmm3,%xmm1
xorps  %xmm2,%xmm2
movsd  0xdb5(%rip),%xmm0
movsd  %xmm1,0x20(%rsp)
ucomisd %xmm1,%xmm0
jbe    12aa <TH_digammaf+0x15a>
movaps %xmm3,%xmm1
mulss  %xmm3,%xmm1
movss  0xd8e(%rip),%xmm0
divss  %xmm1,%xmm0
movss  %xmm0,0x1c(%rsp)
lea    0x2dc9(%rip),%rdi
mov    $0x6,%esi
movss  %xmm3,0x8(%rsp)
call   1070 <TH_polevlf@plt>
movss  0x8(%rsp),%xmm3
mulss  0x1c(%rsp),%xmm0
xorps  %xmm2,%xmm2
cvtss2sd %xmm0,%xmm2
movsd  %xmm2,0x8(%rsp)
movaps %xmm3,%xmm0
call   1040 <logf@plt>
movss  0x10(%rsp),%xmm1
addss  %xmm0,%xmm1
cvtss2sd %xmm1,%xmm1
movsd  0xd4a(%rip),%xmm0
divsd  0x20(%rsp),%xmm0
addsd  %xmm1,%xmm0
subsd  0x8(%rsp),%xmm0
add    $0x28,%rsp
ret

LLVM IR (-O0):
@TH_digammaf.PSI_10 = internal global float 0x40020396E0000000
@INFINITY = global double 0.000000e+00
@M_PI = global double 0.000000e+00
@TH_digammaf.A = internal global [7 x float] [float 0x3FB5555560000000, float 0xBF959959A0000000, float 0x3F7F07C200000000, float 0xBF71111120000000, float 0x3F70410420000000, float 0xBF81111120000000, float 0x3FB5555560000000]
define double @TH_digammaf(float %0) {
%2 = alloca double
%3 = alloca float
%4 = alloca i32
%5 = alloca float
%6 = alloca float
%7 = alloca float
%8 = alloca float
store float %0, float* %3
%9 = load float, float* %3
%10 = fcmp oeq float %9, 0.000000e+00
br i1 %10, label %11, label %13
11: ; preds = %1
%12 = load double, double* @INFINITY
store double %12, double* %2
br label %86
13: ; preds = %1
%14 = load float, float* %3
%15 = load float, float* %3
%16 = call float @llvm.floor.f32(float %15)
%17 = fcmp oeq float %14, %16
%18 = zext i1 %17 to i32
store i32 %18, i32* %4
%19 = load float, float* %3
%20 = fcmp olt float %19, 0.000000e+00
br i1 %20, label %21, label %41
21: ; preds = %13
%22 = load i32, i32* %4
%23 = icmp ne i32 %22, 0
br i1 %23, label %24, label %26
24: ; preds = %21
%25 = load double, double* @INFINITY
store double %25, double* %2
br label %86
26: ; preds = %21
%27 = load double, double* @M_PI
%28 = load double, double* @M_PI
%29 = load float, float* %3
%30 = fpext float %29 to double
%31 = fmul double %28, %30
%32 = call double @tan(double %31)
%33 = fdiv double %27, %32
%34 = fptrunc double %33 to float
store float %34, float* %5
%35 = load float, float* %3
%36 = fsub float 1.000000e+00, %35
%37 = call double @TH_digammaf(float %36)
%38 = load float, float* %5
%39 = fpext float %38 to double
%40 = fsub double %37, %39
store double %40, double* %2
br label %86
41: ; preds = %13
store float 0.000000e+00, float* %6
br label %42
42: ; preds = %45, %41
%43 = load float, float* %3
%44 = fcmp olt float %43, 1.000000e+01
br i1 %44, label %45, label %52
45: ; preds = %42
%46 = load float, float* %3
%47 = fdiv float 1.000000e+00, %46
%48 = load float, float* %6
%49 = fsub float %48, %47
store float %49, float* %6
%50 = load float, float* %3
%51 = fadd float %50, 1.000000e+00
store float %51, float* %3
br label %42
52: ; preds = %42
%53 = load float, float* %3
%54 = fcmp oeq float %53, 1.000000e+01
br i1 %54, label %55, label %60
55: ; preds = %52
%56 = load float, float* %6
%57 = load float, float* @TH_digammaf.PSI_10
%58 = fadd float %56, %57
%59 = fpext float %58 to double
store double %59, double* %2
br label %86
60: ; preds = %52
store float 0.000000e+00, float* %7
%61 = load float, float* %3
%62 = fpext float %61 to double
%63 = fcmp olt double %62, 1.000000e+17
br i1 %63, label %64, label %73
64: ; preds = %60
%65 = load float, float* %3
%66 = load float, float* %3
%67 = fmul float %65, %66
%68 = fdiv float 1.000000e+00, %67
store float %68, float* %8
%69 = load float, float* %8
%70 = load float, float* %8
%71 = call float @TH_polevlf(float %70, float* getelementptr inbounds ([7 x float], [7 x float]* @TH_digammaf.A, i64 0, i64 0), i32 6)
%72 = fmul float %69, %71
store float %72, float* %7
br label %73
73: ; preds = %64, %60
%74 = load float, float* %6
%75 = load float, float* %3
%76 = call float @logf(float %75)
%77 = fadd float %74, %76
%78 = fpext float %77 to double
%79 = load float, float* %3
%80 = fpext float %79 to double
%81 = fdiv double 5.000000e-01, %80
%82 = fsub double %78, %81
%83 = load float, float* %7
%84 = fpext float %83 to double
%85 = fsub double %82, %84
store double %85, double* %2
br label %86
86: ; preds = %73, %55, %26, %24, %11
%87 = load double, double* %2
ret double %87
}

LLVM IR (-O2):
@INFINITY = global double 0.000000e+00
@M_PI = global double 0.000000e+00
@TH_digammaf.A = internal global [7 x float] [float 0x3FB5555560000000, float 0xBF959959A0000000, float 0x3F7F07C200000000, float 0xBF71111120000000, float 0x3F70410420000000, float 0xBF81111120000000, float 0x3FB5555560000000]
define double @TH_digammaf(float %0) {
%2 = fcmp oeq float %0, 0.000000e+00
br i1 %2, label %3, label %5
3: ; preds = %1
%4 = load double, double* @INFINITY
br label %14
5: ; preds = %1
%6 = fcmp olt float %0, 0.000000e+00
br i1 %6, label %9, label %7
7: ; preds = %5
%8 = fcmp olt float %0, 1.000000e+01
br i1 %8, label %27, label %34
9: ; preds = %5
%10 = tail call float @llvm.floor.f32(float %0)
%11 = fcmp oeq float %10, %0
br i1 %11, label %12, label %16
12: ; preds = %9
%13 = load double, double* @INFINITY
br label %14
14: ; preds = %3, %38, %50, %12, %16
%15 = phi double [ %26, %16 ], [ %4, %3 ], [ %13, %12 ], [ %40, %38 ], [ %57, %50 ]
ret double %15
16: ; preds = %9
%17 = load double, double* @M_PI
%18 = fpext float %0 to double
%19 = fmul double %17, %18
%20 = tail call double @tan(double %19)
%21 = fdiv double %17, %20
%22 = fptrunc double %21 to float
%23 = fsub float 1.000000e+00, %0
%24 = tail call double @TH_digammaf(float %23)
%25 = fpext float %22 to double
%26 = fsub double %24, %25
br label %14
27: ; preds = %7, %27
%28 = phi float [ %31, %27 ], [ 0.000000e+00, %7 ]
%29 = phi float [ %32, %27 ], [ %0, %7 ]
%30 = fdiv float 1.000000e+00, %29
%31 = fsub float %28, %30
%32 = fadd float %29, 1.000000e+00
%33 = fcmp olt float %32, 1.000000e+01
br i1 %33, label %27, label %34
34: ; preds = %27, %7
%35 = phi float [ %0, %7 ], [ %32, %27 ]
%36 = phi float [ 0.000000e+00, %7 ], [ %31, %27 ]
%37 = fcmp oeq float %35, 1.000000e+01
br i1 %37, label %38, label %41
38: ; preds = %34
%39 = fadd float %36, 0x40020396E0000000
%40 = fpext float %39 to double
br label %14
41: ; preds = %34
%42 = fpext float %35 to double
%43 = fcmp olt double %42, 1.000000e+17
br i1 %43, label %44, label %50
44: ; preds = %41
%45 = fmul float %35, %35
%46 = fdiv float 1.000000e+00, %45
%47 = tail call float @TH_polevlf(float %46, float* getelementptr inbounds ([7 x float], [7 x float]* @TH_digammaf.A, i64 0, i64 0), i32 6)
%48 = fmul float %46, %47
%49 = fpext float %48 to double
br label %50
50: ; preds = %44, %41
%51 = phi double [ %49, %44 ], [ 0.000000e+00, %41 ]
%52 = tail call float @logf(float %35)
%53 = fadd float %36, %52
%54 = fpext float %53 to double
%55 = fdiv double 5.000000e-01, %42
%56 = fsub double %54, %55
%57 = fsub double %56, %51
br label %14
}