#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 */
typedef int /*<<< orphan*/ mpf_t;
typedef int mp_bitcnt_t;

/* Variables and functions */
int /*<<< orphan*/ mpf_add_ui(int /*<<< orphan*/, int /*<<< orphan*/, int);
int /*<<< orphan*/ mpf_clear(int /*<<< orphan*/);
int /*<<< orphan*/ mpf_div(int /*<<< orphan*/, int /*<<< orphan*/,
                           int /*<<< orphan*/);
int /*<<< orphan*/ mpf_div_ui(int /*<<< orphan*/, int /*<<< orphan*/, int);
double mpf_get_d(int /*<<< orphan*/);
int /*<<< orphan*/ mpf_init2(int /*<<< orphan*/, int);
int /*<<< orphan*/ mpf_init_set_d(int /*<<< orphan*/, double);
int /*<<< orphan*/ mpf_init_set_si(int /*<<< orphan*/, int);
int /*<<< orphan*/ mpf_mul(int /*<<< orphan*/, int /*<<< orphan*/,
                           int /*<<< orphan*/);
int /*<<< orphan*/ mpf_set_si(int /*<<< orphan*/, int);
int /*<<< orphan*/ mpf_sub_ui(int /*<<< orphan*/, int /*<<< orphan*/, int);
double rf_hyp2f1_core(double a, int b, double c, double w, int mpf_prec) {
  double d_result;
  mpf_t ma, mb, mc, mw;
  mpf_t result;
  int i;
  int start_iter = -(b + 1);
  mpf_init_set_d(mw, w);
  mp_bitcnt_t prec = mpf_prec;
  mpf_init2(result, prec);
  mpf_set_si(result, 1);
  mpf_init_set_d(ma, a + start_iter);
  mpf_init_set_si(mb, b + start_iter);
  mpf_init_set_d(mc, c + start_iter);
  for (i = -(b + 1); i >= 0; i--) {
    mpf_mul(result, result, mw);
    mpf_mul(result, result, ma);
    mpf_mul(result, result, mb);
    mpf_div_ui(result, result, i + 1);
    mpf_div(result, result, mc);
    mpf_add_ui(result, result, 1);
    mpf_sub_ui(ma, ma, 1);
    mpf_sub_ui(mb, mb, 1);
    mpf_sub_ui(mc, mc, 1);
  }
  d_result = mpf_get_d(result);
  mpf_clear(result);
  mpf_clear(ma);
  mpf_clear(mb);
  mpf_clear(mc);
  mpf_clear(mw);
  return d_result;
}


x86 assembly (clang, -O0):
<rf_hyp2f1_core>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
movsd  %xmm0,-0x8(%rbp)
mov    %edi,-0xc(%rbp)
movsd  %xmm1,-0x18(%rbp)
movsd  %xmm2,-0x20(%rbp)
mov    %esi,-0x24(%rbp)
mov    -0xc(%rbp),%ecx
add    $0x1,%ecx
xor    %eax,%eax
sub    %ecx,%eax
mov    %eax,-0x4c(%rbp)
mov    -0x40(%rbp),%edi
movsd  -0x20(%rbp),%xmm0
call   1060 <mpf_init_set_d@plt>
mov    -0x24(%rbp),%eax
mov    %eax,-0x50(%rbp)
mov    -0x44(%rbp),%edi
mov    -0x50(%rbp),%esi
call   10d0 <mpf_init2@plt>
mov    -0x44(%rbp),%edi
mov    $0x1,%esi
call   1050 <mpf_set_si@plt>
mov    -0x34(%rbp),%edi
movsd  -0x8(%rbp),%xmm0
cvtsi2sdl -0x4c(%rbp),%xmm1
addsd  %xmm1,%xmm0
call   1060 <mpf_init_set_d@plt>
mov    -0x38(%rbp),%edi
mov    -0xc(%rbp),%esi
add    -0x4c(%rbp),%esi
call   1030 <mpf_init_set_si@plt>
mov    -0x3c(%rbp),%edi
movsd  -0x18(%rbp),%xmm0
cvtsi2sdl -0x4c(%rbp),%xmm1
addsd  %xmm1,%xmm0
call   1060 <mpf_init_set_d@plt>
mov    -0xc(%rbp),%ecx
add    $0x1,%ecx
xor    %eax,%eax
sub    %ecx,%eax
mov    %eax,-0x48(%rbp)
cmpl   $0x0,-0x48(%rbp)
jl     12ed <rf_hyp2f1_core+0x13d>
mov    -0x44(%rbp),%edi
mov    -0x44(%rbp),%esi
mov    -0x40(%rbp),%edx
call   1090 <mpf_mul@plt>
mov    -0x44(%rbp),%edi
mov    -0x44(%rbp),%esi
mov    -0x34(%rbp),%edx
call   1090 <mpf_mul@plt>
mov    -0x44(%rbp),%edi
mov    -0x44(%rbp),%esi
mov    -0x38(%rbp),%edx
call   1090 <mpf_mul@plt>
mov    -0x44(%rbp),%edi
mov    -0x44(%rbp),%esi
mov    -0x48(%rbp),%edx
add    $0x1,%edx
call   1080 <mpf_div_ui@plt>
mov    -0x44(%rbp),%edi
mov    -0x44(%rbp),%esi
mov    -0x3c(%rbp),%edx
call   10c0 <mpf_div@plt>
mov    -0x44(%rbp),%edi
mov    -0x44(%rbp),%esi
mov    $0x1,%edx
call   10a0 <mpf_add_ui@plt>
mov    -0x34(%rbp),%edi
mov    -0x34(%rbp),%esi
mov    $0x1,%edx
call   1040 <mpf_sub_ui@plt>
mov    -0x38(%rbp),%edi
mov    -0x38(%rbp),%esi
mov    $0x1,%edx
call   1040 <mpf_sub_ui@plt>
mov    -0x3c(%rbp),%edi
mov    -0x3c(%rbp),%esi
mov    $0x1,%edx
call   1040 <mpf_sub_ui@plt>
mov    -0x48(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x48(%rbp)
jmp    124c <rf_hyp2f1_core+0x9c>
mov    -0x44(%rbp),%edi
call   10b0 <mpf_get_d@plt>
movsd  %xmm0,-0x30(%rbp)
mov    -0x44(%rbp),%edi
call   1070 <mpf_clear@plt>
mov    -0x34(%rbp),%edi
call   1070 <mpf_clear@plt>
mov    -0x38(%rbp),%edi
call   1070 <mpf_clear@plt>
mov    -0x3c(%rbp),%edi
call   1070 <mpf_clear@plt>
mov    -0x40(%rbp),%edi
call   1070 <mpf_clear@plt>
movsd  -0x30(%rbp),%xmm0
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<rf_hyp2f1_core>:
push   %rbp
push   %r14
push   %rbx
sub    $0x20,%rsp
mov    %esi,%ebp
movsd  %xmm1,0x8(%rsp)
mov    %edi,%r14d
movsd  %xmm0,0x18(%rsp)
mov    %edi,%ebx
not    %ebx
movaps %xmm2,%xmm0
call   1060 <mpf_init_set_d@plt>
mov    %ebp,%esi
call   10d0 <mpf_init2@plt>
mov    $0x1,%esi
call   1050 <mpf_set_si@plt>
xorps  %xmm1,%xmm1
cvtsi2sd %ebx,%xmm1
movsd  %xmm1,0x10(%rsp)
movsd  0x18(%rsp),%xmm0
addsd  %xmm1,%xmm0
call   1060 <mpf_init_set_d@plt>
mov    $0xffffffff,%esi
call   1030 <mpf_init_set_si@plt>
movsd  0x8(%rsp),%xmm0
addsd  0x10(%rsp),%xmm0
call   1060 <mpf_init_set_d@plt>
test   %r14d,%r14d
jns    127a <rf_hyp2f1_core+0xca>
add    $0x1,%ebx
cs nopw 0x0(%rax,%rax,1)
nop
call   1090 <mpf_mul@plt>
call   1090 <mpf_mul@plt>
call   1090 <mpf_mul@plt>
mov    %ebx,%edx
call   1080 <mpf_div_ui@plt>
call   10c0 <mpf_div@plt>
mov    $0x1,%edx
call   10a0 <mpf_add_ui@plt>
mov    $0x1,%edx
call   1040 <mpf_sub_ui@plt>
mov    $0x1,%edx
call   1040 <mpf_sub_ui@plt>
mov    $0x1,%edx
call   1040 <mpf_sub_ui@plt>
add    $0xffffffff,%ebx
test   %ebx,%ebx
jg     1230 <rf_hyp2f1_core+0x80>
call   10b0 <mpf_get_d@plt>
movsd  %xmm0,0x8(%rsp)
call   1070 <mpf_clear@plt>
call   1070 <mpf_clear@plt>
call   1070 <mpf_clear@plt>
call   1070 <mpf_clear@plt>
call   1070 <mpf_clear@plt>
movsd  0x8(%rsp),%xmm0
add    $0x20,%rsp
pop    %rbx
pop    %r14
pop    %rbp
ret

LLVM IR (-O0):
define double @rf_hyp2f1_core(double %0, i32 %1, double %2, double %3, i32 %4) {
%6 = alloca double
%7 = alloca i32
%8 = alloca double
%9 = alloca double
%10 = alloca i32
%11 = alloca double
%12 = alloca i32
%13 = alloca i32
%14 = alloca i32
%15 = alloca i32
%16 = alloca i32
%17 = alloca i32
%18 = alloca i32
%19 = alloca i32
store double %0, double* %6
store i32 %1, i32* %7
store double %2, double* %8
store double %3, double* %9
store i32 %4, i32* %10
%20 = load i32, i32* %7
%21 = add nsw i32 %20, 1
%22 = sub nsw i32 0, %21
store i32 %22, i32* %18
%23 = load i32, i32* %15
%24 = load double, double* %9
%25 = call i32 @mpf_init_set_d(i32 %23, double %24)
%26 = load i32, i32* %10
store i32 %26, i32* %19
%27 = load i32, i32* %16
%28 = load i32, i32* %19
%29 = call i32 @mpf_init2(i32 %27, i32 %28)
%30 = load i32, i32* %16
%31 = call i32 @mpf_set_si(i32 %30, i32 1)
%32 = load i32, i32* %12
%33 = load double, double* %6
%34 = load i32, i32* %18
%35 = sitofp i32 %34 to double
%36 = fadd double %33, %35
%37 = call i32 @mpf_init_set_d(i32 %32, double %36)
%38 = load i32, i32* %13
%39 = load i32, i32* %7
%40 = load i32, i32* %18
%41 = add nsw i32 %39, %40
%42 = call i32 @mpf_init_set_si(i32 %38, i32 %41)
%43 = load i32, i32* %14
%44 = load double, double* %8
%45 = load i32, i32* %18
%46 = sitofp i32 %45 to double
%47 = fadd double %44, %46
%48 = call i32 @mpf_init_set_d(i32 %43, double %47)
%49 = load i32, i32* %7
%50 = add nsw i32 %49, 1
%51 = sub nsw i32 0, %50
store i32 %51, i32* %17
br label %52
52: ; preds = %89, %5
%53 = load i32, i32* %17
%54 = icmp sge i32 %53, 0
br i1 %54, label %55, label %92
55: ; preds = %52
%56 = load i32, i32* %16
%57 = load i32, i32* %16
%58 = load i32, i32* %15
%59 = call i32 @mpf_mul(i32 %56, i32 %57, i32 %58)
%60 = load i32, i32* %16
%61 = load i32, i32* %16
%62 = load i32, i32* %12
%63 = call i32 @mpf_mul(i32 %60, i32 %61, i32 %62)
%64 = load i32, i32* %16
%65 = load i32, i32* %16
%66 = load i32, i32* %13
%67 = call i32 @mpf_mul(i32 %64, i32 %65, i32 %66)
%68 = load i32, i32* %16
%69 = load i32, i32* %16
%70 = load i32, i32* %17
%71 = add nsw i32 %70, 1
%72 = call i32 @mpf_div_ui(i32 %68, i32 %69, i32 %71)
%73 = load i32, i32* %16
%74 = load i32, i32* %16
%75 = load i32, i32* %14
%76 = call i32 @mpf_div(i32 %73, i32 %74, i32 %75)
%77 = load i32, i32* %16
%78 = load i32, i32* %16
%79 = call i32 @mpf_add_ui(i32 %77, i32 %78, i32 1)
%80 = load i32, i32* %12
%81 = load i32, i32* %12
%82 = call i32 @mpf_sub_ui(i32 %80, i32 %81, i32 1)
%83 = load i32, i32* %13
%84 = load i32, i32* %13
%85 = call i32 @mpf_sub_ui(i32 %83, i32 %84, i32 1)
%86 = load i32, i32* %14
%87 = load i32, i32* %14
%88 = call i32 @mpf_sub_ui(i32 %86, i32 %87, i32 1)
br label %89
89: ; preds = %55
%90 = load i32, i32* %17
%91 = add nsw i32 %90, -1
store i32 %91, i32* %17
br label %52
92: ; preds = %52
%93 = load i32, i32* %16
%94 = call double @mpf_get_d(i32 %93)
store double %94, double* %11
%95 = load i32, i32* %16
%96 = call i32 @mpf_clear(i32 %95)
%97 = load i32, i32* %12
%98 = call i32 @mpf_clear(i32 %97)
%99 = load i32, i32* %13
%100 = call i32 @mpf_clear(i32 %99)
%101 = load i32, i32* %14
%102 = call i32 @mpf_clear(i32 %101)
%103 = load i32, i32* %15
%104 = call i32 @mpf_clear(i32 %103)
%105 = load double, double* %11
ret double %105
}

LLVM IR (-O2):
define double @rf_hyp2f1_core(double %0, i32 %1, double %2, double %3, i32 %4) {
%6 = xor i32 %1, -1
%7 = tail call i32 @mpf_init_set_d(i32 undef, double %3)
%8 = tail call i32 @mpf_init2(i32 undef, i32 %4)
%9 = tail call i32 @mpf_set_si(i32 undef, i32 1)
%10 = sitofp i32 %6 to double
%11 = fadd double %10, %0
%12 = tail call i32 @mpf_init_set_d(i32 undef, double %11)
%13 = tail call i32 @mpf_init_set_si(i32 undef, i32 -1)
%14 = fadd double %10, %2
%15 = tail call i32 @mpf_init_set_d(i32 undef, double %14)
%16 = icmp slt i32 %1, 0
br i1 %16, label %17, label %31
17: ; preds = %5, %17
%18 = phi i32 [ %29, %17 ], [ %6, %5 ]
%19 = tail call i32 @mpf_mul(i32 undef, i32 undef, i32 undef)
%20 = tail call i32 @mpf_mul(i32 undef, i32 undef, i32 undef)
%21 = tail call i32 @mpf_mul(i32 undef, i32 undef, i32 undef)
%22 = add nuw nsw i32 %18, 1
%23 = tail call i32 @mpf_div_ui(i32 undef, i32 undef, i32 %22)
%24 = tail call i32 @mpf_div(i32 undef, i32 undef, i32 undef)
%25 = tail call i32 @mpf_add_ui(i32 undef, i32 undef, i32 1)
%26 = tail call i32 @mpf_sub_ui(i32 undef, i32 undef, i32 1)
%27 = tail call i32 @mpf_sub_ui(i32 undef, i32 undef, i32 1)
%28 = tail call i32 @mpf_sub_ui(i32 undef, i32 undef, i32 1)
%29 = add nsw i32 %18, -1
%30 = icmp sgt i32 %18, 0
br i1 %30, label %17, label %31
31: ; preds = %17, %5
%32 = tail call double @mpf_get_d(i32 undef)
%33 = tail call i32 @mpf_clear(i32 undef)
%34 = tail call i32 @mpf_clear(i32 undef)
%35 = tail call i32 @mpf_clear(i32 undef)
%36 = tail call i32 @mpf_clear(i32 undef)
%37 = tail call i32 @mpf_clear(i32 undef)
ret double %32
}