#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 stringXOR(size_t size, char *source, char *dest, char key) {
  for (int i = 0; i < size; i++) {
    dest[i] = source[i] ^ key;
  }
}


x86 assembly (clang, -O0):
<stringXOR>:
push   %rbp
mov    %rsp,%rbp
mov    %cl,%al
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %al,-0x19(%rbp)
movl   $0x0,-0x20(%rbp)
movslq -0x20(%rbp),%rax
cmp    -0x8(%rbp),%rax
jae    1157 <stringXOR+0x57>
mov    -0x10(%rbp),%rax
movslq -0x20(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
movsbl -0x19(%rbp),%ecx
xor    %ecx,%eax
mov    %al,%dl
mov    -0x18(%rbp),%rax
movslq -0x20(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    111c <stringXOR+0x1c>
pop    %rbp
ret

x86 assembly (clang, -O2):
<stringXOR>:
push   %r14
push   %rbx
test   %rdi,%rdi
je     119b <stringXOR+0x9b>
cmp    $0x8,%rdi
jb     1128 <stringXOR+0x28>
lea    (%rsi,%rdi,1),%rax
cmp    %rdx,%rax
jbe    119f <stringXOR+0x9f>
lea    (%rdx,%rdi,1),%rax
cmp    %rsi,%rax
jbe    119f <stringXOR+0x9f>
xor    %r14d,%r14d
mov    %r14,%r8
not    %r8
add    %rdi,%r8
mov    %rdi,%rax
and    $0x3,%rax
je     1155 <stringXOR+0x55>
nopl   (%rax)
movzbl (%rsi,%r14,1),%ebx
xor    %cl,%bl
mov    %bl,(%rdx,%r14,1)
add    $0x1,%r14
add    $0xffffffffffffffff,%rax
jne    1140 <stringXOR+0x40>
cmp    $0x3,%r8
jb     119b <stringXOR+0x9b>
nopl   0x0(%rax,%rax,1)
movzbl (%rsi,%r14,1),%eax
xor    %cl,%al
mov    %al,(%rdx,%r14,1)
movzbl 0x1(%rsi,%r14,1),%eax
xor    %cl,%al
mov    %al,0x1(%rdx,%r14,1)
movzbl 0x2(%rsi,%r14,1),%eax
xor    %cl,%al
mov    %al,0x2(%rdx,%r14,1)
movzbl 0x3(%rsi,%r14,1),%eax
xor    %cl,%al
mov    %al,0x3(%rdx,%r14,1)
add    $0x4,%r14
cmp    %r14,%rdi
jne    1160 <stringXOR+0x60>
pop    %rbx
pop    %r14
ret
movzbl %cl,%r8d
cmp    $0x20,%rdi
jae    11b1 <stringXOR+0xb1>
xor    %r14d,%r14d
jmp    127b <stringXOR+0x17b>
mov    %rdi,%r14
and    $0xffffffffffffffe0,%r14
movd   %r8d,%xmm0
punpcklbw %xmm0,%xmm0
pshuflw $0x0,%xmm0,%xmm0
pshufd $0x0,%xmm0,%xmm0
lea    -0x20(%r14),%rax
mov    %rax,%r10
shr    $0x5,%r10
add    $0x1,%r10
test   %rax,%rax
je     12c5 <stringXOR+0x1c5>
mov    %r10,%r11
and    $0xfffffffffffffffe,%r11
xor    %r9d,%r9d
nopl   (%rax)
movdqu (%rsi,%r9,1),%xmm1
movdqu 0x10(%rsi,%r9,1),%xmm2
pxor   %xmm0,%xmm1
pxor   %xmm0,%xmm2
movdqu %xmm1,(%rdx,%r9,1)
movdqu %xmm2,0x10(%rdx,%r9,1)
movdqu 0x20(%rsi,%r9,1),%xmm1
movdqu 0x30(%rsi,%r9,1),%xmm2
pxor   %xmm0,%xmm1
pxor   %xmm0,%xmm2
movdqu %xmm1,0x20(%rdx,%r9,1)
movdqu %xmm2,0x30(%rdx,%r9,1)
add    $0x40,%r9
add    $0xfffffffffffffffe,%r11
jne    11f0 <stringXOR+0xf0>
test   $0x1,%r10b
je     1268 <stringXOR+0x168>
movdqu (%rsi,%r9,1),%xmm1
movdqu 0x10(%rsi,%r9,1),%xmm2
pxor   %xmm0,%xmm1
pxor   %xmm0,%xmm2
movdqu %xmm1,(%rdx,%r9,1)
movdqu %xmm2,0x10(%rdx,%r9,1)
cmp    %rdi,%r14
je     119b <stringXOR+0x9b>
test   $0x18,%dil
je     112b <stringXOR+0x2b>
mov    %r14,%rax
mov    %rdi,%r14
and    $0xfffffffffffffff8,%r14
movd   %r8d,%xmm0
punpcklbw %xmm0,%xmm0
pshuflw $0x0,%xmm0,%xmm0
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movq   (%rsi,%rax,1),%xmm1
pxor   %xmm0,%xmm1
movq   %xmm1,(%rdx,%rax,1)
add    $0x8,%rax
cmp    %rax,%r14
jne    12a0 <stringXOR+0x1a0>
cmp    %rdi,%r14
je     119b <stringXOR+0x9b>
jmp    112b <stringXOR+0x2b>
xor    %r9d,%r9d
test   $0x1,%r10b
jne    1246 <stringXOR+0x146>
jmp    1268 <stringXOR+0x168>

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

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