unsigned long combination(int m, int n) {
  int i;
  unsigned long temp;
  temp = 1;
  for (i = 1; i <= n; i++) {
    temp *= m;
    m--;
  }
  for (i = 1; i <= n; i++)
    temp /= i;
  return temp;
}


x86 assembly (clang, -O0):
<combination>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
movq   $0x1,-0x18(%rbp)
movl   $0x1,-0xc(%rbp)
mov    -0xc(%rbp),%eax
cmp    -0x8(%rbp),%eax
jg     1149 <combination+0x49>
movslq -0x4(%rbp),%rax
imul   -0x18(%rbp),%rax
mov    %rax,-0x18(%rbp)
mov    -0x4(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x4(%rbp)
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    1119 <combination+0x19>
movl   $0x1,-0xc(%rbp)
mov    -0xc(%rbp),%eax
cmp    -0x8(%rbp),%eax
jg     117b <combination+0x7b>
movslq -0xc(%rbp),%rcx
mov    -0x18(%rbp),%rax
xor    %edx,%edx
div    %rcx
mov    %rax,-0x18(%rbp)
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    1150 <combination+0x50>
mov    -0x18(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<combination>:
test   %esi,%esi
jle    1129 <combination+0x29>
movslq %edi,%rcx
lea    -0x1(%rsi),%eax
mov    %esi,%r9d
and    $0x7,%r9d
cmp    $0x7,%eax
jae    112f <combination+0x2f>
mov    $0x1,%eax
test   %r9d,%r9d
jne    11b0 <combination+0xb0>
jmp    11be <combination+0xbe>
mov    $0x1,%eax
ret
mov    %esi,%r8d
and    $0xfffffff8,%r8d
neg    %r8d
mov    $0x1,%eax
xor    %edi,%edi
lea    (%rcx,%rdi,1),%rdx
imul   %rax,%rdx
lea    (%rcx,%rdi,1),%r10
add    $0xffffffffffffffff,%r10
lea    (%rcx,%rdi,1),%rax
add    $0xfffffffffffffffe,%rax
imul   %r10,%rax
imul   %rdx,%rax
lea    (%rcx,%rdi,1),%r10
add    $0xfffffffffffffffd,%r10
lea    (%rcx,%rdi,1),%r11
add    $0xfffffffffffffffc,%r11
imul   %r10,%r11
lea    (%rcx,%rdi,1),%rdx
add    $0xfffffffffffffffb,%rdx
imul   %r11,%rdx
imul   %rax,%rdx
lea    (%rcx,%rdi,1),%r10
add    $0xfffffffffffffffa,%r10
lea    (%rcx,%rdi,1),%rax
add    $0xfffffffffffffff9,%rax
imul   %r10,%rax
imul   %rdx,%rax
add    $0xfffffffffffffff8,%rdi
cmp    %edi,%r8d
jne    1140 <combination+0x40>
add    %rdi,%rcx
test   %r9d,%r9d
je     11be <combination+0xbe>
nopl   (%rax)
imul   %rcx,%rax
add    $0xffffffffffffffff,%rcx
add    $0xffffffff,%r9d
jne    11b0 <combination+0xb0>
test   %esi,%esi
jle    129a <combination+0x19a>
mov    %esi,%r8d
lea    -0x1(%r8),%rdx
mov    %r8d,%ecx
and    $0x3,%ecx
cmp    $0x3,%rdx
jae    11ec <combination+0xec>
mov    $0x1,%esi
test   %rcx,%rcx
jne    12af <combination+0x1af>
jmp    129a <combination+0x19a>
and    $0xfffffffc,%r8d
neg    %r8
mov    $0x2,%esi
jmp    1217 <combination+0x117>
nopw   0x0(%rax,%rax,1)
xor    %edx,%edx
div    %rdi
lea    (%r8,%rsi,1),%rdx
add    $0x4,%rdx
add    $0x4,%rsi
cmp    $0x2,%rdx
je     1291 <combination+0x191>
lea    -0x1(%rsi),%rdi
mov    %rax,%rdx
or     %rdi,%rdx
shr    $0x20,%rdx
je     1230 <combination+0x130>
xor    %edx,%edx
div    %rdi
jmp    1234 <combination+0x134>
xchg   %ax,%ax
xor    %edx,%edx
div    %edi
mov    %rax,%rdx
or     %rsi,%rdx
shr    $0x20,%rdx
je     1250 <combination+0x150>
xor    %edx,%edx
div    %rsi
jmp    1254 <combination+0x154>
nopw   0x0(%rax,%rax,1)
xor    %edx,%edx
div    %esi
lea    0x1(%rsi),%rdi
mov    %rax,%rdx
or     %rdi,%rdx
shr    $0x20,%rdx
je     1270 <combination+0x170>
xor    %edx,%edx
div    %rdi
jmp    1274 <combination+0x174>
nopl   0x0(%rax,%rax,1)
xor    %edx,%edx
div    %edi
lea    0x2(%rsi),%rdi
mov    %rax,%rdx
or     %rdi,%rdx
shr    $0x20,%rdx
jne    1200 <combination+0x100>
xor    %edx,%edx
div    %edi
jmp    1205 <combination+0x105>
add    $0xffffffffffffffff,%rsi
test   %rcx,%rcx
jne    12af <combination+0x1af>
ret
nopl   0x0(%rax,%rax,1)
xor    %edx,%edx
div    %rsi
add    $0x1,%rsi
add    $0xffffffffffffffff,%rcx
je     129a <combination+0x19a>
mov    %rax,%rdx
or     %rsi,%rdx
shr    $0x20,%rdx
jne    12a0 <combination+0x1a0>
xor    %edx,%edx
div    %esi
jmp    12a5 <combination+0x1a5>

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

LLVM IR (-O2):
define i64 @combination(i32 %0, i32 %1) {
%3 = icmp slt i32 %1, 1
br i1 %3, label %84, label %4
4: ; preds = %2
%5 = sext i32 %0 to i64
%6 = add i32 %1, -1
%7 = and i32 %1, 7
%8 = icmp ult i32 %6, 7
br i1 %8, label %11, label %9
9: ; preds = %4
%10 = and i32 %1, -8
br label %35
11: ; preds = %35, %4
%12 = phi i64 [ undef, %4 ], [ %53, %35 ]
%13 = phi i64 [ %5, %4 ], [ %54, %35 ]
%14 = phi i64 [ 1, %4 ], [ %53, %35 ]
%15 = icmp eq i32 %7, 0
br i1 %15, label %24, label %16
16: ; preds = %11, %16
%17 = phi i64 [ %21, %16 ], [ %13, %11 ]
%18 = phi i64 [ %20, %16 ], [ %14, %11 ]
%19 = phi i32 [ %22, %16 ], [ 0, %11 ]
%20 = mul i64 %18, %17
%21 = add nsw i64 %17, -1
%22 = add i32 %19, 1
%23 = icmp eq i32 %22, %7
br i1 %23, label %24, label %16
24: ; preds = %16, %11
%25 = phi i64 [ %12, %11 ], [ %20, %16 ]
br i1 %3, label %84, label %26
26: ; preds = %24
%27 = add nuw i32 %1, 1
%28 = zext i32 %27 to i64
%29 = add nsw i64 %28, -1
%30 = add nsw i64 %28, -2
%31 = and i64 %29, 3
%32 = icmp ult i64 %30, 3
br i1 %32, label %71, label %33
33: ; preds = %26
%34 = and i64 %29, -4
br label %57
35: ; preds = %35, %9
%36 = phi i64 [ %5, %9 ], [ %54, %35 ]
%37 = phi i64 [ 1, %9 ], [ %53, %35 ]
%38 = phi i32 [ 0, %9 ], [ %55, %35 ]
%39 = mul i64 %37, %36
%40 = add nsw i64 %36, -1
%41 = mul i64 %39, %40
%42 = add nsw i64 %36, -2
%43 = mul i64 %41, %42
%44 = add nsw i64 %36, -3
%45 = mul i64 %43, %44
%46 = add nsw i64 %36, -4
%47 = mul i64 %45, %46
%48 = add nsw i64 %36, -5
%49 = mul i64 %47, %48
%50 = add nsw i64 %36, -6
%51 = mul i64 %49, %50
%52 = add nsw i64 %36, -7
%53 = mul i64 %51, %52
%54 = add nsw i64 %36, -8
%55 = add i32 %38, 8
%56 = icmp eq i32 %55, %10
br i1 %56, label %11, label %35
57: ; preds = %57, %33
%58 = phi i64 [ 1, %33 ], [ %68, %57 ]
%59 = phi i64 [ %25, %33 ], [ %67, %57 ]
%60 = phi i64 [ 0, %33 ], [ %69, %57 ]
%61 = udiv i64 %59, %58
%62 = add nuw nsw i64 %58, 1
%63 = udiv i64 %61, %62
%64 = add nuw nsw i64 %58, 2
%65 = udiv i64 %63, %64
%66 = add nuw nsw i64 %58, 3
%67 = udiv i64 %65, %66
%68 = add nuw nsw i64 %58, 4
%69 = add i64 %60, 4
%70 = icmp eq i64 %69, %34
br i1 %70, label %71, label %57
71: ; preds = %57, %26
%72 = phi i64 [ undef, %26 ], [ %67, %57 ]
%73 = phi i64 [ 1, %26 ], [ %68, %57 ]
%74 = phi i64 [ %25, %26 ], [ %67, %57 ]
%75 = icmp eq i64 %31, 0
br i1 %75, label %84, label %76
76: ; preds = %71, %76
%77 = phi i64 [ %81, %76 ], [ %73, %71 ]
%78 = phi i64 [ %80, %76 ], [ %74, %71 ]
%79 = phi i64 [ %82, %76 ], [ 0, %71 ]
%80 = udiv i64 %78, %77
%81 = add nuw nsw i64 %77, 1
%82 = add i64 %79, 1
%83 = icmp eq i64 %82, %31
br i1 %83, label %84, label %76
84: ; preds = %71, %76, %2, %24
%85 = phi i64 [ %25, %24 ], [ 1, %2 ], [ %72, %71 ], [ %80, %76 ]
ret i64 %85
}