void gf_fast_add_parity(void *to_add, void *to_modify, int size) {
  unsigned long *p, *t;
  int j;
  j = size / sizeof(unsigned long);
  t = (unsigned long *)to_add;
  p = (unsigned long *)to_modify;
  p += j;
  t += j;
  while (t != (unsigned long *)to_add) {
    p--;
    t--;
    *p = *p ^ *t;
  }
}


x86 assembly (clang, -O0):
<gf_fast_add_parity>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
movslq -0x14(%rbp),%rax
shr    $0x3,%rax
mov    %eax,-0x2c(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x2c(%rbp),%ecx
mov    -0x20(%rbp),%rax
movslq %ecx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
mov    %rax,-0x20(%rbp)
mov    -0x2c(%rbp),%ecx
mov    -0x28(%rbp),%rax
movslq %ecx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rax
mov    -0x8(%rbp),%rcx
cmp    %rcx,%rax
je     1197 <gf_fast_add_parity+0x97>
mov    -0x20(%rbp),%rax
add    $0xfffffffffffffff8,%rax
mov    %rax,-0x20(%rbp)
mov    -0x28(%rbp),%rax
add    $0xfffffffffffffff8,%rax
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rax
mov    (%rax),%rcx
mov    -0x28(%rbp),%rax
xor    (%rax),%rcx
mov    -0x20(%rbp),%rax
mov    %rcx,(%rax)
jmp    1154 <gf_fast_add_parity+0x54>
pop    %rbp
ret

x86 assembly (clang, -O2):
<gf_fast_add_parity>:
push   %r14
push   %rbx
sar    $0x3,%edx
movslq %edx,%r11
lea    0x0(,%r11,8),%rax
test   %rax,%rax
je     1244 <gf_fast_add_parity+0x144>
lea    (%rdi,%r11,8),%rax
lea    (%rsi,%r11,8),%rcx
lea    -0x1(%r11),%rdx
movabs $0x1fffffffffffffff,%r10
ff ff 1f
and    %rdx,%r10
cmp    $0x3,%r10
jb     1229 <gf_fast_add_parity+0x129>
lea    (%rdi,%r11,8),%rdx
cmp    %rsi,%rdx
jbe    1153 <gf_fast_add_parity+0x53>
lea    (%rsi,%r11,8),%rdx
cmp    %rdi,%rdx
ja     1229 <gf_fast_add_parity+0x129>
add    $0x1,%r10
mov    %r10,%r8
and    $0xfffffffffffffffc,%r8
lea    -0x4(%r8),%rdx
mov    %rdx,%r9
shr    $0x2,%r9
add    $0x1,%r9
test   %rdx,%rdx
je     1248 <gf_fast_add_parity+0x148>
mov    %r9,%rdx
and    $0xfffffffffffffffe,%rdx
lea    (%rdi,%r11,8),%r14
add    $0xfffffffffffffff0,%r14
lea    (%rsi,%r11,8),%rbx
add    $0xfffffffffffffff0,%rbx
xor    %esi,%esi
nop
movups -0x30(%rbx,%rsi,8),%xmm0
movups -0x20(%rbx,%rsi,8),%xmm1
movups -0x10(%rbx,%rsi,8),%xmm2
movups (%rbx,%rsi,8),%xmm3
movups -0x10(%r14,%rsi,8),%xmm4
xorps  %xmm2,%xmm4
movups (%r14,%rsi,8),%xmm2
xorps  %xmm3,%xmm2
movups %xmm2,(%rbx,%rsi,8)
movups %xmm4,-0x10(%rbx,%rsi,8)
movups -0x30(%r14,%rsi,8),%xmm2
xorps  %xmm0,%xmm2
movups -0x20(%r14,%rsi,8),%xmm0
xorps  %xmm1,%xmm0
movups %xmm0,-0x20(%rbx,%rsi,8)
movups %xmm2,-0x30(%rbx,%rsi,8)
add    $0xfffffffffffffff8,%rsi
add    $0xfffffffffffffffe,%rdx
jne    1190 <gf_fast_add_parity+0x90>
neg    %rsi
test   $0x1,%r9b
je     121a <gf_fast_add_parity+0x11a>
shl    $0x3,%rsi
mov    %rcx,%rdx
sub    %rsi,%rdx
mov    %rax,%rbx
sub    %rsi,%rbx
movups -0x20(%rdx),%xmm0
movups -0x10(%rdx),%xmm1
movups -0x20(%rbx),%xmm2
xorps  %xmm0,%xmm2
movups -0x10(%rbx),%xmm0
xorps  %xmm1,%xmm0
movups %xmm0,-0x10(%rdx)
movups %xmm2,-0x20(%rdx)
cmp    %r8,%r10
je     1244 <gf_fast_add_parity+0x144>
shl    $0x3,%r8
sub    %r8,%rcx
sub    %r8,%rax
add    $0xfffffffffffffff8,%rcx
nopl   (%rax)
mov    -0x8(%rax),%rdx
xor    %rdx,(%rcx)
add    $0xfffffffffffffff8,%rax
add    $0xfffffffffffffff8,%rcx
cmp    %rdi,%rax
jne    1230 <gf_fast_add_parity+0x130>
pop    %rbx
pop    %r14
ret
xor    %esi,%esi
test   $0x1,%r9b
jne    11ec <gf_fast_add_parity+0xec>
jmp    121a <gf_fast_add_parity+0x11a>

LLVM IR (-O0):
define void @gf_fast_add_parity(i8* %0, i8* %1, i32 %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i32
%7 = alloca i64*
%8 = alloca i64*
%9 = alloca i32
store i8* %0, i8** %4
store i8* %1, i8** %5
store i32 %2, i32* %6
%10 = load i32, i32* %6
%11 = sext i32 %10 to i64
%12 = udiv i64 %11, 8
%13 = trunc i64 %12 to i32
store i32 %13, i32* %9
%14 = load i8*, i8** %4
%15 = bitcast i8* %14 to i64*
store i64* %15, i64** %8
%16 = load i8*, i8** %5
%17 = bitcast i8* %16 to i64*
store i64* %17, i64** %7
%18 = load i32, i32* %9
%19 = load i64*, i64** %7
%20 = sext i32 %18 to i64
%21 = getelementptr inbounds i64, i64* %19, i64 %20
store i64* %21, i64** %7
%22 = load i32, i32* %9
%23 = load i64*, i64** %8
%24 = sext i32 %22 to i64
%25 = getelementptr inbounds i64, i64* %23, i64 %24
store i64* %25, i64** %8
br label %26
26: ; preds = %31, %3
%27 = load i64*, i64** %8
%28 = load i8*, i8** %4
%29 = bitcast i8* %28 to i64*
%30 = icmp ne i64* %27, %29
br i1 %30, label %31, label %42
31: ; preds = %26
%32 = load i64*, i64** %7
%33 = getelementptr inbounds i64, i64* %32, i32 -1
store i64* %33, i64** %7
%34 = load i64*, i64** %8
%35 = getelementptr inbounds i64, i64* %34, i32 -1
store i64* %35, i64** %8
%36 = load i64*, i64** %7
%37 = load i64, i64* %36
%38 = load i64*, i64** %8
%39 = load i64, i64* %38
%40 = xor i64 %37, %39
%41 = load i64*, i64** %7
store i64 %40, i64* %41
br label %26
42: ; preds = %26
ret void
}

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