void update(int *count, int a, int n) {
  int i;
  for (i = a; i < n; i++)
    count[i]--;
}


x86 assembly (clang, -O0):
<update>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    -0xc(%rbp),%eax
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%eax
cmp    -0x10(%rbp),%eax
jge    113f <update+0x3f>
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    (%rax,%rcx,4),%edx
add    $0xffffffff,%edx
mov    %edx,(%rax,%rcx,4)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1114 <update+0x14>
pop    %rbp
ret

x86 assembly (clang, -O2):
<update>:
cmp    %edx,%esi
jge    11ed <update+0xed>
movslq %esi,%rax
movslq %edx,%r11
mov    %r11,%r10
sub    %rax,%r10
cmp    $0x8,%r10
jb     11e0 <update+0xe0>
mov    %r10,%r8
and    $0xfffffffffffffff8,%r8
lea    -0x8(%r8),%rcx
mov    %rcx,%r9
shr    $0x3,%r9
add    $0x1,%r9
test   %rcx,%rcx
je     11ee <update+0xee>
mov    %r9,%rdx
and    $0xfffffffffffffffe,%rdx
lea    (%rdi,%rax,4),%rcx
add    $0x30,%rcx
xor    %esi,%esi
pcmpeqd %xmm0,%xmm0
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movdqu -0x30(%rcx,%rsi,4),%xmm1
movdqu -0x20(%rcx,%rsi,4),%xmm2
movdqu -0x10(%rcx,%rsi,4),%xmm3
movdqu (%rcx,%rsi,4),%xmm4
paddd  %xmm0,%xmm1
paddd  %xmm0,%xmm2
movdqu %xmm1,-0x30(%rcx,%rsi,4)
movdqu %xmm2,-0x20(%rcx,%rsi,4)
paddd  %xmm0,%xmm3
paddd  %xmm0,%xmm4
movdqu %xmm3,-0x10(%rcx,%rsi,4)
movdqu %xmm4,(%rcx,%rsi,4)
add    $0x10,%rsi
add    $0xfffffffffffffffe,%rdx
jne    1160 <update+0x60>
test   $0x1,%r9b
je     11d3 <update+0xd3>
add    %rax,%rsi
movdqu (%rdi,%rsi,4),%xmm0
movdqu 0x10(%rdi,%rsi,4),%xmm1
pcmpeqd %xmm2,%xmm2
paddd  %xmm2,%xmm0
paddd  %xmm2,%xmm1
movdqu %xmm0,(%rdi,%rsi,4)
movdqu %xmm1,0x10(%rdi,%rsi,4)
cmp    %r8,%r10
je     11ed <update+0xed>
add    %r8,%rax
nopl   0x0(%rax,%rax,1)
addl   $0xffffffff,(%rdi,%rax,4)
add    $0x1,%rax
cmp    %rax,%r11
jne    11e0 <update+0xe0>
ret
xor    %esi,%esi
test   $0x1,%r9b
jne    11ae <update+0xae>
jmp    11d3 <update+0xd3>

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

LLVM IR (-O2):
define void @update(i32* nocapture %0, i32 %1, i32 %2) {
%4 = icmp slt i32 %1, %2
br i1 %4, label %5, label %75
5: ; preds = %3
%6 = sext i32 %1 to i64
%7 = sext i32 %2 to i64
%8 = sub nsw i64 %7, %6
%9 = icmp ult i64 %8, 8
br i1 %9, label %66, label %10
10: ; preds = %5
%11 = and i64 %8, -8
%12 = add nsw i64 %11, %6
%13 = add nsw i64 %11, -8
%14 = lshr exact i64 %13, 3
%15 = add nuw nsw i64 %14, 1
%16 = and i64 %15, 1
%17 = icmp eq i64 %13, 0
br i1 %17, label %49, label %18
18: ; preds = %10
%19 = and i64 %15, 4611686018427387902
br label %20
20: ; preds = %20, %18
%21 = phi i64 [ 0, %18 ], [ %46, %20 ]
%22 = phi i64 [ 0, %18 ], [ %47, %20 ]
%23 = add i64 %21, %6
%24 = getelementptr inbounds i32, i32* %0, i64 %23
%25 = bitcast i32* %24 to <4 x i32>*
%26 = load <4 x i32>, <4 x i32>* %25
%27 = getelementptr inbounds i32, i32* %24, i64 4
%28 = bitcast i32* %27 to <4 x i32>*
%29 = load <4 x i32>, <4 x i32>* %28
%30 = add nsw <4 x i32> %26, <i32 -1, i32 -1, i32 -1, i32 -1>
%31 = add nsw <4 x i32> %29, <i32 -1, i32 -1, i32 -1, i32 -1>
%32 = bitcast i32* %24 to <4 x i32>*
store <4 x i32> %30, <4 x i32>* %32
%33 = bitcast i32* %27 to <4 x i32>*
store <4 x i32> %31, <4 x i32>* %33
%34 = or i64 %21, 8
%35 = add i64 %34, %6
%36 = getelementptr inbounds i32, i32* %0, i64 %35
%37 = bitcast i32* %36 to <4 x i32>*
%38 = load <4 x i32>, <4 x i32>* %37
%39 = getelementptr inbounds i32, i32* %36, i64 4
%40 = bitcast i32* %39 to <4 x i32>*
%41 = load <4 x i32>, <4 x i32>* %40
%42 = add nsw <4 x i32> %38, <i32 -1, i32 -1, i32 -1, i32 -1>
%43 = add nsw <4 x i32> %41, <i32 -1, i32 -1, i32 -1, i32 -1>
%44 = bitcast i32* %36 to <4 x i32>*
store <4 x i32> %42, <4 x i32>* %44
%45 = bitcast i32* %39 to <4 x i32>*
store <4 x i32> %43, <4 x i32>* %45
%46 = add nuw i64 %21, 16
%47 = add i64 %22, 2
%48 = icmp eq i64 %47, %19
br i1 %48, label %49, label %20
49: ; preds = %20, %10
%50 = phi i64 [ 0, %10 ], [ %46, %20 ]
%51 = icmp eq i64 %16, 0
br i1 %51, label %64, label %52
52: ; preds = %49
%53 = add i64 %50, %6
%54 = getelementptr inbounds i32, i32* %0, i64 %53
%55 = bitcast i32* %54 to <4 x i32>*
%56 = load <4 x i32>, <4 x i32>* %55
%57 = getelementptr inbounds i32, i32* %54, i64 4
%58 = bitcast i32* %57 to <4 x i32>*
%59 = load <4 x i32>, <4 x i32>* %58
%60 = add nsw <4 x i32> %56, <i32 -1, i32 -1, i32 -1, i32 -1>
%61 = add nsw <4 x i32> %59, <i32 -1, i32 -1, i32 -1, i32 -1>
%62 = bitcast i32* %54 to <4 x i32>*
store <4 x i32> %60, <4 x i32>* %62
%63 = bitcast i32* %57 to <4 x i32>*
store <4 x i32> %61, <4 x i32>* %63
br label %64
64: ; preds = %49, %52
%65 = icmp eq i64 %8, %11
br i1 %65, label %75, label %66
66: ; preds = %5, %64
%67 = phi i64 [ %6, %5 ], [ %12, %64 ]
br label %68
68: ; preds = %66, %68
%69 = phi i64 [ %73, %68 ], [ %67, %66 ]
%70 = getelementptr inbounds i32, i32* %0, i64 %69
%71 = load i32, i32* %70
%72 = add nsw i32 %71, -1
store i32 %72, i32* %70
%73 = add nsw i64 %69, 1
%74 = icmp eq i64 %73, %7
br i1 %74, label %75, label %68
75: ; preds = %68, %64, %3
ret void
}