#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 */
scalar_t__ ceill(long double const);
long double const floorl(long double const);
long double percentile_value(long long unsigned *samples,
                             const long double index,
                             const long long unsigned total_number) {
  long long unsigned prev, next;
  long double value;
  prev = (long long unsigned int)floorl(index);
  next = (long long unsigned int)ceill(index);
  if (next >= total_number)
    return (long double)samples[prev];
  value = (long double)samples[prev] +
          (index - floorl(index)) * ((double)samples[next] - samples[prev]);
  return value;
}


x86 assembly (clang, -O0):
<percentile_value>:
push   %rbp
mov    %rsp,%rbp
sub    $0xb0,%rsp
fldt   0x10(%rbp)
mov    %rdi,-0x18(%rbp)
fstpt  -0x30(%rbp)
mov    %rsi,-0x38(%rbp)
fldt   -0x30(%rbp)
mov    %rsp,%rax
fstpt  (%rax)
call   1040 <floorl@plt>
flds   0xeb4(%rip)
fxch   %st(1)
fucomi %st(1),%st
setae  %al
fldz
fcmovnb %st(2),%st
fstp   %st(2)
fsubp  %st,%st(1)
fnstcw -0x82(%rbp)
movzwl -0x82(%rbp),%ecx
or     $0xc00,%ecx
mov    %cx,-0x84(%rbp)
fldcw  -0x84(%rbp)
fistpll -0x68(%rbp)
fldcw  -0x82(%rbp)
movzbl %al,%eax
mov    %eax,%ecx
shl    $0x3f,%rcx
mov    -0x68(%rbp),%rax
xor    %rcx,%rax
mov    %rax,-0x40(%rbp)
fldt   -0x30(%rbp)
mov    %rsp,%rax
fstpt  (%rax)
call   1030 <ceill@plt>
mov    %rax,-0x48(%rbp)
mov    -0x48(%rbp),%rax
cmp    -0x38(%rbp),%rax
jb     11e9 <percentile_value+0xc9>
mov    -0x18(%rbp),%rax
mov    -0x40(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
mov    %rax,-0x80(%rbp)
test   %rax,%rax
sets   %al
movzbl %al,%eax
mov    %eax,%ecx
fildll -0x80(%rbp)
lea    0xe2c(%rip),%rax
flds   (%rax,%rcx,4)
faddp  %st,%st(1)
fstpt  -0x10(%rbp)
jmp    12a0 <percentile_value+0x180>
mov    -0x18(%rbp),%rax
mov    -0x40(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
mov    %rax,-0x70(%rbp)
test   %rax,%rax
sets   %al
movzbl %al,%eax
mov    %eax,%ecx
fildll -0x70(%rbp)
lea    0xdfa(%rip),%rax
flds   (%rax,%rcx,4)
faddp  %st,%st(1)
fstpt  -0x9c(%rbp)
fldt   -0x30(%rbp)
fld    %st(0)
fstpt  -0x90(%rbp)
mov    %rsp,%rax
fstpt  (%rax)
call   1040 <floorl@plt>
fldt   -0x9c(%rbp)
fldt   -0x90(%rbp)
fsubp  %st,%st(2)
mov    -0x18(%rbp),%rax
mov    -0x48(%rbp),%rcx
movq   (%rax,%rcx,8),%xmm0
movaps 0xdc0(%rip),%xmm3
punpckldq %xmm3,%xmm0
movapd 0xdc4(%rip),%xmm2
subpd  %xmm2,%xmm0
movaps %xmm0,%xmm1
unpckhpd %xmm0,%xmm0
addsd  %xmm1,%xmm0
mov    -0x40(%rbp),%rcx
movq   (%rax,%rcx,8),%xmm1
punpckldq %xmm3,%xmm1
subpd  %xmm2,%xmm1
movaps %xmm1,%xmm2
unpckhpd %xmm1,%xmm1
addsd  %xmm2,%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x78(%rbp)
fldl   -0x78(%rbp)
fmulp  %st,%st(2)
faddp  %st,%st(1)
fstpt  -0x60(%rbp)
fldt   -0x60(%rbp)
fstpt  -0x10(%rbp)
fldt   -0x10(%rbp)
add    $0xb0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<percentile_value>:
push   %r15
push   %r14
push   %r12
push   %rbx
sub    $0x48,%rsp
mov    %rsi,%r14
mov    %rdi,%r15
fldt   0x70(%rsp)
fld    %st(0)
fstpt  0x14(%rsp)
fstpt  (%rsp)
call   1040 <floorl@plt>
flds   0xeb7(%rip)
xor    %ebx,%ebx
fxch   %st(1)
fucomi %st(1),%st
setae  %bl
fldz
fcmovnb %st(2),%st
fstp   %st(2)
fsubp  %st,%st(1)
fnstcw 0x10(%rsp)
movzwl 0x10(%rsp),%eax
or     $0xc00,%eax
mov    %ax,0x12(%rsp)
fldcw  0x12(%rsp)
fistpll 0x28(%rsp)
fldcw  0x10(%rsp)
shl    $0x3f,%rbx
xor    0x28(%rsp),%rbx
fldt   0x14(%rsp)
fstpt  (%rsp)
call   1030 <ceill@plt>
mov    %rax,%r12
mov    (%r15,%rbx,8),%rax
xor    %ecx,%ecx
test   %rax,%rax
sets   %cl
mov    %rax,0x30(%rsp)
fildll 0x30(%rsp)
lea    0xe5b(%rip),%rax
fadds  (%rax,%rcx,4)
cmp    %r14,%r12
jae    1221 <percentile_value+0x101>
fldt   0x14(%rsp)
fstpt  (%rsp)
fstpt  0x3c(%rsp)
call   1040 <floorl@plt>
fldt   0x14(%rsp)
fsubp  %st,%st(1)
movsd  (%r15,%r12,8),%xmm0
movapd 0xe37(%rip),%xmm1
unpcklps %xmm1,%xmm0
movapd 0xe3c(%rip),%xmm2
subpd  %xmm2,%xmm0
movapd %xmm0,%xmm3
unpckhpd %xmm0,%xmm3
addsd  %xmm0,%xmm3
movsd  (%r15,%rbx,8),%xmm0
unpcklps %xmm1,%xmm0
subpd  %xmm2,%xmm0
movapd %xmm0,%xmm1
unpckhpd %xmm0,%xmm1
addsd  %xmm0,%xmm1
subsd  %xmm1,%xmm3
movsd  %xmm3,0x20(%rsp)
fmull  0x20(%rsp)
fldt   0x3c(%rsp)
faddp  %st,%st(1)
add    $0x48,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
define x86_fp80 @percentile_value(i64* %0, x86_fp80 %1, i64 %2) {
%4 = alloca x86_fp80
%5 = alloca i64*
%6 = alloca x86_fp80
%7 = alloca i64
%8 = alloca i64
%9 = alloca i64
%10 = alloca x86_fp80
store i64* %0, i64** %5
store x86_fp80 %1, x86_fp80* %6
store i64 %2, i64* %7
%11 = load x86_fp80, x86_fp80* %6
%12 = call x86_fp80 @floorl(x86_fp80 %11)
%13 = fptoui x86_fp80 %12 to i64
store i64 %13, i64* %8
%14 = load x86_fp80, x86_fp80* %6
%15 = call i64 @ceill(x86_fp80 %14)
store i64 %15, i64* %9
%16 = load i64, i64* %9
%17 = load i64, i64* %7
%18 = icmp uge i64 %16, %17
br i1 %18, label %19, label %25
19: ; preds = %3
%20 = load i64*, i64** %5
%21 = load i64, i64* %8
%22 = getelementptr inbounds i64, i64* %20, i64 %21
%23 = load i64, i64* %22
%24 = uitofp i64 %23 to x86_fp80
store x86_fp80 %24, x86_fp80* %4
br label %49
25: ; preds = %3
%26 = load i64*, i64** %5
%27 = load i64, i64* %8
%28 = getelementptr inbounds i64, i64* %26, i64 %27
%29 = load i64, i64* %28
%30 = uitofp i64 %29 to x86_fp80
%31 = load x86_fp80, x86_fp80* %6
%32 = load x86_fp80, x86_fp80* %6
%33 = call x86_fp80 @floorl(x86_fp80 %32)
%34 = fsub x86_fp80 %31, %33
%35 = load i64*, i64** %5
%36 = load i64, i64* %9
%37 = getelementptr inbounds i64, i64* %35, i64 %36
%38 = load i64, i64* %37
%39 = uitofp i64 %38 to double
%40 = load i64*, i64** %5
%41 = load i64, i64* %8
%42 = getelementptr inbounds i64, i64* %40, i64 %41
%43 = load i64, i64* %42
%44 = uitofp i64 %43 to double
%45 = fsub double %39, %44
%46 = fpext double %45 to x86_fp80
%47 = call x86_fp80 @llvm.fmuladd.f80(x86_fp80 %34, x86_fp80 %46, x86_fp80 %30)
store x86_fp80 %47, x86_fp80* %10
%48 = load x86_fp80, x86_fp80* %10
store x86_fp80 %48, x86_fp80* %4
br label %49
49: ; preds = %25, %19
%50 = load x86_fp80, x86_fp80* %4
ret x86_fp80 %50
}

LLVM IR (-O2):
define x86_fp80 @percentile_value(i64* nocapture %0, x86_fp80 %1, i64 %2) {
%4 = tail call x86_fp80 @floorl(x86_fp80 %1)
%5 = fptoui x86_fp80 %4 to i64
%6 = tail call i64 @ceill(x86_fp80 %1)
%7 = icmp ult i64 %6, %2
%8 = getelementptr inbounds i64, i64* %0, i64 %5
%9 = load i64, i64* %8
%10 = uitofp i64 %9 to x86_fp80
br i1 %7, label %11, label %22
11: ; preds = %3
%12 = tail call x86_fp80 @floorl(x86_fp80 %1)
%13 = fsub x86_fp80 %1, %12
%14 = getelementptr inbounds i64, i64* %0, i64 %6
%15 = load i64, i64* %14
%16 = uitofp i64 %15 to double
%17 = load i64, i64* %8
%18 = uitofp i64 %17 to double
%19 = fsub double %16, %18
%20 = fpext double %19 to x86_fp80
%21 = tail call x86_fp80 @llvm.fmuladd.f80(x86_fp80 %13, x86_fp80 %20, x86_fp80 %10)
br label %22
22: ; preds = %3, %11
%23 = phi x86_fp80 [ %21, %11 ], [ %10, %3 ]
ret x86_fp80 %23
}