int combos(int n, int k) {
  int ret = 1;
  for (int i = k + 1; i <= n; i++)
    ret *= i;
  for (int i = 1; i <= n - k; i++)
    ret /= i;
  return ret;
}


x86 assembly (clang, -O0):
<combos>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
movl   $0x1,-0xc(%rbp)
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x10(%rbp)
mov    -0x10(%rbp),%eax
cmp    -0x4(%rbp),%eax
jg     113e <combos+0x3e>
mov    -0x10(%rbp),%eax
imul   -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
mov    -0x10(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x10(%rbp)
jmp    111a <combos+0x1a>
movl   $0x1,-0x14(%rbp)
mov    -0x14(%rbp),%eax
mov    -0x4(%rbp),%ecx
sub    -0x8(%rbp),%ecx
cmp    %ecx,%eax
jg     1170 <combos+0x70>
mov    -0x14(%rbp),%ecx
mov    -0xc(%rbp),%eax
cltd
idiv   %ecx
mov    %eax,-0xc(%rbp)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1145 <combos+0x45>
mov    -0xc(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<combos>:
mov    $0x1,%eax
mov    %edi,%r8d
sub    %esi,%r8d
jle    1382 <combos+0x282>
mov    $0x1,%eax
mov    %esi,%ecx
cmp    $0x8,%r8d
jb     1365 <combos+0x265>
mov    %r8d,%ecx
and    $0xfffffff8,%ecx
movd   %esi,%xmm0
pshufd $0x0,%xmm0,%xmm7
paddd  0xec7(%rip),%xmm7
lea    -0x8(%rcx),%r9d
mov    %r9d,%eax
shr    $0x3,%eax
add    $0x1,%eax
mov    %eax,%edx
and    $0x3,%edx
cmp    $0x18,%r9d
jae    1162 <combos+0x62>
movdqa 0xeb7(%rip),%xmm5
movdqa %xmm5,%xmm1
jmp    12a3 <combos+0x1a3>
and    $0xfffffffc,%eax
movdqa 0xea3(%rip),%xmm5
pcmpeqd %xmm8,%xmm8
movdqa 0xea5(%rip),%xmm9
movdqa 0xeac(%rip),%xmm10
movdqa 0xeb3(%rip),%xmm11
movdqa 0xeba(%rip),%xmm12
movdqa 0xec1(%rip),%xmm13
movdqa 0xec8(%rip),%xmm14
movdqa 0xecf(%rip),%xmm15
movdqa 0xed7(%rip),%xmm4
movdqa %xmm5,%xmm1
nopl   (%rax)
movdqa %xmm7,%xmm6
psubd  %xmm8,%xmm6
movdqa %xmm7,%xmm0
paddd  %xmm9,%xmm0
pshufd $0xf5,%xmm6,%xmm2
pshufd $0xf5,%xmm5,%xmm3
pmuludq %xmm2,%xmm3
pmuludq %xmm5,%xmm6
pshufd $0xf5,%xmm1,%xmm2
pshufd $0xf5,%xmm0,%xmm5
pmuludq %xmm2,%xmm5
pmuludq %xmm1,%xmm0
movdqa %xmm7,%xmm1
paddd  %xmm10,%xmm1
movdqa %xmm7,%xmm2
paddd  %xmm11,%xmm2
pmuludq %xmm1,%xmm6
pshufd $0xf5,%xmm1,%xmm1
pmuludq %xmm3,%xmm1
pmuludq %xmm2,%xmm0
pshufd $0xf5,%xmm2,%xmm2
pmuludq %xmm5,%xmm2
movdqa %xmm7,%xmm3
paddd  %xmm12,%xmm3
pshufd $0xf5,%xmm3,%xmm5
pmuludq %xmm1,%xmm5
movdqa %xmm7,%xmm1
paddd  %xmm13,%xmm1
pmuludq %xmm6,%xmm3
pshufd $0xf5,%xmm1,%xmm6
pmuludq %xmm2,%xmm6
pmuludq %xmm0,%xmm1
movdqa %xmm7,%xmm0
paddd  %xmm14,%xmm0
pmuludq %xmm0,%xmm3
pshufd $0xf5,%xmm0,%xmm0
pmuludq %xmm5,%xmm0
pshufd $0xe8,%xmm3,%xmm5
pshufd $0xe8,%xmm0,%xmm0
punpckldq %xmm0,%xmm5
movdqa %xmm7,%xmm0
paddd  %xmm15,%xmm0
pmuludq %xmm0,%xmm1
pshufd $0xf5,%xmm0,%xmm0
pmuludq %xmm6,%xmm0
pshufd $0xe8,%xmm1,%xmm1
pshufd $0xe8,%xmm0,%xmm0
punpckldq %xmm0,%xmm1
paddd  %xmm4,%xmm7
add    $0xfffffffc,%eax
jne    11c0 <combos+0xc0>
movdqa %xmm5,%xmm0
movdqa %xmm1,%xmm6
test   %edx,%edx
je     1332 <combos+0x232>
pcmpeqd %xmm8,%xmm8
movdqa 0xd60(%rip),%xmm3
movdqa 0xdd8(%rip),%xmm4
nopl   0x0(%rax,%rax,1)
movdqa %xmm7,%xmm0
psubd  %xmm8,%xmm0
movdqa %xmm7,%xmm6
paddd  %xmm3,%xmm6
pshufd $0xf5,%xmm0,%xmm2
pmuludq %xmm5,%xmm0
pshufd $0xe8,%xmm0,%xmm0
pshufd $0xf5,%xmm5,%xmm5
pmuludq %xmm2,%xmm5
pshufd $0xe8,%xmm5,%xmm2
punpckldq %xmm2,%xmm0
pshufd $0xf5,%xmm6,%xmm2
pmuludq %xmm1,%xmm6
pshufd $0xe8,%xmm6,%xmm6
pshufd $0xf5,%xmm1,%xmm1
pmuludq %xmm2,%xmm1
pshufd $0xe8,%xmm1,%xmm1
punpckldq %xmm1,%xmm6
paddd  %xmm4,%xmm7
movdqa %xmm0,%xmm5
movdqa %xmm6,%xmm1
add    $0xffffffff,%edx
jne    12d0 <combos+0x1d0>
pshufd $0xf5,%xmm0,%xmm1
pshufd $0xf5,%xmm6,%xmm2
pmuludq %xmm1,%xmm2
pmuludq %xmm0,%xmm6
pshufd $0xee,%xmm6,%xmm0
pmuludq %xmm6,%xmm0
pshufd $0xaa,%xmm2,%xmm1
pmuludq %xmm2,%xmm1
pmuludq %xmm0,%xmm1
movd   %xmm1,%eax
cmp    %ecx,%r8d
je     1382 <combos+0x282>
add    %esi,%ecx
mov    %edi,%r8d
neg    %r8d
add    $0x1,%ecx
xchg   %ax,%ax
imul   %ecx,%eax
lea    (%r8,%rcx,1),%edx
add    $0x1,%edx
add    $0x1,%ecx
cmp    $0x1,%edx
jne    1370 <combos+0x270>
mov    %edi,%r8d
sub    %esi,%r8d
jle    13eb <combos+0x2eb>
not    %esi
add    %edi,%esi
mov    %r8d,%ecx
and    $0x3,%ecx
cmp    $0x3,%esi
jae    13a0 <combos+0x2a0>
mov    $0x1,%esi
jmp    13cd <combos+0x2cd>
and    $0xfffffffc,%r8d
mov    $0x1,%esi
nopl   0x0(%rax)
cltd
idiv   %esi
lea    0x1(%rsi),%edi
cltd
idiv   %edi
lea    0x2(%rsi),%edi
cltd
idiv   %edi
lea    0x3(%rsi),%edi
cltd
idiv   %edi
add    $0x4,%esi
cmp    %r8d,%edi
jne    13b0 <combos+0x2b0>
test   %ecx,%ecx
je     13eb <combos+0x2eb>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
cltd
idiv   %esi
add    $0x1,%esi
add    $0xffffffff,%ecx
jne    13e0 <combos+0x2e0>
ret

LLVM IR (-O0):
define i32 @combos(i32 %0, i32 %1) {
%3 = alloca i32
%4 = alloca i32
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
store i32 %0, i32* %3
store i32 %1, i32* %4
store i32 1, i32* %5
%8 = load i32, i32* %4
%9 = add nsw i32 %8, 1
store i32 %9, i32* %6
br label %10
10: ; preds = %18, %2
%11 = load i32, i32* %6
%12 = load i32, i32* %3
%13 = icmp sle i32 %11, %12
br i1 %13, label %14, label %21
14: ; preds = %10
%15 = load i32, i32* %6
%16 = load i32, i32* %5
%17 = mul nsw i32 %16, %15
store i32 %17, i32* %5
br label %18
18: ; preds = %14
%19 = load i32, i32* %6
%20 = add nsw i32 %19, 1
store i32 %20, i32* %6
br label %10
21: ; preds = %10
store i32 1, i32* %7
br label %22
22: ; preds = %32, %21
%23 = load i32, i32* %7
%24 = load i32, i32* %3
%25 = load i32, i32* %4
%26 = sub nsw i32 %24, %25
%27 = icmp sle i32 %23, %26
br i1 %27, label %28, label %35
28: ; preds = %22
%29 = load i32, i32* %7
%30 = load i32, i32* %5
%31 = sdiv i32 %30, %29
store i32 %31, i32* %5
br label %32
32: ; preds = %28
%33 = load i32, i32* %7
%34 = add nsw i32 %33, 1
store i32 %34, i32* %7
br label %22
35: ; preds = %22
%36 = load i32, i32* %5
ret i32 %36
}

LLVM IR (-O2):
define i32 @combos(i32 %0, i32 %1) {
%3 = icmp sgt i32 %0, %1
br i1 %3, label %4, label %72
4: ; preds = %2
%5 = sub i32 %0, %1
%6 = icmp ult i32 %5, 8
br i1 %6, label %69, label %7
7: ; preds = %4
%8 = and i32 %5, -8
%9 = add i32 %8, %1
%10 = insertelement <4 x i32> poison, i32 %1, i64 0
%11 = shufflevector <4 x i32> %10, <4 x i32> poison, <4 x i32> zeroinitializer
%12 = add <4 x i32> %11, <i32 0, i32 1, i32 2, i32 3>
%13 = add i32 %8, -8
%14 = lshr exact i32 %13, 3
%15 = add nuw nsw i32 %14, 1
%16 = and i32 %15, 3
%17 = icmp ult i32 %13, 24
br i1 %17, label %44, label %18
18: ; preds = %7
%19 = and i32 %15, 1073741820
br label %20
20: ; preds = %20, %18
%21 = phi <4 x i32> [ %12, %18 ], [ %41, %20 ]
%22 = phi <4 x i32> [ <i32 1, i32 1, i32 1, i32 1>, %18 ], [ %39, %20 ]
%23 = phi <4 x i32> [ <i32 1, i32 1, i32 1, i32 1>, %18 ], [ %40, %20 ]
%24 = phi i32 [ 0, %18 ], [ %42, %20 ]
%25 = add nsw <4 x i32> %21, <i32 1, i32 1, i32 1, i32 1>
%26 = add <4 x i32> %21, <i32 5, i32 5, i32 5, i32 5>
%27 = mul <4 x i32> %25, %22
%28 = mul <4 x i32> %26, %23
%29 = add <4 x i32> %21, <i32 9, i32 9, i32 9, i32 9>
%30 = add <4 x i32> %21, <i32 13, i32 13, i32 13, i32 13>
%31 = mul <4 x i32> %29, %27
%32 = mul <4 x i32> %30, %28
%33 = add <4 x i32> %21, <i32 17, i32 17, i32 17, i32 17>
%34 = add <4 x i32> %21, <i32 21, i32 21, i32 21, i32 21>
%35 = mul <4 x i32> %33, %31
%36 = mul <4 x i32> %34, %32
%37 = add <4 x i32> %21, <i32 25, i32 25, i32 25, i32 25>
%38 = add <4 x i32> %21, <i32 29, i32 29, i32 29, i32 29>
%39 = mul <4 x i32> %37, %35
%40 = mul <4 x i32> %38, %36
%41 = add <4 x i32> %21, <i32 32, i32 32, i32 32, i32 32>
%42 = add i32 %24, 4
%43 = icmp eq i32 %42, %19
br i1 %43, label %44, label %20
44: ; preds = %20, %7
%45 = phi <4 x i32> [ undef, %7 ], [ %39, %20 ]
%46 = phi <4 x i32> [ undef, %7 ], [ %40, %20 ]
%47 = phi <4 x i32> [ %12, %7 ], [ %41, %20 ]
%48 = phi <4 x i32> [ <i32 1, i32 1, i32 1, i32 1>, %7 ], [ %39, %20 ]
%49 = phi <4 x i32> [ <i32 1, i32 1, i32 1, i32 1>, %7 ], [ %40, %20 ]
%50 = icmp eq i32 %16, 0
br i1 %50, label %63, label %51
51: ; preds = %44, %51
%52 = phi <4 x i32> [ %60, %51 ], [ %47, %44 ]
%53 = phi <4 x i32> [ %58, %51 ], [ %48, %44 ]
%54 = phi <4 x i32> [ %59, %51 ], [ %49, %44 ]
%55 = phi i32 [ %61, %51 ], [ 0, %44 ]
%56 = add nsw <4 x i32> %52, <i32 1, i32 1, i32 1, i32 1>
%57 = add <4 x i32> %52, <i32 5, i32 5, i32 5, i32 5>
%58 = mul <4 x i32> %56, %53
%59 = mul <4 x i32> %57, %54
%60 = add <4 x i32> %52, <i32 8, i32 8, i32 8, i32 8>
%61 = add i32 %55, 1
%62 = icmp eq i32 %61, %16
br i1 %62, label %63, label %51
63: ; preds = %51, %44
%64 = phi <4 x i32> [ %45, %44 ], [ %58, %51 ]
%65 = phi <4 x i32> [ %46, %44 ], [ %59, %51 ]
%66 = mul <4 x i32> %65, %64
%67 = call i32 @llvm.vector.reduce.mul.v4i32(<4 x i32> %66)
%68 = icmp eq i32 %5, %8
br i1 %68, label %72, label %69
69: ; preds = %4, %63
%70 = phi i32 [ %1, %4 ], [ %9, %63 ]
%71 = phi i32 [ 1, %4 ], [ %67, %63 ]
br label %83
72: ; preds = %83, %63, %2
%73 = phi i32 [ 1, %2 ], [ %67, %63 ], [ %87, %83 ]
%74 = icmp sgt i32 %0, %1
br i1 %74, label %75, label %102
75: ; preds = %72
%76 = sub i32 %0, %1
%77 = xor i32 %1, -1
%78 = add i32 %77, %0
%79 = and i32 %76, 3
%80 = icmp ult i32 %78, 3
br i1 %80, label %89, label %81
81: ; preds = %75
%82 = and i32 %76, -4
br label %104
83: ; preds = %69, %83
%84 = phi i32 [ %86, %83 ], [ %70, %69 ]
%85 = phi i32 [ %87, %83 ], [ %71, %69 ]
%86 = add nsw i32 %84, 1
%87 = mul nsw i32 %86, %85
%88 = icmp eq i32 %86, %0
br i1 %88, label %72, label %83
89: ; preds = %104, %75
%90 = phi i32 [ undef, %75 ], [ %114, %104 ]
%91 = phi i32 [ 1, %75 ], [ %115, %104 ]
%92 = phi i32 [ %73, %75 ], [ %114, %104 ]
%93 = icmp eq i32 %79, 0
br i1 %93, label %102, label %94
94: ; preds = %89, %94
%95 = phi i32 [ %99, %94 ], [ %91, %89 ]
%96 = phi i32 [ %98, %94 ], [ %92, %89 ]
%97 = phi i32 [ %100, %94 ], [ 0, %89 ]
%98 = sdiv i32 %96, %95
%99 = add nuw i32 %95, 1
%100 = add i32 %97, 1
%101 = icmp eq i32 %100, %79
br i1 %101, label %102, label %94
102: ; preds = %89, %94, %72
%103 = phi i32 [ %73, %72 ], [ %90, %89 ], [ %98, %94 ]
ret i32 %103
104: ; preds = %104, %81
%105 = phi i32 [ 1, %81 ], [ %115, %104 ]
%106 = phi i32 [ %73, %81 ], [ %114, %104 ]
%107 = phi i32 [ 0, %81 ], [ %116, %104 ]
%108 = sdiv i32 %106, %105
%109 = add nuw nsw i32 %105, 1
%110 = sdiv i32 %108, %109
%111 = add nuw nsw i32 %105, 2
%112 = sdiv i32 %110, %111
%113 = add nuw i32 %105, 3
%114 = sdiv i32 %112, %113
%115 = add nuw i32 %105, 4
%116 = add i32 %107, 4
%117 = icmp eq i32 %116, %82
br i1 %117, label %89, label %104
}