void __attribute__((noipa))
f(signed char *restrict a, signed char *restrict b, signed char *restrict c) {
  for (long int i = 0; i < 50; ++i)
    a[i] = (b[i] + c[i] + 1) >> 1;
}


x86 assembly (clang, -O0):
<f>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
movq   $0x0,-0x20(%rbp)
cmpq   $0x32,-0x20(%rbp)
jge    1161 <f+0x61>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
mov    -0x18(%rbp),%rcx
mov    -0x20(%rbp),%rdx
movsbl (%rcx,%rdx,1),%ecx
add    %ecx,%eax
add    $0x1,%eax
sar    $0x1,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
jmp    1118 <f+0x18>
pop    %rbp
ret

x86 assembly (clang, -O2):
<f>:
movdqu (%rsi),%xmm0
punpckhbw %xmm0,%xmm1
psraw  $0x8,%xmm1
punpcklbw %xmm0,%xmm0
psraw  $0x8,%xmm0
movdqu (%rdx),%xmm2
punpckhbw %xmm2,%xmm3
psraw  $0x8,%xmm3
paddw  %xmm1,%xmm3
punpcklbw %xmm2,%xmm2
psraw  $0x8,%xmm2
paddw  %xmm0,%xmm2
pcmpeqd %xmm0,%xmm0
psubw  %xmm0,%xmm3
psubw  %xmm0,%xmm2
psrlw  $0x1,%xmm2
psrlw  $0x1,%xmm3
movdqa 0xeae(%rip),%xmm1
pand   %xmm1,%xmm3
pand   %xmm1,%xmm2
packuswb %xmm3,%xmm2
movdqu %xmm2,(%rdi)
movdqu 0x10(%rsi),%xmm2
punpckhbw %xmm2,%xmm3
psraw  $0x8,%xmm3
punpcklbw %xmm2,%xmm2
psraw  $0x8,%xmm2
movdqu 0x10(%rdx),%xmm4
punpckhbw %xmm4,%xmm5
psraw  $0x8,%xmm5
paddw  %xmm3,%xmm5
punpcklbw %xmm4,%xmm3
psraw  $0x8,%xmm3
paddw  %xmm2,%xmm3
psubw  %xmm0,%xmm5
psubw  %xmm0,%xmm3
psrlw  $0x1,%xmm3
psrlw  $0x1,%xmm5
pand   %xmm1,%xmm5
pand   %xmm1,%xmm3
packuswb %xmm5,%xmm3
movdqu %xmm3,0x10(%rdi)
movdqu 0x20(%rsi),%xmm2
punpckhbw %xmm2,%xmm3
psraw  $0x8,%xmm3
punpcklbw %xmm2,%xmm2
psraw  $0x8,%xmm2
movdqu 0x20(%rdx),%xmm4
punpckhbw %xmm4,%xmm5
psraw  $0x8,%xmm5
paddw  %xmm3,%xmm5
punpcklbw %xmm4,%xmm3
psraw  $0x8,%xmm3
paddw  %xmm2,%xmm3
psubw  %xmm0,%xmm5
psubw  %xmm0,%xmm3
psrlw  $0x1,%xmm3
psrlw  $0x1,%xmm5
pand   %xmm1,%xmm5
pand   %xmm1,%xmm3
packuswb %xmm5,%xmm3
movdqu %xmm3,0x20(%rdi)
movsbl 0x30(%rsi),%eax
movsbl 0x30(%rdx),%ecx
add    %ecx,%eax
add    $0x1,%eax
shr    %eax
mov    %al,0x30(%rdi)
movsbl 0x31(%rsi),%eax
movsbl 0x31(%rdx),%ecx
add    %ecx,%eax
add    $0x1,%eax
shr    %eax
mov    %al,0x31(%rdi)
ret

LLVM IR (-O0):
define void @f(i8* noalias %0, i8* noalias %1, i8* noalias %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i8*
%7 = alloca i64
store i8* %0, i8** %4
store i8* %1, i8** %5
store i8* %2, i8** %6
store i64 0, i64* %7
br label %8
8: ; preds = %29, %3
%9 = load i64, i64* %7
%10 = icmp slt i64 %9, 50
br i1 %10, label %11, label %32
11: ; preds = %8
%12 = load i8*, i8** %5
%13 = load i64, i64* %7
%14 = getelementptr inbounds i8, i8* %12, i64 %13
%15 = load i8, i8* %14
%16 = sext i8 %15 to i32
%17 = load i8*, i8** %6
%18 = load i64, i64* %7
%19 = getelementptr inbounds i8, i8* %17, i64 %18
%20 = load i8, i8* %19
%21 = sext i8 %20 to i32
%22 = add nsw i32 %16, %21
%23 = add nsw i32 %22, 1
%24 = ashr i32 %23, 1
%25 = trunc i32 %24 to i8
%26 = load i8*, i8** %4
%27 = load i64, i64* %7
%28 = getelementptr inbounds i8, i8* %26, i64 %27
store i8 %25, i8* %28
br label %29
29: ; preds = %11
%30 = load i64, i64* %7
%31 = add nsw i64 %30, 1
store i64 %31, i64* %7
br label %8
32: ; preds = %8
ret void
}

LLVM IR (-O2):
define void @f(i8* noalias nocapture writeonly %0, i8* noalias nocapture %1, i8* noalias nocapture %2) {
%4 = bitcast i8* %1 to <16 x i8>*
%5 = load <16 x i8>, <16 x i8>* %4
%6 = sext <16 x i8> %5 to <16 x i16>
%7 = bitcast i8* %2 to <16 x i8>*
%8 = load <16 x i8>, <16 x i8>* %7
%9 = sext <16 x i8> %8 to <16 x i16>
%10 = add nsw <16 x i16> %6, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%11 = add nsw <16 x i16> %10, %9
%12 = lshr <16 x i16> %11, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%13 = trunc <16 x i16> %12 to <16 x i8>
%14 = bitcast i8* %0 to <16 x i8>*
store <16 x i8> %13, <16 x i8>* %14
%15 = getelementptr inbounds i8, i8* %1, i64 16
%16 = bitcast i8* %15 to <16 x i8>*
%17 = load <16 x i8>, <16 x i8>* %16
%18 = sext <16 x i8> %17 to <16 x i16>
%19 = getelementptr inbounds i8, i8* %2, i64 16
%20 = bitcast i8* %19 to <16 x i8>*
%21 = load <16 x i8>, <16 x i8>* %20
%22 = sext <16 x i8> %21 to <16 x i16>
%23 = add nsw <16 x i16> %18, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%24 = add nsw <16 x i16> %23, %22
%25 = lshr <16 x i16> %24, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%26 = trunc <16 x i16> %25 to <16 x i8>
%27 = getelementptr inbounds i8, i8* %0, i64 16
%28 = bitcast i8* %27 to <16 x i8>*
store <16 x i8> %26, <16 x i8>* %28
%29 = getelementptr inbounds i8, i8* %1, i64 32
%30 = bitcast i8* %29 to <16 x i8>*
%31 = load <16 x i8>, <16 x i8>* %30
%32 = sext <16 x i8> %31 to <16 x i16>
%33 = getelementptr inbounds i8, i8* %2, i64 32
%34 = bitcast i8* %33 to <16 x i8>*
%35 = load <16 x i8>, <16 x i8>* %34
%36 = sext <16 x i8> %35 to <16 x i16>
%37 = add nsw <16 x i16> %32, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%38 = add nsw <16 x i16> %37, %36
%39 = lshr <16 x i16> %38, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%40 = trunc <16 x i16> %39 to <16 x i8>
%41 = getelementptr inbounds i8, i8* %0, i64 32
%42 = bitcast i8* %41 to <16 x i8>*
store <16 x i8> %40, <16 x i8>* %42
%43 = getelementptr inbounds i8, i8* %1, i64 48
%44 = load i8, i8* %43
%45 = sext i8 %44 to i16
%46 = getelementptr inbounds i8, i8* %2, i64 48
%47 = load i8, i8* %46
%48 = sext i8 %47 to i16
%49 = add nsw i16 %45, 1
%50 = add nsw i16 %49, %48
%51 = lshr i16 %50, 1
%52 = trunc i16 %51 to i8
%53 = getelementptr inbounds i8, i8* %0, i64 48
store i8 %52, i8* %53
%54 = getelementptr inbounds i8, i8* %1, i64 49
%55 = load i8, i8* %54
%56 = sext i8 %55 to i16
%57 = getelementptr inbounds i8, i8* %2, i64 49
%58 = load i8, i8* %57
%59 = sext i8 %58 to i16
%60 = add nsw i16 %56, 1
%61 = add nsw i16 %60, %59
%62 = lshr i16 %61, 1
%63 = trunc i16 %62 to i8
%64 = getelementptr inbounds i8, i8* %0, i64 49
store i8 %63, i8* %64
ret void
}