#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 HUGE_VAL;
int /*<<< orphan*/ fff_combination(unsigned int *, unsigned int, unsigned int,
                                   double);
double floor(double);
unsigned int fff_twosample_permutation(unsigned int *idx1, unsigned int *idx2,
                                       unsigned int n1, unsigned int n2,
                                       double *magic) {
  unsigned int n = ((n1) < (n2) ? (n1) : (n2)), i;
  double aux, magic1, magic2, cuml = 0, cumr = 1, c1 = 1, c2 = 1;
  if ((idx1 == NULL) || (idx2 == NULL))
    *magic = HUGE_VAL;
  for (i = 0; i <= n; i++) {
    if (*magic < cumr) {
      *magic -= cuml;
      break;
    }
    aux = (double)(i + 1);
    c1 *= (n1 - i);
    c1 /= aux;
    c2 *= (n2 - i);
    c2 /= aux;
    cuml = cumr;
    cumr += c1 * c2;
  }
  if (*magic >= cumr) {
    *magic = cumr;
    return 0;
  }
  magic2 = floor(*magic / c1);
  magic1 = *magic - magic2 * c1;
  fff_combination(idx1, i, n1, magic1);
  fff_combination(idx2, i, n2, magic2);
  return i;
}


x86 assembly (clang, -O0):
<fff_twosample_permutation>:
push   %rbp
mov    %rsp,%rbp
sub    $0x70,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %edx,-0x1c(%rbp)
mov    %ecx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0x20(%rbp),%eax
jae    1151 <fff_twosample_permutation+0x31>
mov    -0x1c(%rbp),%eax
mov    %eax,-0x6c(%rbp)
jmp    1157 <fff_twosample_permutation+0x37>
mov    -0x20(%rbp),%eax
mov    %eax,-0x6c(%rbp)
mov    -0x6c(%rbp),%eax
mov    %eax,-0x2c(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  0xe93(%rip),%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  0xe86(%rip),%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  0xe79(%rip),%xmm0
movsd  %xmm0,-0x68(%rbp)
cmpq   $0x0,-0x10(%rbp)
je     11a2 <fff_twosample_permutation+0x82>
cmpq   $0x0,-0x18(%rbp)
jne    11b5 <fff_twosample_permutation+0x95>
mov    0x2e3f(%rip),%rax
movsd  (%rax),%xmm0
mov    -0x28(%rbp),%rax
movsd  %xmm0,(%rax)
movl   $0x0,-0x30(%rbp)
mov    -0x30(%rbp),%eax
cmp    -0x2c(%rbp),%eax
ja     1295 <fff_twosample_permutation+0x175>
mov    -0x28(%rbp),%rax
movsd  (%rax),%xmm1
movsd  -0x58(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    11f9 <fff_twosample_permutation+0xd9>
movsd  -0x50(%rbp),%xmm1
mov    -0x28(%rbp),%rax
movsd  (%rax),%xmm0
subsd  %xmm1,%xmm0
movsd  %xmm0,(%rax)
jmp    1295 <fff_twosample_permutation+0x175>
mov    -0x30(%rbp),%eax
add    $0x1,%eax
cvtsi2sd %rax,%xmm0
movsd  %xmm0,-0x38(%rbp)
mov    -0x1c(%rbp),%eax
mov    -0x30(%rbp),%ecx
sub    %ecx,%eax
cvtsi2sd %rax,%xmm1
movsd  -0x60(%rbp),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  -0x38(%rbp),%xmm1
movsd  -0x60(%rbp),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x60(%rbp)
mov    -0x20(%rbp),%eax
mov    -0x30(%rbp),%ecx
sub    %ecx,%eax
cvtsi2sd %rax,%xmm0
mulsd  -0x68(%rbp),%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  -0x38(%rbp),%xmm1
movsd  -0x68(%rbp),%xmm0
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  -0x58(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x60(%rbp),%xmm0
movsd  -0x68(%rbp),%xmm2
movsd  -0x58(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x30(%rbp)
jmp    11bc <fff_twosample_permutation+0x9c>
mov    -0x28(%rbp),%rax
movsd  (%rax),%xmm0
ucomisd -0x58(%rbp),%xmm0
jb     12c1 <fff_twosample_permutation+0x1a1>
movsd  -0x58(%rbp),%xmm0
mov    -0x28(%rbp),%rax
movsd  %xmm0,(%rax)
movl   $0x0,-0x4(%rbp)
jmp    133c <fff_twosample_permutation+0x21c>
mov    -0x28(%rbp),%rax
movsd  (%rax),%xmm0
divsd  -0x60(%rbp),%xmm0
call   1040 <floor@plt>
movsd  %xmm0,-0x48(%rbp)
mov    -0x28(%rbp),%rax
movsd  (%rax),%xmm1
movsd  -0x48(%rbp),%xmm0
movsd  -0x60(%rbp),%xmm2
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x10(%rbp),%rdi
mov    -0x30(%rbp),%esi
mov    -0x1c(%rbp),%edx
movsd  -0x40(%rbp),%xmm0
call   1030 <fff_combination@plt>
mov    -0x18(%rbp),%rdi
mov    -0x30(%rbp),%esi
mov    -0x20(%rbp),%edx
movsd  -0x48(%rbp),%xmm0
call   1030 <fff_combination@plt>
mov    -0x30(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x70,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<fff_twosample_permutation>:
push   %rbp
push   %r15
push   %r14
push   %r12
push   %rbx
sub    $0x20,%rsp
mov    %ecx,%r12d
mov    %edx,%ebp
mov    %rsi,%r14
mov    %rdi,%r15
cmp    %ecx,%edx
mov    %ecx,%eax
cmovb  %edx,%eax
test   %rdi,%rdi
je     114f <fff_twosample_permutation+0x2f>
test   %r14,%r14
je     114f <fff_twosample_permutation+0x2f>
movsd  (%r8),%xmm7
jmp    115f <fff_twosample_permutation+0x3f>
mov    0x2e92(%rip),%rcx
movsd  (%rcx),%xmm7
movsd  %xmm7,(%r8)
movsd  0xe99(%rip),%xmm3
ucomisd %xmm7,%xmm3
jbe    117c <fff_twosample_permutation+0x5c>
xor    %ebx,%ebx
xorpd  %xmm1,%xmm1
movapd %xmm3,%xmm0
jmp    1205 <fff_twosample_permutation+0xe5>
movd   %r12d,%xmm0
movd   %ebp,%xmm2
punpckldq %xmm0,%xmm2
movapd 0xe7f(%rip),%xmm3
movsd  0xe67(%rip),%xmm0
xor    %ecx,%ecx
pxor   %xmm8,%xmm8
movdqa 0xe78(%rip),%xmm4
nopl   0x0(%rax,%rax,1)
movapd %xmm0,%xmm1
lea    0x1(%rcx),%ebx
xorps  %xmm0,%xmm0
cvtsi2sd %rbx,%xmm0
movd   %ecx,%xmm5
pshufd $0x50,%xmm5,%xmm5
movdqa %xmm2,%xmm6
psubd  %xmm5,%xmm6
punpckldq %xmm8,%xmm6
por    %xmm4,%xmm6
subpd  %xmm4,%xmm6
mulpd  %xmm6,%xmm3
unpcklpd %xmm0,%xmm0
divpd  %xmm0,%xmm3
movapd %xmm3,%xmm0
unpckhpd %xmm3,%xmm0
mulsd  %xmm3,%xmm0
addsd  %xmm1,%xmm0
cmp    %eax,%ebx
ja     1266 <fff_twosample_permutation+0x146>
ucomisd %xmm7,%xmm0
mov    %ebx,%ecx
jbe    11b0 <fff_twosample_permutation+0x90>
subsd  %xmm1,%xmm7
movsd  %xmm7,(%r8)
ucomisd %xmm0,%xmm7
jae    1271 <fff_twosample_permutation+0x151>
movapd %xmm7,%xmm0
divsd  %xmm3,%xmm0
movsd  %xmm7,(%rsp)
movapd %xmm3,0x10(%rsp)
call   1040 <floor@plt>
movsd  %xmm0,0x8(%rsp)
movapd 0x10(%rsp),%xmm1
mulsd  %xmm0,%xmm1
movsd  (%rsp),%xmm0
subsd  %xmm1,%xmm0
mov    %r15,%rdi
mov    %ebx,%esi
mov    %ebp,%edx
call   1030 <fff_combination@plt>
mov    %r14,%rdi
mov    %ebx,%esi
mov    %r12d,%edx
movsd  0x8(%rsp),%xmm0
call   1030 <fff_combination@plt>
jmp    1278 <fff_twosample_permutation+0x158>
add    $0x1,%ecx
mov    %ecx,%ebx
ucomisd %xmm0,%xmm7
jb     1214 <fff_twosample_permutation+0xf4>
movsd  %xmm0,(%r8)
xor    %ebx,%ebx
mov    %ebx,%eax
add    $0x20,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@HUGE_VAL = global double 0.000000e+00
define i32 @fff_twosample_permutation(i32* %0, i32* %1, i32 %2, i32 %3, double* %4) {
%6 = alloca i32
%7 = alloca i32*
%8 = alloca i32*
%9 = alloca i32
%10 = alloca i32
%11 = alloca double*
%12 = alloca i32
%13 = alloca i32
%14 = alloca double
%15 = alloca double
%16 = alloca double
%17 = alloca double
%18 = alloca double
%19 = alloca double
%20 = alloca double
store i32* %0, i32** %7
store i32* %1, i32** %8
store i32 %2, i32* %9
store i32 %3, i32* %10
store double* %4, double** %11
%21 = load i32, i32* %9
%22 = load i32, i32* %10
%23 = icmp ult i32 %21, %22
br i1 %23, label %24, label %26
24: ; preds = %5
%25 = load i32, i32* %9
br label %28
26: ; preds = %5
%27 = load i32, i32* %10
br label %28
28: ; preds = %26, %24
%29 = phi i32 [ %25, %24 ], [ %27, %26 ]
store i32 %29, i32* %12
store double 0.000000e+00, double* %17
store double 1.000000e+00, double* %18
store double 1.000000e+00, double* %19
store double 1.000000e+00, double* %20
%30 = load i32*, i32** %7
%31 = icmp eq i32* %30, null
br i1 %31, label %35, label %32
32: ; preds = %28
%33 = load i32*, i32** %8
%34 = icmp eq i32* %33, null
br i1 %34, label %35, label %38
35: ; preds = %32, %28
%36 = load double, double* @HUGE_VAL
%37 = load double*, double** %11
store double %36, double* %37
br label %38
38: ; preds = %35, %32
store i32 0, i32* %13
br label %39
39: ; preds = %80, %38
%40 = load i32, i32* %13
%41 = load i32, i32* %12
%42 = icmp ule i32 %40, %41
br i1 %42, label %43, label %83
43: ; preds = %39
%44 = load double*, double** %11
%45 = load double, double* %44
%46 = load double, double* %18
%47 = fcmp olt double %45, %46
br i1 %47, label %48, label %53
48: ; preds = %43
%49 = load double, double* %17
%50 = load double*, double** %11
%51 = load double, double* %50
%52 = fsub double %51, %49
store double %52, double* %50
br label %83
53: ; preds = %43
%54 = load i32, i32* %13
%55 = add i32 %54, 1
%56 = uitofp i32 %55 to double
store double %56, double* %14
%57 = load i32, i32* %9
%58 = load i32, i32* %13
%59 = sub i32 %57, %58
%60 = uitofp i32 %59 to double
%61 = load double, double* %19
%62 = fmul double %61, %60
store double %62, double* %19
%63 = load double, double* %14
%64 = load double, double* %19
%65 = fdiv double %64, %63
store double %65, double* %19
%66 = load i32, i32* %10
%67 = load i32, i32* %13
%68 = sub i32 %66, %67
%69 = uitofp i32 %68 to double
%70 = load double, double* %20
%71 = fmul double %70, %69
store double %71, double* %20
%72 = load double, double* %14
%73 = load double, double* %20
%74 = fdiv double %73, %72
store double %74, double* %20
%75 = load double, double* %18
store double %75, double* %17
%76 = load double, double* %19
%77 = load double, double* %20
%78 = load double, double* %18
%79 = call double @llvm.fmuladd.f64(double %76, double %77, double %78)
store double %79, double* %18
br label %80
80: ; preds = %53
%81 = load i32, i32* %13
%82 = add i32 %81, 1
store i32 %82, i32* %13
br label %39
83: ; preds = %48, %39
%84 = load double*, double** %11
%85 = load double, double* %84
%86 = load double, double* %18
%87 = fcmp oge double %85, %86
br i1 %87, label %88, label %91
88: ; preds = %83
%89 = load double, double* %18
%90 = load double*, double** %11
store double %89, double* %90
store i32 0, i32* %6
br label %114
91: ; preds = %83
%92 = load double*, double** %11
%93 = load double, double* %92
%94 = load double, double* %19
%95 = fdiv double %93, %94
%96 = call double @llvm.floor.f64(double %95)
store double %96, double* %16
%97 = load double*, double** %11
%98 = load double, double* %97
%99 = load double, double* %16
%100 = load double, double* %19
%101 = fneg double %99
%102 = call double @llvm.fmuladd.f64(double %101, double %100, double %98)
store double %102, double* %15
%103 = load i32*, i32** %7
%104 = load i32, i32* %13
%105 = load i32, i32* %9
%106 = load double, double* %15
%107 = call i32 @fff_combination(i32* %103, i32 %104, i32 %105, double %106)
%108 = load i32*, i32** %8
%109 = load i32, i32* %13
%110 = load i32, i32* %10
%111 = load double, double* %16
%112 = call i32 @fff_combination(i32* %108, i32 %109, i32 %110, double %111)
%113 = load i32, i32* %13
store i32 %113, i32* %6
br label %114
114: ; preds = %91, %88
%115 = load i32, i32* %6
ret i32 %115
}

LLVM IR (-O2):
@HUGE_VAL = global double 0.000000e+00
define i32 @fff_twosample_permutation(i32* %0, i32* %1, i32 %2, i32 %3, double* nocapture %4) {
%6 = icmp ult i32 %2, %3
%7 = select i1 %6, i32 %2, i32 %3
%8 = icmp eq i32* %0, null
%9 = icmp eq i32* %1, null
%10 = or i1 %8, %9
br i1 %10, label %13, label %11
11: ; preds = %5
%12 = load double, double* %4
br label %15
13: ; preds = %5
%14 = load double, double* @HUGE_VAL
store double %14, double* %4
br label %15
15: ; preds = %11, %13
%16 = phi double [ %12, %11 ], [ %14, %13 ]
%17 = fcmp olt double %16, 1.000000e+00
br i1 %17, label %25, label %18
18: ; preds = %15
%19 = insertelement <2 x i32> poison, i32 %2, i64 0
%20 = insertelement <2 x i32> %19, i32 %3, i64 1
br label %31
21: ; preds = %31
%22 = fcmp olt double %16, %47
br i1 %22, label %23, label %31
23: ; preds = %21
%24 = extractelement <2 x double> %44, i64 0
br label %25
25: ; preds = %23, %15
%26 = phi double [ 1.000000e+00, %15 ], [ %24, %23 ]
%27 = phi double [ 1.000000e+00, %15 ], [ %47, %23 ]
%28 = phi double [ 0.000000e+00, %15 ], [ %33, %23 ]
%29 = phi i32 [ 0, %15 ], [ %35, %23 ]
%30 = fsub double %16, %28
store double %30, double* %4
br label %51
31: ; preds = %18, %21
%32 = phi i32 [ %35, %21 ], [ 0, %18 ]
%33 = phi double [ %47, %21 ], [ 1.000000e+00, %18 ]
%34 = phi <2 x double> [ %44, %21 ], [ <double 1.000000e+00, double 1.000000e+00>, %18 ]
%35 = add i32 %32, 1
%36 = uitofp i32 %35 to double
%37 = insertelement <2 x i32> poison, i32 %32, i64 0
%38 = shufflevector <2 x i32> %37, <2 x i32> poison, <2 x i32> zeroinitializer
%39 = sub <2 x i32> %20, %38
%40 = uitofp <2 x i32> %39 to <2 x double>
%41 = fmul <2 x double> %34, %40
%42 = insertelement <2 x double> poison, double %36, i64 0
%43 = shufflevector <2 x double> %42, <2 x double> poison, <2 x i32> zeroinitializer
%44 = fdiv <2 x double> %41, %43
%45 = extractelement <2 x double> %44, i64 0
%46 = extractelement <2 x double> %44, i64 1
%47 = tail call double @llvm.fmuladd.f64(double %45, double %46, double %33)
%48 = icmp ugt i32 %35, %7
br i1 %48, label %49, label %21
49: ; preds = %31
%50 = extractelement <2 x double> %44, i64 0
br label %51
51: ; preds = %49, %25
%52 = phi double [ %30, %25 ], [ %16, %49 ]
%53 = phi i32 [ %29, %25 ], [ %35, %49 ]
%54 = phi double [ %27, %25 ], [ %47, %49 ]
%55 = phi double [ %26, %25 ], [ %50, %49 ]
%56 = fcmp ult double %52, %54
br i1 %56, label %58, label %57
57: ; preds = %51
store double %54, double* %4
br label %65
58: ; preds = %51
%59 = fdiv double %52, %55
%60 = tail call double @llvm.floor.f64(double %59)
%61 = fneg double %60
%62 = tail call double @llvm.fmuladd.f64(double %61, double %55, double %52)
%63 = tail call i32 @fff_combination(i32* %0, i32 %53, i32 %2, double %62)
%64 = tail call i32 @fff_combination(i32* %1, i32 %53, i32 %3, double %60)
br label %65
65: ; preds = %58, %57
%66 = phi i32 [ 0, %57 ], [ %53, %58 ]
ret i32 %66
}