#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
void mem_xor2(void *__restrict__ dst_, const void *__restrict__ src1_,
              const void *__restrict__ src2_, size_t n) {
  unsigned char *dst = (unsigned char *)dst_;
  const unsigned char *src1 = (const unsigned char *)src1_;
  const unsigned char *src2 = (const unsigned char *)src2_;
  size_t i;
  for (i = 0; i < n; i++) {
    dst[i] = src1[i] ^ src2[i];
  }
}


x86 assembly (clang, -O0):
<mem_xor2>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x18(%rbp),%rax
mov    %rax,-0x38(%rbp)
movq   $0x0,-0x40(%rbp)
mov    -0x40(%rbp),%rax
cmp    -0x20(%rbp),%rax
jae    117a <mem_xor2+0x7a>
mov    -0x30(%rbp),%rax
mov    -0x40(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
mov    -0x38(%rbp),%rcx
mov    -0x40(%rbp),%rdx
movzbl (%rcx,%rdx,1),%ecx
xor    %ecx,%eax
mov    %al,%dl
mov    -0x28(%rbp),%rax
mov    -0x40(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x40(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x40(%rbp)
jmp    1134 <mem_xor2+0x34>
pop    %rbp
ret

x86 assembly (clang, -O2):
<mem_xor2>:
test   %rcx,%rcx
je     1226 <mem_xor2+0x126>
cmp    $0x8,%rcx
jae    1117 <mem_xor2+0x17>
xor    %r11d,%r11d
jmp    1210 <mem_xor2+0x110>
cmp    $0x20,%rcx
jae    1125 <mem_xor2+0x25>
xor    %r11d,%r11d
jmp    11e2 <mem_xor2+0xe2>
mov    %rcx,%r11
and    $0xffffffffffffffe0,%r11
lea    -0x20(%r11),%rax
mov    %rax,%r9
shr    $0x5,%r9
add    $0x1,%r9
test   %rax,%rax
je     1227 <mem_xor2+0x127>
mov    %r9,%r10
and    $0xfffffffffffffffe,%r10
xor    %r8d,%r8d
xchg   %ax,%ax
movups (%rsi,%r8,1),%xmm0
movups 0x10(%rsi,%r8,1),%xmm1
movups (%rdx,%r8,1),%xmm2
xorps  %xmm0,%xmm2
movups 0x10(%rdx,%r8,1),%xmm0
xorps  %xmm1,%xmm0
movups %xmm2,(%rdi,%r8,1)
movups %xmm0,0x10(%rdi,%r8,1)
movups 0x20(%rsi,%r8,1),%xmm0
movups 0x30(%rsi,%r8,1),%xmm1
movups 0x20(%rdx,%r8,1),%xmm2
xorps  %xmm0,%xmm2
movups 0x30(%rdx,%r8,1),%xmm0
xorps  %xmm1,%xmm0
movups %xmm2,0x20(%rdi,%r8,1)
movups %xmm0,0x30(%rdi,%r8,1)
add    $0x40,%r8
add    $0xfffffffffffffffe,%r10
jne    1150 <mem_xor2+0x50>
test   $0x1,%r9b
je     11d8 <mem_xor2+0xd8>
movups (%rsi,%r8,1),%xmm0
movups 0x10(%rsi,%r8,1),%xmm1
movups (%rdx,%r8,1),%xmm2
xorps  %xmm0,%xmm2
movups 0x10(%rdx,%r8,1),%xmm0
xorps  %xmm1,%xmm0
movups %xmm2,(%rdi,%r8,1)
movups %xmm0,0x10(%rdi,%r8,1)
cmp    %rcx,%r11
je     1226 <mem_xor2+0x126>
test   $0x18,%cl
je     1210 <mem_xor2+0x110>
mov    %r11,%r8
mov    %rcx,%r11
and    $0xfffffffffffffff8,%r11
nopl   0x0(%rax)
mov    (%rdx,%r8,1),%rax
xor    (%rsi,%r8,1),%rax
mov    %rax,(%rdi,%r8,1)
add    $0x8,%r8
cmp    %r8,%r11
jne    11f0 <mem_xor2+0xf0>
cmp    %rcx,%r11
je     1226 <mem_xor2+0x126>
nopw   0x0(%rax,%rax,1)
movzbl (%rdx,%r11,1),%eax
xor    (%rsi,%r11,1),%al
mov    %al,(%rdi,%r11,1)
add    $0x1,%r11
cmp    %r11,%rcx
jne    1210 <mem_xor2+0x110>
ret
xor    %r8d,%r8d
test   $0x1,%r9b
jne    11b1 <mem_xor2+0xb1>
jmp    11d8 <mem_xor2+0xd8>

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

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