int ncopy(int *src, int *dst, int len) {
  int count = 0;
  int val;
  while (len > 0) {
    val = *src++;
    *dst++ = val;
    if (val > 0)
      count++;
    len--;
  }
  return count;
}


x86 assembly (clang, -O0):
<ncopy>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
movl   $0x0,-0x18(%rbp)
cmpl   $0x0,-0x14(%rbp)
jle    1169 <ncopy+0x69>
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x4,%rcx
mov    %rcx,-0x8(%rbp)
mov    (%rax),%eax
mov    %eax,-0x1c(%rbp)
mov    -0x1c(%rbp),%ecx
mov    -0x10(%rbp),%rax
mov    %rax,%rdx
add    $0x4,%rdx
mov    %rdx,-0x10(%rbp)
mov    %ecx,(%rax)
cmpl   $0x0,-0x1c(%rbp)
jle    115b <ncopy+0x5b>
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
mov    -0x14(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x14(%rbp)
jmp    1116 <ncopy+0x16>
mov    -0x18(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<ncopy>:
test   %edx,%edx
jle    1252 <ncopy+0x152>
lea    -0x1(%rdx),%r10d
xor    %eax,%eax
cmp    $0x7,%r10d
jb     1222 <ncopy+0x122>
lea    (%rdi,%r10,4),%rcx
add    $0x4,%rcx
cmp    %rsi,%rcx
jbe    1136 <ncopy+0x36>
lea    (%rsi,%r10,4),%rcx
add    $0x4,%rcx
cmp    %rdi,%rcx
ja     1222 <ncopy+0x122>
add    $0x1,%r10
mov    %r10,%r8
and    $0xfffffffffffffff8,%r8
lea    -0x8(%r8),%rax
mov    %rax,%r9
shr    $0x3,%r9
add    $0x1,%r9
test   %rax,%rax
je     1255 <ncopy+0x155>
mov    %r9,%rcx
and    $0xfffffffffffffffe,%rcx
pxor   %xmm2,%xmm2
xor    %eax,%eax
pxor   %xmm0,%xmm0
pxor   %xmm1,%xmm1
xchg   %ax,%ax
movdqu (%rdi,%rax,4),%xmm3
movdqu 0x10(%rdi,%rax,4),%xmm4
movdqu %xmm3,(%rsi,%rax,4)
movdqu %xmm4,0x10(%rsi,%rax,4)
pcmpgtd %xmm2,%xmm3
psubd  %xmm3,%xmm0
pcmpgtd %xmm2,%xmm4
psubd  %xmm4,%xmm1
movdqu 0x20(%rdi,%rax,4),%xmm3
movdqu 0x30(%rdi,%rax,4),%xmm4
movdqu %xmm3,0x20(%rsi,%rax,4)
movdqu %xmm4,0x30(%rsi,%rax,4)
pcmpgtd %xmm2,%xmm3
psubd  %xmm3,%xmm0
pcmpgtd %xmm2,%xmm4
psubd  %xmm4,%xmm1
add    $0x10,%rax
add    $0xfffffffffffffffe,%rcx
jne    1170 <ncopy+0x70>
test   $0x1,%r9b
je     11f8 <ncopy+0xf8>
movdqu (%rdi,%rax,4),%xmm2
movdqu 0x10(%rdi,%rax,4),%xmm3
movdqu %xmm2,(%rsi,%rax,4)
movdqu %xmm3,0x10(%rsi,%rax,4)
pxor   %xmm4,%xmm4
pcmpgtd %xmm4,%xmm2
psubd  %xmm2,%xmm0
pcmpgtd %xmm4,%xmm3
psubd  %xmm3,%xmm1
paddd  %xmm1,%xmm0
pshufd $0xee,%xmm0,%xmm1
paddd  %xmm0,%xmm1
pshufd $0x55,%xmm1,%xmm0
paddd  %xmm1,%xmm0
movd   %xmm0,%eax
cmp    %r8,%r10
je     1251 <ncopy+0x151>
lea    (%rdi,%r8,4),%rdi
sub    %r8d,%edx
lea    (%rsi,%r8,4),%rsi
add    $0x1,%edx
xor    %ecx,%ecx
nopw   0x0(%rax,%rax,1)
mov    (%rdi,%rcx,1),%r8d
mov    %r8d,(%rsi,%rcx,1)
xor    %r9d,%r9d
test   %r8d,%r8d
setg   %r9b
add    %r9d,%eax
add    $0x4,%rcx
add    $0xffffffff,%edx
cmp    $0x1,%edx
ja     1230 <ncopy+0x130>
ret
xor    %eax,%eax
ret
pxor   %xmm0,%xmm0
xor    %eax,%eax
pxor   %xmm1,%xmm1
test   $0x1,%r9b
jne    11ce <ncopy+0xce>
jmp    11f8 <ncopy+0xf8>

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

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