double pocet(int n) {
  int i, j;
  double stromy[n + 1];
  stromy[0] = stromy[1] = 1;
  for (i = 2; i <= n; i++) {
    stromy[i] = 0;
    for (j = 0; j < i; j++)
      stromy[i] += stromy[j] * stromy[i - j - 1];
  }
  return stromy[n];
}


x86 assembly (clang, -O0):
<pocet>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %edi,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x1,%eax
mov    %eax,%ecx
mov    %rsp,%rax
mov    %rax,-0x18(%rbp)
lea    0xf(,%rcx,8),%rdx
and    $0xfffffffffffffff0,%rdx
mov    %rsp,%rax
sub    %rdx,%rax
mov    %rax,-0x28(%rbp)
mov    %rax,%rsp
mov    %rcx,-0x20(%rbp)
movsd  0xec1(%rip),%xmm0
movsd  %xmm0,0x8(%rax)
movsd  0xeb4(%rip),%xmm0
movsd  %xmm0,(%rax)
movl   $0x2,-0x8(%rbp)
mov    -0x8(%rbp),%eax
cmp    -0x4(%rbp),%eax
jg     11db <pocet+0xdb>
mov    -0x28(%rbp),%rax
movslq -0x8(%rbp),%rcx
xorps  %xmm0,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
movl   $0x0,-0xc(%rbp)
mov    -0xc(%rbp),%eax
cmp    -0x8(%rbp),%eax
jge    11c8 <pocet+0xc8>
mov    -0x28(%rbp),%rax
movslq -0xc(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x8(%rbp),%ecx
sub    -0xc(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm2
movslq -0x8(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    117a <pocet+0x7a>
jmp    11cd <pocet+0xcd>
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    1157 <pocet+0x57>
mov    -0x28(%rbp),%rax
movslq -0x4(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x18(%rbp),%rax
mov    %rax,%rsp
mov    %rbp,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<pocet>:
push   %rbp
mov    %rsp,%rbp
push   %rbx
push   %rax
lea    0x1(%rdi),%r9d
mov    %rsp,%rax
lea    0xf(,%r9,8),%rcx
and    $0xfffffffffffffff0,%rcx
mov    %rax,%r11
sub    %rcx,%r11
mov    %r11,%rsp
neg    %rcx
movapd 0xed3(%rip),%xmm0
movapd %xmm0,(%rax,%rcx,1)
cmp    $0x2,%edi
jge    1147 <pocet+0x47>
movslq %edi,%rax
movsd  (%r11,%rax,8),%xmm0
lea    -0x8(%rbp),%rsp
pop    %rbx
pop    %rbp
ret
lea    0x8(%r11),%r8
mov    $0x2,%esi
xor    %r10d,%r10d
mov    %r8,%rax
jmp    116d <pocet+0x6d>
nopl   0x0(%rax,%rax,1)
add    $0x1,%rsi
add    $0x8,%rax
cmp    %r9,%rsi
je     1137 <pocet+0x37>
movq   $0x0,(%r11,%rsi,8)
inc    %r10
jne    1190 <pocet+0x90>
xorpd  %xmm0,%xmm0
xor    %edx,%edx
test   $0x1,%sil
je     1160 <pocet+0x60>
jmp    11f2 <pocet+0xf2>
nopl   0x0(%rax,%rax,1)
mov    %rsi,%rcx
and    $0xfffffffffffffffe,%rcx
neg    %rcx
xorpd  %xmm0,%xmm0
xor    %edx,%edx
mov    %r8,%rbx
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movsd  -0x8(%rbx),%xmm1
mulsd  (%rax,%rdx,8),%xmm1
addsd  %xmm0,%xmm1
movsd  %xmm1,(%r11,%rsi,8)
movsd  (%rbx),%xmm0
mulsd  -0x8(%rax,%rdx,8),%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,(%r11,%rsi,8)
add    $0x10,%rbx
add    $0xfffffffffffffffe,%rdx
cmp    %rdx,%rcx
jne    11b0 <pocet+0xb0>
neg    %rdx
test   $0x1,%sil
je     1160 <pocet+0x60>
movsd  (%r11,%rdx,8),%xmm1
not    %rdx
add    %rsi,%rdx
mulsd  (%r11,%rdx,8),%xmm1
addsd  %xmm0,%xmm1
movsd  %xmm1,(%r11,%rsi,8)
jmp    1160 <pocet+0x60>

LLVM IR (-O0):
define double @pocet(i32 %0) {
%2 = alloca i32
%3 = alloca i32
%4 = alloca i32
%5 = alloca i8*
%6 = alloca i64
store i32 %0, i32* %2
%7 = load i32, i32* %2
%8 = add nsw i32 %7, 1
%9 = zext i32 %8 to i64
%10 = call i8* @llvm.stacksave()
store i8* %10, i8** %5
%11 = alloca double, i64 %9
store i64 %9, i64* %6
%12 = getelementptr inbounds double, double* %11, i64 1
store double 1.000000e+00, double* %12
%13 = getelementptr inbounds double, double* %11, i64 0
store double 1.000000e+00, double* %13
store i32 2, i32* %3
br label %14
14: ; preds = %47, %1
%15 = load i32, i32* %3
%16 = load i32, i32* %2
%17 = icmp sle i32 %15, %16
br i1 %17, label %18, label %50
18: ; preds = %14
%19 = load i32, i32* %3
%20 = sext i32 %19 to i64
%21 = getelementptr inbounds double, double* %11, i64 %20
store double 0.000000e+00, double* %21
store i32 0, i32* %4
br label %22
22: ; preds = %43, %18
%23 = load i32, i32* %4
%24 = load i32, i32* %3
%25 = icmp slt i32 %23, %24
br i1 %25, label %26, label %46
26: ; preds = %22
%27 = load i32, i32* %4
%28 = sext i32 %27 to i64
%29 = getelementptr inbounds double, double* %11, i64 %28
%30 = load double, double* %29
%31 = load i32, i32* %3
%32 = load i32, i32* %4
%33 = sub nsw i32 %31, %32
%34 = sub nsw i32 %33, 1
%35 = sext i32 %34 to i64
%36 = getelementptr inbounds double, double* %11, i64 %35
%37 = load double, double* %36
%38 = load i32, i32* %3
%39 = sext i32 %38 to i64
%40 = getelementptr inbounds double, double* %11, i64 %39
%41 = load double, double* %40
%42 = call double @llvm.fmuladd.f64(double %30, double %37, double %41)
store double %42, double* %40
br label %43
43: ; preds = %26
%44 = load i32, i32* %4
%45 = add nsw i32 %44, 1
store i32 %45, i32* %4
br label %22
46: ; preds = %22
br label %47
47: ; preds = %46
%48 = load i32, i32* %3
%49 = add nsw i32 %48, 1
store i32 %49, i32* %3
br label %14
50: ; preds = %14
%51 = load i32, i32* %2
%52 = sext i32 %51 to i64
%53 = getelementptr inbounds double, double* %11, i64 %52
%54 = load double, double* %53
%55 = load i8*, i8** %5
ret double %54
}

LLVM IR (-O2):
define double @pocet(i32 %0) {
%2 = add i32 %0, 1
%3 = zext i32 %2 to i64
%4 = alloca double, i64 %3
%5 = bitcast double* %4 to <2 x double>*
store <2 x double> <double 1.000000e+00, double 1.000000e+00>, <2 x double>* %5
%6 = icmp slt i32 %0, 2
br i1 %6, label %53, label %7
7: ; preds = %1, %49
%8 = phi i64 [ %52, %49 ], [ 0, %1 ]
%9 = phi i64 [ %50, %49 ], [ 2, %1 ]
%10 = getelementptr inbounds double, double* %4, i64 %9
store double 0.000000e+00, double* %10
%11 = and i64 %9, 1
%12 = icmp eq i64 %8, -1
br i1 %12, label %37, label %13
13: ; preds = %7
%14 = and i64 %9, 9223372036854775806
br label %15
15: ; preds = %15, %13
%16 = phi double [ 0.000000e+00, %13 ], [ %33, %15 ]
%17 = phi i64 [ 0, %13 ], [ %34, %15 ]
%18 = phi i64 [ 0, %13 ], [ %35, %15 ]
%19 = getelementptr inbounds double, double* %4, i64 %17
%20 = load double, double* %19
%21 = xor i64 %17, -1
%22 = add nsw i64 %9, %21
%23 = getelementptr inbounds double, double* %4, i64 %22
%24 = load double, double* %23
%25 = tail call double @llvm.fmuladd.f64(double %20, double %24, double %16)
store double %25, double* %10
%26 = or i64 %17, 1
%27 = getelementptr inbounds double, double* %4, i64 %26
%28 = load double, double* %27
%29 = sub nuw nsw i64 -2, %17
%30 = add nsw i64 %9, %29
%31 = getelementptr inbounds double, double* %4, i64 %30
%32 = load double, double* %31
%33 = tail call double @llvm.fmuladd.f64(double %28, double %32, double %25)
store double %33, double* %10
%34 = add nuw nsw i64 %17, 2
%35 = add i64 %18, 2
%36 = icmp eq i64 %35, %14
br i1 %36, label %37, label %15
37: ; preds = %15, %7
%38 = phi double [ 0.000000e+00, %7 ], [ %33, %15 ]
%39 = phi i64 [ 0, %7 ], [ %34, %15 ]
%40 = icmp eq i64 %11, 0
br i1 %40, label %49, label %41
41: ; preds = %37
%42 = getelementptr inbounds double, double* %4, i64 %39
%43 = load double, double* %42
%44 = xor i64 %39, -1
%45 = add nsw i64 %9, %44
%46 = getelementptr inbounds double, double* %4, i64 %45
%47 = load double, double* %46
%48 = tail call double @llvm.fmuladd.f64(double %43, double %47, double %38)
store double %48, double* %10
br label %49
49: ; preds = %37, %41
%50 = add nuw nsw i64 %9, 1
%51 = icmp eq i64 %50, %3
%52 = add i64 %8, 1
br i1 %51, label %53, label %7
53: ; preds = %49, %1
%54 = sext i32 %0 to i64
%55 = getelementptr inbounds double, double* %4, i64 %54
%56 = load double, double* %55
ret double %56
}