#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 exp(double);
double const sqrt(double);
void fgamma(double *fm, double t, int m) {
  register int i;
  register double sum, term, expt, twot, mphalf;
  const double tcrit = 36. + 2 * m;
  const double sqrtpi = 0.88622692545275801365;
  const double eps = 1.e-14;
  if (t > tcrit) {
    fm[0] = sqrtpi / sqrt(t);
    for (i = 1; i <= m; i++)
      fm[i] = fm[i - 1] * (i - 0.5) / t;
    return;
  }
  mphalf = m + 0.5;
  term = 0.5 / mphalf;
  sum = term;
  for (i = 1; i <= 500; i++) {
    term *= (t / (mphalf + i));
    sum += term;
    if (term < eps)
      break;
  }
  twot = 2.0 * t;
  expt = exp(-t);
  fm[m] = sum * expt;
  for (i = m; i--;)
    fm[i] = (fm[i + 1] * twot + expt) / (2.0 * i + 1.0);
}


x86 assembly (clang, -O0):
<fgamma>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %rdi,-0x8(%rbp)
movsd  %xmm0,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    -0x14(%rbp),%eax
shl    $0x1,%eax
cvtsi2sd %eax,%xmm1
movsd  0xeca(%rip),%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  0xeb1(%rip),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  0xe9c(%rip),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x10(%rbp),%xmm0
ucomisd -0x48(%rbp),%xmm0
jbe    11f9 <fgamma+0xd9>
movsd  -0x10(%rbp),%xmm0
call   1040 <sqrt@plt>
movaps %xmm0,%xmm1
movsd  0xe7a(%rip),%xmm0
divsd  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movsd  %xmm0,(%rax)
movl   $0x1,-0x18(%rbp)
mov    -0x18(%rbp),%eax
cmp    -0x14(%rbp),%eax
jg     11f4 <fgamma+0xd4>
mov    -0x8(%rbp),%rax
mov    -0x18(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
cvtsi2sdl -0x18(%rbp),%xmm1
movsd  0xe4c(%rip),%xmm2
subsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
divsd  -0x10(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movslq -0x18(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    11a1 <fgamma+0x81>
jmp    1352 <fgamma+0x232>
cvtsi2sdl -0x14(%rbp),%xmm0
movsd  0xe12(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  0xe01(%rip),%xmm0
divsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
movl   $0x1,-0x18(%rbp)
cmpl   $0x1f4,-0x18(%rbp)
jg     129a <fgamma+0x17a>
movsd  -0x10(%rbp),%xmm0
movsd  -0x40(%rbp),%xmm1
cvtsi2sdl -0x18(%rbp),%xmm2
addsd  %xmm2,%xmm1
divsd  %xmm1,%xmm0
mulsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
addsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  0xd89(%rip),%xmm0
ucomisd -0x28(%rbp),%xmm0
jbe    1287 <fgamma+0x167>
jmp    129a <fgamma+0x17a>
jmp    128c <fgamma+0x16c>
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    1232 <fgamma+0x112>
movsd  0xd7e(%rip),%xmm0
mulsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x10(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
call   1030 <exp@plt>
movsd  %xmm0,-0x30(%rbp)
movsd  -0x20(%rbp),%xmm0
mulsd  -0x30(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x14(%rbp),%eax
mov    %eax,-0x18(%rbp)
mov    -0x18(%rbp),%eax
mov    %eax,%ecx
add    $0xffffffff,%ecx
mov    %ecx,-0x18(%rbp)
cmp    $0x0,%eax
je     1352 <fgamma+0x232>
mov    -0x8(%rbp),%rax
mov    -0x18(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  -0x38(%rbp),%xmm2
movsd  -0x30(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsi2sdl -0x18(%rbp),%xmm1
addsd  %xmm1,%xmm1
movsd  0xcf0(%rip),%xmm2
addsd  %xmm2,%xmm1
divsd  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movslq -0x18(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
jmp    12ef <fgamma+0x1cf>
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<fgamma>:
push   %r14
push   %rbx
sub    $0x18,%rsp
mov    %esi,%r14d
movapd %xmm0,%xmm5
mov    %rdi,%rbx
lea    (%r14,%r14,1),%eax
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
addsd  0xebc(%rip),%xmm0
ucomisd %xmm0,%xmm5
jbe    1164 <fgamma+0x44>
xorpd  %xmm0,%xmm0
ucomisd %xmm0,%xmm5
jb     12a3 <fgamma+0x183>
xorps  %xmm0,%xmm0
sqrtsd %xmm5,%xmm0
jmp    12b6 <fgamma+0x196>
xorps  %xmm0,%xmm0
cvtsi2sd %r14d,%xmm0
movsd  0xe94(%rip),%xmm6
addsd  %xmm6,%xmm0
divsd  %xmm0,%xmm6
mov    $0x1,%eax
movsd  0xe87(%rip),%xmm1
movapd %xmm6,%xmm2
nopl   (%rax)
movapd %xmm2,%xmm3
xorps  %xmm4,%xmm4
cvtsi2sd %eax,%xmm4
addsd  %xmm0,%xmm4
movapd %xmm5,%xmm2
divsd  %xmm4,%xmm2
mulsd  %xmm3,%xmm2
addsd  %xmm2,%xmm6
ucomisd %xmm2,%xmm1
ja     11c1 <fgamma+0xa1>
lea    0x1(%rax),%ecx
cmp    $0x1f4,%eax
mov    %ecx,%eax
jne    1190 <fgamma+0x70>
movapd 0xe67(%rip),%xmm0
xorpd  %xmm5,%xmm0
movapd %xmm5,(%rsp)
movsd  %xmm6,0x10(%rsp)
call   1030 <exp@plt>
movsd  0x10(%rsp),%xmm4
movapd (%rsp),%xmm3
mulsd  %xmm0,%xmm4
movslq %r14d,%rax
movsd  %xmm4,(%rbx,%rax,8)
test   %r14d,%r14d
je     134f <fgamma+0x22f>
addsd  %xmm3,%xmm3
test   $0x1,%r14b
je     1233 <fgamma+0x113>
lea    -0x1(%rax),%rcx
mulsd  %xmm3,%xmm4
addsd  %xmm0,%xmm4
xorps  %xmm1,%xmm1
cvtsi2sd %ecx,%xmm1
addsd  %xmm1,%xmm1
addsd  0xdf2(%rip),%xmm1
divsd  %xmm1,%xmm4
movsd  %xmm4,-0x8(%rbx,%rax,8)
mov    %rcx,%rax
cmp    $0x1,%r14d
je     134f <fgamma+0x22f>
lea    (%rbx,%rax,8),%rcx
add    $0xfffffffffffffff8,%rcx
add    $0xffffffff,%eax
movsd  0xdc8(%rip),%xmm1
mulsd  %xmm3,%xmm4
addsd  %xmm0,%xmm4
xorps  %xmm2,%xmm2
cvtsi2sd %eax,%xmm2
addsd  %xmm2,%xmm2
addsd  %xmm1,%xmm2
divsd  %xmm2,%xmm4
movsd  %xmm4,(%rcx)
mulsd  %xmm3,%xmm4
lea    -0x1(%rax),%edx
xorps  %xmm2,%xmm2
cvtsi2sd %edx,%xmm2
addsd  %xmm0,%xmm4
addsd  %xmm2,%xmm2
addsd  %xmm1,%xmm2
divsd  %xmm2,%xmm4
movsd  %xmm4,-0x8(%rcx)
add    $0xfffffffffffffff0,%rcx
add    $0xfffffffe,%eax
cmp    $0xffffffff,%eax
jne    1250 <fgamma+0x130>
jmp    134f <fgamma+0x22f>
movapd %xmm5,%xmm0
movapd %xmm5,(%rsp)
call   1040 <sqrt@plt>
movapd (%rsp),%xmm5
movsd  0xd62(%rip),%xmm1
divsd  %xmm0,%xmm1
movsd  %xmm1,(%rbx)
test   %r14d,%r14d
jle    134f <fgamma+0x22f>
mov    %r14d,%ecx
mov    $0x1,%eax
cmp    $0x1,%r14d
je     132e <fgamma+0x20e>
mov    %ecx,%edx
and    $0xfffffffe,%edx
mov    $0x1,%eax
movsd  0xd39(%rip),%xmm0
nop
xorps  %xmm2,%xmm2
cvtsi2sd %eax,%xmm2
addsd  %xmm0,%xmm2
mulsd  %xmm1,%xmm2
divsd  %xmm5,%xmm2
movsd  %xmm2,(%rbx,%rax,8)
lea    0x1(%rax),%rsi
xorps  %xmm1,%xmm1
cvtsi2sd %esi,%xmm1
addsd  %xmm0,%xmm1
mulsd  %xmm2,%xmm1
divsd  %xmm5,%xmm1
movsd  %xmm1,0x8(%rbx,%rax,8)
add    $0x2,%rax
cmp    %rdx,%rsi
jne    12f0 <fgamma+0x1d0>
test   $0x1,%cl
je     134f <fgamma+0x22f>
xorps  %xmm0,%xmm0
cvtsi2sd %eax,%xmm0
addsd  0xce6(%rip),%xmm0
mulsd  %xmm1,%xmm0
divsd  %xmm5,%xmm0
movsd  %xmm0,(%rbx,%rax,8)
add    $0x18,%rsp
pop    %rbx
pop    %r14
ret

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

LLVM IR (-O2):
define void @fgamma(double* nocapture %0, double %1, i32 %2) {
%4 = shl nsw i32 %2, 1
%5 = sitofp i32 %4 to double
%6 = fadd double %5, 3.600000e+01
%7 = fcmp olt double %6, %1
br i1 %7, label %8, label %38
8: ; preds = %3
%9 = tail call double @sqrt(double %1)
%10 = fdiv double 0x3FEC5BF891B4EF6B, %9
store double %10, double* %0
%11 = icmp slt i32 %2, 1
br i1 %11, label %107, label %12
12: ; preds = %8
%13 = zext i32 %2 to i64
%14 = and i64 %13, 1
%15 = icmp eq i32 %2, 1
br i1 %15, label %96, label %16
16: ; preds = %12
%17 = and i64 %13, 4294967294
br label %18
18: ; preds = %18, %16
%19 = phi double [ %10, %16 ], [ %33, %18 ]
%20 = phi i64 [ 1, %16 ], [ %35, %18 ]
%21 = phi i64 [ 0, %16 ], [ %36, %18 ]
%22 = trunc i64 %20 to i32
%23 = sitofp i32 %22 to double
%24 = fadd double %23, -5.000000e-01
%25 = fmul double %24, %19
%26 = fdiv double %25, %1
%27 = getelementptr inbounds double, double* %0, i64 %20
store double %26, double* %27
%28 = add nuw nsw i64 %20, 1
%29 = trunc i64 %28 to i32
%30 = sitofp i32 %29 to double
%31 = fadd double %30, -5.000000e-01
%32 = fmul double %31, %26
%33 = fdiv double %32, %1
%34 = getelementptr inbounds double, double* %0, i64 %28
store double %33, double* %34
%35 = add nuw nsw i64 %20, 2
%36 = add i64 %21, 2
%37 = icmp eq i64 %36, %17
br i1 %37, label %96, label %18
38: ; preds = %3
%39 = sitofp i32 %2 to double
%40 = fadd double %39, 5.000000e-01
%41 = fdiv double 5.000000e-01, %40
br label %42
42: ; preds = %42, %38
%43 = phi i32 [ 1, %38 ], [ %52, %42 ]
%44 = phi double [ %41, %38 ], [ %50, %42 ]
%45 = phi double [ %41, %38 ], [ %49, %42 ]
%46 = sitofp i32 %43 to double
%47 = fadd double %40, %46
%48 = fdiv double %1, %47
%49 = fmul double %45, %48
%50 = fadd double %44, %49
%51 = fcmp olt double %49, 0x3D06849B86A12B9B
%52 = add nuw nsw i32 %43, 1
%53 = icmp eq i32 %52, 501
%54 = select i1 %51, i1 true, i1 %53
br i1 %54, label %55, label %42
55: ; preds = %42
%56 = fmul double %1, 2.000000e+00
%57 = fneg double %1
%58 = tail call double @exp(double %57)
%59 = fmul double %50, %58
%60 = sext i32 %2 to i64
%61 = getelementptr inbounds double, double* %0, i64 %60
store double %59, double* %61
%62 = icmp eq i32 %2, 0
br i1 %62, label %107, label %63
63: ; preds = %55
%64 = and i32 %2, 1
%65 = icmp eq i32 %64, 0
br i1 %65, label %74, label %66
66: ; preds = %63
%67 = add nsw i64 %60, -1
%68 = tail call double @llvm.fmuladd.f64(double %59, double %56, double %58)
%69 = trunc i64 %67 to i32
%70 = sitofp i32 %69 to double
%71 = tail call double @llvm.fmuladd.f64(double %70, double 2.000000e+00, double 1.000000e+00)
%72 = fdiv double %68, %71
%73 = getelementptr inbounds double, double* %0, i64 %67
store double %72, double* %73
br label %74
74: ; preds = %66, %63
%75 = phi double [ %59, %63 ], [ %72, %66 ]
%76 = phi i64 [ %60, %63 ], [ %67, %66 ]
%77 = icmp eq i32 %2, 1
br i1 %77, label %107, label %78
78: ; preds = %74, %78
%79 = phi double [ %93, %78 ], [ %75, %74 ]
%80 = phi i64 [ %88, %78 ], [ %76, %74 ]
%81 = add nsw i64 %80, -1
%82 = tail call double @llvm.fmuladd.f64(double %79, double %56, double %58)
%83 = trunc i64 %81 to i32
%84 = sitofp i32 %83 to double
%85 = tail call double @llvm.fmuladd.f64(double %84, double 2.000000e+00, double 1.000000e+00)
%86 = fdiv double %82, %85
%87 = getelementptr inbounds double, double* %0, i64 %81
store double %86, double* %87
%88 = add nsw i64 %80, -2
%89 = tail call double @llvm.fmuladd.f64(double %86, double %56, double %58)
%90 = trunc i64 %88 to i32
%91 = sitofp i32 %90 to double
%92 = tail call double @llvm.fmuladd.f64(double %91, double 2.000000e+00, double 1.000000e+00)
%93 = fdiv double %89, %92
%94 = getelementptr inbounds double, double* %0, i64 %88
store double %93, double* %94
%95 = icmp eq i32 %90, 0
br i1 %95, label %107, label %78
96: ; preds = %18, %12
%97 = phi double [ %10, %12 ], [ %33, %18 ]
%98 = phi i64 [ 1, %12 ], [ %35, %18 ]
%99 = icmp eq i64 %14, 0
br i1 %99, label %107, label %100
100: ; preds = %96
%101 = trunc i64 %98 to i32
%102 = sitofp i32 %101 to double
%103 = fadd double %102, -5.000000e-01
%104 = fmul double %103, %97
%105 = fdiv double %104, %1
%106 = getelementptr inbounds double, double* %0, i64 %98
store double %105, double* %106
br label %107
107: ; preds = %74, %78, %100, %96, %55, %8
ret void
}