short sum(short *nums, short index) {
  return index != 0 ? *(nums + index) + sum(nums, index - 1) : nums[0];
}


x86 assembly (clang, -O0):
<sum>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %si,%ax
mov    %rdi,-0x8(%rbp)
mov    %ax,-0xa(%rbp)
movswl -0xa(%rbp),%eax
cmp    $0x0,%eax
je     1168 <sum+0x58>
mov    -0x8(%rbp),%rax
movswl -0xa(%rbp),%ecx
movslq %ecx,%rcx
movswl (%rax,%rcx,2),%eax
mov    %eax,-0x14(%rbp)
mov    -0x8(%rbp),%rdi
movswl -0xa(%rbp),%eax
sub    $0x1,%eax
movswl %ax,%esi
call   1030 <sum@plt>
mov    %ax,%cx
mov    -0x14(%rbp),%eax
movswl %cx,%ecx
add    %ecx,%eax
mov    %eax,-0x10(%rbp)
jmp    1172 <sum+0x62>
mov    -0x8(%rbp),%rax
movswl (%rax),%eax
mov    %eax,-0x10(%rbp)
mov    -0x10(%rbp),%eax
cwtl
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<sum>:
push   %rbx
test   %si,%si
je     1113 <sum+0x13>
cmp    $0x10,%si
jge    111a <sum+0x1a>
xor    %eax,%eax
jmp    1256 <sum+0x156>
xor    %eax,%eax
jmp    12c1 <sum+0x1c1>
lea    -0x1(%rsi),%eax
movzwl %ax,%r9d
add    $0x1,%r9d
mov    %r9d,%r10d
and    $0xfffffff0,%r10d
mov    %esi,%r8d
lea    -0x10(%r10),%eax
mov    %eax,%r11d
shr    $0x4,%r11d
add    $0x1,%r11d
test   %eax,%eax
je     11dc <sum+0xdc>
mov    %r11d,%eax
and    $0xfffffffe,%eax
pxor   %xmm0,%xmm0
xor    %ecx,%ecx
mov    %esi,%edx
pxor   %xmm1,%xmm1
nopl   0x0(%rax,%rax,1)
movswq %dx,%rbx
movdqu -0x1e(%rdi,%rbx,2),%xmm2
movdqu -0xe(%rdi,%rbx,2),%xmm3
pshufd $0x4e,%xmm3,%xmm3
pshuflw $0x1b,%xmm3,%xmm3
pshufhw $0x1b,%xmm3,%xmm3
paddw  %xmm0,%xmm3
pshufd $0x4e,%xmm2,%xmm0
pshuflw $0x1b,%xmm0,%xmm0
pshufhw $0x1b,%xmm0,%xmm2
paddw  %xmm1,%xmm2
lea    -0x10(%rdx),%ebx
movswq %bx,%rbx
movdqu -0x1e(%rdi,%rbx,2),%xmm1
movdqu -0xe(%rdi,%rbx,2),%xmm0
pshufd $0x4e,%xmm0,%xmm0
pshuflw $0x1b,%xmm0,%xmm0
pshufhw $0x1b,%xmm0,%xmm0
paddw  %xmm3,%xmm0
pshufd $0x4e,%xmm1,%xmm1
pshuflw $0x1b,%xmm1,%xmm1
pshufhw $0x1b,%xmm1,%xmm1
paddw  %xmm2,%xmm1
add    $0xffffffe0,%edx
add    $0x20,%ecx
add    $0xfffffffe,%eax
jne    1160 <sum+0x60>
jmp    11e6 <sum+0xe6>
pxor   %xmm0,%xmm0
xor    %ecx,%ecx
pxor   %xmm1,%xmm1
sub    %r10d,%r8d
test   $0x1,%r11b
je     1227 <sum+0x127>
sub    %ecx,%esi
movswq %si,%rax
movdqu -0x1e(%rdi,%rax,2),%xmm2
movdqu -0xe(%rdi,%rax,2),%xmm3
pshufd $0x4e,%xmm3,%xmm3
pshuflw $0x1b,%xmm3,%xmm3
pshufhw $0x1b,%xmm3,%xmm3
paddw  %xmm3,%xmm0
pshufd $0x4e,%xmm2,%xmm2
pshuflw $0x1b,%xmm2,%xmm2
pshufhw $0x1b,%xmm2,%xmm2
paddw  %xmm2,%xmm1
paddw  %xmm1,%xmm0
pshufd $0xee,%xmm0,%xmm1
paddw  %xmm0,%xmm1
pshufd $0x55,%xmm1,%xmm0
paddw  %xmm1,%xmm0
movdqa %xmm0,%xmm1
psrld  $0x10,%xmm1
paddw  %xmm0,%xmm1
movd   %xmm1,%eax
mov    %r8d,%esi
cmp    %r10d,%r9d
je     12c1 <sum+0x1c1>
lea    -0x1(%rsi),%ecx
mov    %esi,%edx
and    $0x3,%dx
je     1281 <sum+0x181>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movswq %si,%rbx
add    $0xffffffff,%esi
add    (%rdi,%rbx,2),%ax
add    $0xffff,%dx
jne    1270 <sum+0x170>
cmp    $0x3,%cx
jb     12c1 <sum+0x1c1>
nopw   0x0(%rax,%rax,1)
lea    -0x1(%rsi),%ecx
movswq %si,%rdx
add    (%rdi,%rdx,2),%ax
lea    -0x2(%rsi),%ebx
movswq %cx,%rcx
add    (%rdi,%rcx,2),%ax
lea    -0x3(%rsi),%ecx
movswq %bx,%rsi
add    (%rdi,%rsi,2),%ax
movswq %cx,%rcx
add    (%rdi,%rcx,2),%ax
add    $0xfffc,%dx
mov    %edx,%esi
jne    1290 <sum+0x190>
add    (%rdi),%ax
pop    %rbx
ret

LLVM IR (-O0):
define signext i16 @sum(i16* %0, i16 signext %1) {
%3 = alloca i16*
%4 = alloca i16
store i16* %0, i16** %3
store i16 %1, i16* %4
%5 = load i16, i16* %4
%6 = sext i16 %5 to i32
%7 = icmp ne i32 %6, 0
br i1 %7, label %8, label %24
8: ; preds = %2
%9 = load i16*, i16** %3
%10 = load i16, i16* %4
%11 = sext i16 %10 to i32
%12 = sext i32 %11 to i64
%13 = getelementptr inbounds i16, i16* %9, i64 %12
%14 = load i16, i16* %13
%15 = sext i16 %14 to i32
%16 = load i16*, i16** %3
%17 = load i16, i16* %4
%18 = sext i16 %17 to i32
%19 = sub nsw i32 %18, 1
%20 = trunc i32 %19 to i16
%21 = call signext i16 @sum(i16* %16, i16 signext %20)
%22 = sext i16 %21 to i32
%23 = add nsw i32 %15, %22
br label %29
24: ; preds = %2
%25 = load i16*, i16** %3
%26 = getelementptr inbounds i16, i16* %25, i64 0
%27 = load i16, i16* %26
%28 = sext i16 %27 to i32
br label %29
29: ; preds = %24, %8
%30 = phi i32 [ %23, %8 ], [ %28, %24 ]
%31 = trunc i32 %30 to i16
ret i16 %31
}

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