void unpredict(short *buf, int n) {
  short *p;
  n--;
  p = buf;
  while (n--)
    *++buf += *p++;
}


x86 assembly (clang, -O0):
<unpredict>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    -0xc(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0xc(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x18(%rbp)
mov    -0xc(%rbp),%eax
mov    %eax,%ecx
add    $0xffffffff,%ecx
mov    %ecx,-0xc(%rbp)
cmp    $0x0,%eax
je     1160 <unpredict+0x60>
mov    -0x18(%rbp),%rax
mov    %rax,%rcx
add    $0x2,%rcx
mov    %rcx,-0x18(%rbp)
movswl (%rax),%edx
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x2,%rcx
mov    %rcx,-0x8(%rbp)
movswl 0x2(%rax),%ecx
add    %edx,%ecx
mov    %cx,0x2(%rax)
jmp    111c <unpredict+0x1c>
pop    %rbp
ret

x86 assembly (clang, -O2):
<unpredict>:
mov    %esi,%ecx
add    $0xffffffff,%ecx
je     1170 <unpredict+0x70>
movzwl (%rdi),%eax
lea    -0x2(%rsi),%r8d
test   $0x3,%cl
je     1136 <unpredict+0x36>
add    $0xff,%sil
movzbl %sil,%esi
and    $0x3,%esi
xor    %edx,%edx
add    0x2(%rdi),%ax
mov    %ax,0x2(%rdi)
add    $0x2,%rdi
add    $0x1,%rdx
cmp    %edx,%esi
jne    1120 <unpredict+0x20>
sub    %edx,%ecx
cmp    $0x3,%r8d
jb     1170 <unpredict+0x70>
mov    %ecx,%ecx
xor    %edx,%edx
add    0x2(%rdi,%rdx,2),%ax
mov    %ax,0x2(%rdi,%rdx,2)
add    0x4(%rdi,%rdx,2),%ax
mov    %ax,0x4(%rdi,%rdx,2)
add    0x6(%rdi,%rdx,2),%ax
mov    %ax,0x6(%rdi,%rdx,2)
add    0x8(%rdi,%rdx,2),%ax
mov    %ax,0x8(%rdi,%rdx,2)
add    $0x4,%rdx
cmp    %edx,%ecx
jne    1140 <unpredict+0x40>
ret

LLVM IR (-O0):
define void @unpredict(i16* %0, i32 %1) {
%3 = alloca i16*
%4 = alloca i32
%5 = alloca i16*
store i16* %0, i16** %3
store i32 %1, i32* %4
%6 = load i32, i32* %4
%7 = add nsw i32 %6, -1
store i32 %7, i32* %4
%8 = load i16*, i16** %3
store i16* %8, i16** %5
br label %9
9: ; preds = %13, %2
%10 = load i32, i32* %4
%11 = add nsw i32 %10, -1
store i32 %11, i32* %4
%12 = icmp ne i32 %10, 0
br i1 %12, label %13, label %24
13: ; preds = %9
%14 = load i16*, i16** %5
%15 = getelementptr inbounds i16, i16* %14, i32 1
store i16* %15, i16** %5
%16 = load i16, i16* %14
%17 = sext i16 %16 to i32
%18 = load i16*, i16** %3
%19 = getelementptr inbounds i16, i16* %18, i32 1
store i16* %19, i16** %3
%20 = load i16, i16* %19
%21 = sext i16 %20 to i32
%22 = add nsw i32 %21, %17
%23 = trunc i32 %22 to i16
store i16 %23, i16* %19
br label %9
24: ; preds = %9
ret void
}

LLVM IR (-O2):
define void @unpredict(i16* nocapture %0, i32 %1) {
%3 = add i32 %1, -1
%4 = icmp eq i32 %3, 0
br i1 %4, label %44, label %5
5: ; preds = %2
%6 = load i16, i16* %0
%7 = add i32 %1, -2
%8 = and i32 %3, 3
%9 = icmp eq i32 %8, 0
br i1 %9, label %21, label %10
10: ; preds = %5, %10
%11 = phi i16 [ %17, %10 ], [ %6, %5 ]
%12 = phi i32 [ %18, %10 ], [ %3, %5 ]
%13 = phi i16* [ %15, %10 ], [ %0, %5 ]
%14 = phi i32 [ %19, %10 ], [ 0, %5 ]
%15 = getelementptr inbounds i16, i16* %13, i64 1
%16 = load i16, i16* %15
%17 = add i16 %16, %11
store i16 %17, i16* %15
%18 = add nsw i32 %12, -1
%19 = add i32 %14, 1
%20 = icmp eq i32 %19, %8
br i1 %20, label %21, label %10
21: ; preds = %10, %5
%22 = phi i16 [ %6, %5 ], [ %17, %10 ]
%23 = phi i32 [ %3, %5 ], [ %18, %10 ]
%24 = phi i16* [ %0, %5 ], [ %15, %10 ]
%25 = icmp ult i32 %7, 3
br i1 %25, label %44, label %26
26: ; preds = %21, %26
%27 = phi i16 [ %41, %26 ], [ %22, %21 ]
%28 = phi i32 [ %42, %26 ], [ %23, %21 ]
%29 = phi i16* [ %39, %26 ], [ %24, %21 ]
%30 = getelementptr inbounds i16, i16* %29, i64 1
%31 = load i16, i16* %30
%32 = add i16 %31, %27
store i16 %32, i16* %30
%33 = getelementptr inbounds i16, i16* %29, i64 2
%34 = load i16, i16* %33
%35 = add i16 %34, %32
store i16 %35, i16* %33
%36 = getelementptr inbounds i16, i16* %29, i64 3
%37 = load i16, i16* %36
%38 = add i16 %37, %35
store i16 %38, i16* %36
%39 = getelementptr inbounds i16, i16* %29, i64 4
%40 = load i16, i16* %39
%41 = add i16 %40, %38
store i16 %41, i16* %39
%42 = add nsw i32 %28, -4
%43 = icmp eq i32 %42, 0
br i1 %43, label %44, label %26
44: ; preds = %21, %26, %2
ret void
}