void exclusive(unsigned char *output, unsigned char *input, int n) {
  unsigned char i;
  for (i = 0; i < n; ++i) {
    output[i] ^= input[i];
  }
}


x86 assembly (clang, -O0):
<exclusive>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
movb   $0x0,-0x15(%rbp)
movzbl -0x15(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    114a <exclusive+0x4a>
mov    -0x10(%rbp),%rax
movzbl -0x15(%rbp),%ecx
movzbl (%rax,%rcx,1),%esi
mov    -0x8(%rbp),%rax
movzbl -0x15(%rbp),%ecx
movzbl (%rax,%rcx,1),%edx
xor    %esi,%edx
mov    %dl,(%rax,%rcx,1)
mov    -0x15(%rbp),%al
add    $0x1,%al
mov    %al,-0x15(%rbp)
jmp    1113 <exclusive+0x13>
pop    %rbp
ret

x86 assembly (clang, -O2):
<exclusive>:
test   %edx,%edx
jle    1313 <exclusive+0x213>
cmp    $0x8,%edx
jae    1114 <exclusive+0x14>
xor    %eax,%eax
jmp    1300 <exclusive+0x200>
lea    -0x1(%rdx),%ecx
xor    %eax,%eax
cmp    $0xff,%cl
je     1300 <exclusive+0x200>
cmp    $0xff,%ecx
ja     1300 <exclusive+0x200>
lea    (%rsi,%rcx,1),%r8
add    $0x1,%r8
xor    %eax,%eax
cmp    %rdi,%r8
jbe    114d <exclusive+0x4d>
add    %rdi,%rcx
add    $0x1,%rcx
cmp    %rsi,%rcx
ja     1300 <exclusive+0x200>
cmp    $0x20,%edx
jb     12d8 <exclusive+0x1d8>
mov    %edx,%eax
and    $0xffffffe0,%eax
movups (%rsi),%xmm0
movups 0x10(%rsi),%xmm1
movups (%rdi),%xmm2
xorps  %xmm0,%xmm2
movups 0x10(%rdi),%xmm0
xorps  %xmm1,%xmm0
movups %xmm2,(%rdi)
movups %xmm0,0x10(%rdi)
cmp    $0x20,%eax
je     12cf <exclusive+0x1cf>
movups 0x20(%rsi),%xmm0
movups 0x30(%rsi),%xmm1
movups 0x20(%rdi),%xmm2
xorps  %xmm0,%xmm2
movups 0x30(%rdi),%xmm0
xorps  %xmm1,%xmm0
movups %xmm2,0x20(%rdi)
movups %xmm0,0x30(%rdi)
cmp    $0x40,%eax
je     12cf <exclusive+0x1cf>
movups 0x40(%rsi),%xmm0
movups 0x50(%rsi),%xmm1
movups 0x40(%rdi),%xmm2
xorps  %xmm0,%xmm2
movups 0x50(%rdi),%xmm0
xorps  %xmm1,%xmm0
movups %xmm2,0x40(%rdi)
movups %xmm0,0x50(%rdi)
cmp    $0x60,%eax
je     12cf <exclusive+0x1cf>
movups 0x60(%rsi),%xmm0
movups 0x70(%rsi),%xmm1
movups 0x60(%rdi),%xmm2
xorps  %xmm0,%xmm2
movups 0x70(%rdi),%xmm0
xorps  %xmm1,%xmm0
movups %xmm2,0x60(%rdi)
movups %xmm0,0x70(%rdi)
cmp    $0x80,%eax
je     12cf <exclusive+0x1cf>
movups 0x80(%rsi),%xmm0
movups 0x90(%rsi),%xmm1
movups 0x80(%rdi),%xmm2
xorps  %xmm0,%xmm2
movups 0x90(%rdi),%xmm0
xorps  %xmm1,%xmm0
movups %xmm2,0x80(%rdi)
movups %xmm0,0x90(%rdi)
cmp    $0xa0,%eax
je     12cf <exclusive+0x1cf>
movups 0xa0(%rsi),%xmm0
movups 0xb0(%rsi),%xmm1
movups 0xa0(%rdi),%xmm2
xorps  %xmm0,%xmm2
movups 0xb0(%rdi),%xmm0
xorps  %xmm1,%xmm0
movups %xmm2,0xa0(%rdi)
movups %xmm0,0xb0(%rdi)
cmp    $0xc0,%eax
je     12cf <exclusive+0x1cf>
movups 0xc0(%rsi),%xmm0
movups 0xd0(%rsi),%xmm1
movups 0xc0(%rdi),%xmm2
xorps  %xmm0,%xmm2
movups 0xd0(%rdi),%xmm0
xorps  %xmm1,%xmm0
movups %xmm2,0xc0(%rdi)
movups %xmm0,0xd0(%rdi)
cmp    $0xe0,%eax
je     12cf <exclusive+0x1cf>
movups 0xe0(%rsi),%xmm0
movups 0xf0(%rsi),%xmm1
movups 0xe0(%rdi),%xmm2
xorps  %xmm0,%xmm2
movups 0xf0(%rdi),%xmm0
xorps  %xmm1,%xmm0
movups %xmm2,0xe0(%rdi)
movups %xmm0,0xf0(%rdi)
cmp    %edx,%eax
je     1313 <exclusive+0x213>
test   $0x18,%dl
je     1300 <exclusive+0x200>
mov    %eax,%r9d
mov    %edx,%eax
and    $0xfffffff8,%eax
mov    %r9d,%r8d
and    $0xf8,%r8d
mov    (%rsi,%r8,1),%rcx
xor    %rcx,(%rdi,%r8,1)
add    $0x8,%r9d
cmp    %r9d,%eax
jne    12e0 <exclusive+0x1e0>
cmp    %edx,%eax
je     1313 <exclusive+0x213>
nop
movzbl %al,%eax
movzbl (%rsi,%rax,1),%ecx
xor    %cl,(%rdi,%rax,1)
add    $0x1,%al
movzbl %al,%ecx
cmp    %edx,%ecx
jl     1300 <exclusive+0x200>
ret

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

LLVM IR (-O2):
define void @exclusive(i8* nocapture %0, i8* nocapture %1, i32 %2) {
%4 = icmp sgt i32 %2, 0
br i1 %4, label %5, label %205
5: ; preds = %3
%6 = icmp ult i32 %2, 8
br i1 %6, label %192, label %7
7: ; preds = %5
%8 = add i32 %2, -1
%9 = trunc i32 %8 to i8
%10 = icmp eq i8 %9, -1
%11 = icmp ugt i32 %8, 255
%12 = or i1 %10, %11
br i1 %12, label %192, label %13
13: ; preds = %7
%14 = add i32 %2, -1
%15 = zext i32 %14 to i64
%16 = add nuw nsw i64 %15, 1
%17 = getelementptr i8, i8* %0, i64 %16
%18 = getelementptr i8, i8* %1, i64 %16
%19 = icmp ugt i8* %18, %0
%20 = icmp ugt i8* %17, %1
%21 = and i1 %19, %20
br i1 %21, label %192, label %22
22: ; preds = %13
%23 = icmp ult i32 %2, 32
br i1 %23, label %172, label %24
24: ; preds = %22
%25 = and i32 %2, -32
%26 = bitcast i8* %1 to <16 x i8>*
%27 = load <16 x i8>, <16 x i8>* %26
%28 = getelementptr inbounds i8, i8* %1, i64 16
%29 = bitcast i8* %28 to <16 x i8>*
%30 = load <16 x i8>, <16 x i8>* %29
%31 = bitcast i8* %0 to <16 x i8>*
%32 = load <16 x i8>, <16 x i8>* %31
%33 = getelementptr inbounds i8, i8* %0, i64 16
%34 = bitcast i8* %33 to <16 x i8>*
%35 = load <16 x i8>, <16 x i8>* %34
%36 = xor <16 x i8> %32, %27
%37 = xor <16 x i8> %35, %30
%38 = bitcast i8* %0 to <16 x i8>*
store <16 x i8> %36, <16 x i8>* %38
%39 = bitcast i8* %33 to <16 x i8>*
store <16 x i8> %37, <16 x i8>* %39
%40 = icmp eq i32 %25, 32
br i1 %40, label %166, label %41
41: ; preds = %24
%42 = getelementptr inbounds i8, i8* %1, i64 32
%43 = bitcast i8* %42 to <16 x i8>*
%44 = load <16 x i8>, <16 x i8>* %43
%45 = getelementptr inbounds i8, i8* %1, i64 48
%46 = bitcast i8* %45 to <16 x i8>*
%47 = load <16 x i8>, <16 x i8>* %46
%48 = getelementptr inbounds i8, i8* %0, i64 32
%49 = bitcast i8* %48 to <16 x i8>*
%50 = load <16 x i8>, <16 x i8>* %49
%51 = getelementptr inbounds i8, i8* %0, i64 48
%52 = bitcast i8* %51 to <16 x i8>*
%53 = load <16 x i8>, <16 x i8>* %52
%54 = xor <16 x i8> %50, %44
%55 = xor <16 x i8> %53, %47
%56 = bitcast i8* %48 to <16 x i8>*
store <16 x i8> %54, <16 x i8>* %56
%57 = bitcast i8* %51 to <16 x i8>*
store <16 x i8> %55, <16 x i8>* %57
%58 = icmp eq i32 %25, 64
br i1 %58, label %166, label %59
59: ; preds = %41
%60 = getelementptr inbounds i8, i8* %1, i64 64
%61 = bitcast i8* %60 to <16 x i8>*
%62 = load <16 x i8>, <16 x i8>* %61
%63 = getelementptr inbounds i8, i8* %1, i64 80
%64 = bitcast i8* %63 to <16 x i8>*
%65 = load <16 x i8>, <16 x i8>* %64
%66 = getelementptr inbounds i8, i8* %0, i64 64
%67 = bitcast i8* %66 to <16 x i8>*
%68 = load <16 x i8>, <16 x i8>* %67
%69 = getelementptr inbounds i8, i8* %0, i64 80
%70 = bitcast i8* %69 to <16 x i8>*
%71 = load <16 x i8>, <16 x i8>* %70
%72 = xor <16 x i8> %68, %62
%73 = xor <16 x i8> %71, %65
%74 = bitcast i8* %66 to <16 x i8>*
store <16 x i8> %72, <16 x i8>* %74
%75 = bitcast i8* %69 to <16 x i8>*
store <16 x i8> %73, <16 x i8>* %75
%76 = icmp eq i32 %25, 96
br i1 %76, label %166, label %77
77: ; preds = %59
%78 = getelementptr inbounds i8, i8* %1, i64 96
%79 = bitcast i8* %78 to <16 x i8>*
%80 = load <16 x i8>, <16 x i8>* %79
%81 = getelementptr inbounds i8, i8* %1, i64 112
%82 = bitcast i8* %81 to <16 x i8>*
%83 = load <16 x i8>, <16 x i8>* %82
%84 = getelementptr inbounds i8, i8* %0, i64 96
%85 = bitcast i8* %84 to <16 x i8>*
%86 = load <16 x i8>, <16 x i8>* %85
%87 = getelementptr inbounds i8, i8* %0, i64 112
%88 = bitcast i8* %87 to <16 x i8>*
%89 = load <16 x i8>, <16 x i8>* %88
%90 = xor <16 x i8> %86, %80
%91 = xor <16 x i8> %89, %83
%92 = bitcast i8* %84 to <16 x i8>*
store <16 x i8> %90, <16 x i8>* %92
%93 = bitcast i8* %87 to <16 x i8>*
store <16 x i8> %91, <16 x i8>* %93
%94 = icmp eq i32 %25, 128
br i1 %94, label %166, label %95
95: ; preds = %77
%96 = getelementptr inbounds i8, i8* %1, i64 128
%97 = bitcast i8* %96 to <16 x i8>*
%98 = load <16 x i8>, <16 x i8>* %97
%99 = getelementptr inbounds i8, i8* %1, i64 144
%100 = bitcast i8* %99 to <16 x i8>*
%101 = load <16 x i8>, <16 x i8>* %100
%102 = getelementptr inbounds i8, i8* %0, i64 128
%103 = bitcast i8* %102 to <16 x i8>*
%104 = load <16 x i8>, <16 x i8>* %103
%105 = getelementptr inbounds i8, i8* %0, i64 144
%106 = bitcast i8* %105 to <16 x i8>*
%107 = load <16 x i8>, <16 x i8>* %106
%108 = xor <16 x i8> %104, %98
%109 = xor <16 x i8> %107, %101
%110 = bitcast i8* %102 to <16 x i8>*
store <16 x i8> %108, <16 x i8>* %110
%111 = bitcast i8* %105 to <16 x i8>*
store <16 x i8> %109, <16 x i8>* %111
%112 = icmp eq i32 %25, 160
br i1 %112, label %166, label %113
113: ; preds = %95
%114 = getelementptr inbounds i8, i8* %1, i64 160
%115 = bitcast i8* %114 to <16 x i8>*
%116 = load <16 x i8>, <16 x i8>* %115
%117 = getelementptr inbounds i8, i8* %1, i64 176
%118 = bitcast i8* %117 to <16 x i8>*
%119 = load <16 x i8>, <16 x i8>* %118
%120 = getelementptr inbounds i8, i8* %0, i64 160
%121 = bitcast i8* %120 to <16 x i8>*
%122 = load <16 x i8>, <16 x i8>* %121
%123 = getelementptr inbounds i8, i8* %0, i64 176
%124 = bitcast i8* %123 to <16 x i8>*
%125 = load <16 x i8>, <16 x i8>* %124
%126 = xor <16 x i8> %122, %116
%127 = xor <16 x i8> %125, %119
%128 = bitcast i8* %120 to <16 x i8>*
store <16 x i8> %126, <16 x i8>* %128
%129 = bitcast i8* %123 to <16 x i8>*
store <16 x i8> %127, <16 x i8>* %129
%130 = icmp eq i32 %25, 192
br i1 %130, label %166, label %131
131: ; preds = %113
%132 = getelementptr inbounds i8, i8* %1, i64 192
%133 = bitcast i8* %132 to <16 x i8>*
%134 = load <16 x i8>, <16 x i8>* %133
%135 = getelementptr inbounds i8, i8* %1, i64 208
%136 = bitcast i8* %135 to <16 x i8>*
%137 = load <16 x i8>, <16 x i8>* %136
%138 = getelementptr inbounds i8, i8* %0, i64 192
%139 = bitcast i8* %138 to <16 x i8>*
%140 = load <16 x i8>, <16 x i8>* %139
%141 = getelementptr inbounds i8, i8* %0, i64 208
%142 = bitcast i8* %141 to <16 x i8>*
%143 = load <16 x i8>, <16 x i8>* %142
%144 = xor <16 x i8> %140, %134
%145 = xor <16 x i8> %143, %137
%146 = bitcast i8* %138 to <16 x i8>*
store <16 x i8> %144, <16 x i8>* %146
%147 = bitcast i8* %141 to <16 x i8>*
store <16 x i8> %145, <16 x i8>* %147
%148 = icmp eq i32 %25, 224
br i1 %148, label %166, label %149
149: ; preds = %131
%150 = getelementptr inbounds i8, i8* %1, i64 224
%151 = bitcast i8* %150 to <16 x i8>*
%152 = load <16 x i8>, <16 x i8>* %151
%153 = getelementptr inbounds i8, i8* %1, i64 240
%154 = bitcast i8* %153 to <16 x i8>*
%155 = load <16 x i8>, <16 x i8>* %154
%156 = getelementptr inbounds i8, i8* %0, i64 224
%157 = bitcast i8* %156 to <16 x i8>*
%158 = load <16 x i8>, <16 x i8>* %157
%159 = getelementptr inbounds i8, i8* %0, i64 240
%160 = bitcast i8* %159 to <16 x i8>*
%161 = load <16 x i8>, <16 x i8>* %160
%162 = xor <16 x i8> %158, %152
%163 = xor <16 x i8> %161, %155
%164 = bitcast i8* %156 to <16 x i8>*
store <16 x i8> %162, <16 x i8>* %164
%165 = bitcast i8* %159 to <16 x i8>*
store <16 x i8> %163, <16 x i8>* %165
br label %166
166: ; preds = %149, %131, %113, %95, %77, %59, %41, %24
%167 = icmp eq i32 %25, %2
br i1 %167, label %205, label %168
168: ; preds = %166
%169 = trunc i32 %25 to i8
%170 = and i32 %2, 24
%171 = icmp eq i32 %170, 0
br i1 %171, label %192, label %172
172: ; preds = %22, %168
%173 = phi i32 [ %25, %168 ], [ 0, %22 ]
%174 = and i32 %2, -8
%175 = trunc i32 %174 to i8
br label %176
176: ; preds = %176, %172
%177 = phi i32 [ %173, %172 ], [ %188, %176 ]
%178 = and i32 %177, 248
%179 = zext i32 %178 to i64
%180 = getelementptr inbounds i8, i8* %1, i64 %179
%181 = bitcast i8* %180 to <8 x i8>*
%182 = load <8 x i8>, <8 x i8>* %181
%183 = getelementptr inbounds i8, i8* %0, i64 %179
%184 = bitcast i8* %183 to <8 x i8>*
%185 = load <8 x i8>, <8 x i8>* %184
%186 = xor <8 x i8> %185, %182
%187 = bitcast i8* %183 to <8 x i8>*
store <8 x i8> %186, <8 x i8>* %187
%188 = add nuw i32 %177, 8
%189 = icmp eq i32 %188, %174
br i1 %189, label %190, label %176
190: ; preds = %176
%191 = icmp eq i32 %174, %2
br i1 %191, label %205, label %192
192: ; preds = %13, %7, %5, %168, %190
%193 = phi i8 [ 0, %5 ], [ 0, %13 ], [ 0, %7 ], [ %169, %168 ], [ %175, %190 ]
br label %194
194: ; preds = %192, %194
%195 = phi i8 [ %202, %194 ], [ %193, %192 ]
%196 = zext i8 %195 to i64
%197 = getelementptr inbounds i8, i8* %1, i64 %196
%198 = load i8, i8* %197
%199 = getelementptr inbounds i8, i8* %0, i64 %196
%200 = load i8, i8* %199
%201 = xor i8 %200, %198
store i8 %201, i8* %199
%202 = add i8 %195, 1
%203 = zext i8 %202 to i32
%204 = icmp slt i32 %203, %2
br i1 %204, label %194, label %205
205: ; preds = %194, %166, %190, %3
ret void
}