int sum(int a[], int i, int n) {
  static int su = 0;
  if (i == n) {
    return (su);
  } else {
    su = su + a[i];
    sum(a, i + 1, n);
  }
}


x86 assembly (clang, -O0):
<sum>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    %edx,-0x18(%rbp)
mov    -0x14(%rbp),%eax
cmp    -0x18(%rbp),%eax
jne    113c <sum+0x2c>
mov    0x2ef8(%rip),%eax
mov    %eax,-0x4(%rbp)
jmp    1165 <sum+0x55>
mov    0x2eea(%rip),%eax
mov    -0x10(%rbp),%rcx
movslq -0x14(%rbp),%rdx
add    (%rcx,%rdx,4),%eax
mov    %eax,0x2ed9(%rip)
mov    -0x10(%rbp),%rdi
mov    -0x14(%rbp),%esi
add    $0x1,%esi
mov    -0x18(%rbp),%edx
call   1030 <sum@plt>
mov    -0x4(%rbp),%eax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<sum>:
push   %rbx
mov    0x2f1d(%rip),%eax
cmp    %edx,%esi
je     1233 <sum+0x133>
movslq %esi,%r10
not    %esi
add    %edx,%esi
cmp    $0x7,%esi
jae    1122 <sum+0x22>
mov    %eax,%ecx
jmp    121e <sum+0x11e>
add    $0x1,%rsi
mov    %rsi,%r8
and    $0xfffffffffffffff8,%r8
movd   %eax,%xmm0
lea    -0x8(%r8),%rcx
mov    %rcx,%r11
shr    $0x3,%r11
add    $0x1,%r11
mov    %r11d,%r9d
and    $0x3,%r9d
cmp    $0x18,%rcx
jae    1155 <sum+0x55>
pxor   %xmm1,%xmm1
xor    %ecx,%ecx
jmp    11c9 <sum+0xc9>
and    $0xfffffffffffffffc,%r11
lea    (%rdi,%r10,4),%rbx
add    $0x70,%rbx
pxor   %xmm1,%xmm1
xor    %ecx,%ecx
nopw   0x0(%rax,%rax,1)
movdqu -0x70(%rbx,%rcx,4),%xmm2
paddd  %xmm0,%xmm2
movdqu -0x60(%rbx,%rcx,4),%xmm0
paddd  %xmm1,%xmm0
movdqu -0x50(%rbx,%rcx,4),%xmm1
movdqu -0x40(%rbx,%rcx,4),%xmm3
movdqu -0x30(%rbx,%rcx,4),%xmm4
paddd  %xmm1,%xmm4
paddd  %xmm2,%xmm4
movdqu -0x20(%rbx,%rcx,4),%xmm2
paddd  %xmm3,%xmm2
paddd  %xmm0,%xmm2
movdqu -0x10(%rbx,%rcx,4),%xmm0
paddd  %xmm4,%xmm0
movdqu (%rbx,%rcx,4),%xmm1
paddd  %xmm2,%xmm1
add    $0x20,%rcx
add    $0xfffffffffffffffc,%r11
jne    1170 <sum+0x70>
test   %r9,%r9
je     11fc <sum+0xfc>
add    %r10,%rcx
lea    (%rdi,%rcx,4),%rcx
add    $0x10,%rcx
shl    $0x5,%r9
xor    %ebx,%ebx
nop
movdqu -0x10(%rcx,%rbx,1),%xmm2
paddd  %xmm2,%xmm0
movdqu (%rcx,%rbx,1),%xmm2
paddd  %xmm2,%xmm1
add    $0x20,%rbx
cmp    %rbx,%r9
jne    11e0 <sum+0xe0>
paddd  %xmm1,%xmm0
pshufd $0xee,%xmm0,%xmm1
paddd  %xmm0,%xmm1
pshufd $0x55,%xmm1,%xmm0
paddd  %xmm1,%xmm0
movd   %xmm0,%ecx
cmp    %r8,%rsi
je     122d <sum+0x12d>
add    %r8,%r10
mov    %edx,%edx
add    (%rdi,%r10,4),%ecx
add    $0x1,%r10
cmp    %r10d,%edx
jne    1220 <sum+0x120>
mov    %ecx,0x2df1(%rip)
pop    %rbx
ret

LLVM IR (-O0):
@sum.su = internal global i32 0
define i32 @sum(i32* %0, i32 %1, i32 %2) {
%4 = alloca i32
%5 = alloca i32*
%6 = alloca i32
%7 = alloca i32
store i32* %0, i32** %5
store i32 %1, i32* %6
store i32 %2, i32* %7
%8 = load i32, i32* %6
%9 = load i32, i32* %7
%10 = icmp eq i32 %8, %9
br i1 %10, label %11, label %13
11: ; preds = %3
%12 = load i32, i32* @sum.su
store i32 %12, i32* %4
br label %26
13: ; preds = %3
%14 = load i32, i32* @sum.su
%15 = load i32*, i32** %5
%16 = load i32, i32* %6
%17 = sext i32 %16 to i64
%18 = getelementptr inbounds i32, i32* %15, i64 %17
%19 = load i32, i32* %18
%20 = add nsw i32 %14, %19
store i32 %20, i32* @sum.su
%21 = load i32*, i32** %5
%22 = load i32, i32* %6
%23 = add nsw i32 %22, 1
%24 = load i32, i32* %7
%25 = call i32 @sum(i32* %21, i32 %23, i32 %24)
br label %26
26: ; preds = %11, %13
%27 = load i32, i32* %4
ret i32 %27
}

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