void add_Bytes(void *state, const unsigned char *data, unsigned int offset,
               unsigned int length) {
  unsigned int i;
  for (i = 0; i < length; i++)
    ((unsigned char *)state)[offset + i] ^= data[i];
}


x86 assembly (clang, -O0):
<add_Bytes>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    %ecx,-0x18(%rbp)
movl   $0x0,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0x18(%rbp),%eax
jae    1153 <add_Bytes+0x53>
mov    -0x10(%rbp),%rax
mov    -0x1c(%rbp),%ecx
movzbl (%rax,%rcx,1),%esi
mov    -0x8(%rbp),%rax
mov    -0x14(%rbp),%ecx
add    -0x1c(%rbp),%ecx
mov    %ecx,%ecx
movzbl (%rax,%rcx,1),%edx
xor    %esi,%edx
mov    %dl,(%rax,%rcx,1)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1119 <add_Bytes+0x19>
pop    %rbp
ret

x86 assembly (clang, -O2):
<add_Bytes>:
push   %r14
push   %rbx
test   %ecx,%ecx
je     115f <add_Bytes+0x5f>
mov    %ecx,%eax
cmp    $0x8,%ecx
jae    1163 <add_Bytes+0x63>
xor    %r8d,%r8d
mov    %r8,%rcx
not    %rcx
test   $0x1,%al
je     112b <add_Bytes+0x2b>
mov    (%rsi,%r8,1),%r9b
lea    (%r8,%rdx,1),%ebx
xor    %r9b,(%rdi,%rbx,1)
or     $0x1,%r8
add    %rax,%rcx
je     115f <add_Bytes+0x5f>
sub    %r8,%rax
add    %r8d,%edx
lea    (%r8,%rsi,1),%rcx
add    $0x1,%rcx
xchg   %ax,%ax
movzbl -0x1(%rcx),%ebx
mov    %edx,%esi
xor    %bl,(%rdi,%rsi,1)
movzbl (%rcx),%ebx
lea    0x1(%rdx),%esi
xor    %bl,(%rdi,%rsi,1)
add    $0x2,%edx
add    $0x2,%rcx
add    $0xfffffffffffffffe,%rax
jne    1140 <add_Bytes+0x40>
pop    %rbx
pop    %r14
ret
lea    -0x1(%rax),%r9
xor    %r8d,%r8d
mov    %edx,%ebx
add    %r9d,%ebx
jb     1111 <add_Bytes+0x11>
shr    $0x20,%r9
jne    1111 <add_Bytes+0x11>
mov    %edx,%r9d
lea    (%rax,%r9,1),%rbx
add    %rdi,%rbx
cmp    %rsi,%rbx
jbe    1197 <add_Bytes+0x97>
lea    (%rsi,%rax,1),%r8
lea    (%rdi,%r9,1),%rbx
cmp    %r8,%rbx
jb     110e <add_Bytes+0xe>
cmp    $0x20,%ecx
jae    11a4 <add_Bytes+0xa4>
xor    %r8d,%r8d
jmp    126c <add_Bytes+0x16c>
mov    %eax,%r8d
and    $0xffffffe0,%r8d
lea    -0x20(%r8),%rcx
mov    %rcx,%r10
shr    $0x5,%r10
add    $0x1,%r10
test   %rcx,%rcx
je     122b <add_Bytes+0x12b>
mov    %r10,%r11
and    $0xfffffffffffffffe,%r11
xor    %r14d,%r14d
mov    %edx,%ebx
nopl   0x0(%rax,%rax,1)
movups (%rsi,%r14,1),%xmm0
movups 0x10(%rsi,%r14,1),%xmm1
mov    %ebx,%ecx
movups (%rdi,%rcx,1),%xmm2
xorps  %xmm0,%xmm2
movups 0x10(%rdi,%rcx,1),%xmm0
xorps  %xmm1,%xmm0
movups %xmm2,(%rdi,%rcx,1)
movups %xmm0,0x10(%rdi,%rcx,1)
movups 0x20(%rsi,%r14,1),%xmm0
movups 0x30(%rsi,%r14,1),%xmm1
lea    0x20(%rbx),%ecx
movups (%rdi,%rcx,1),%xmm2
xorps  %xmm0,%xmm2
movups 0x10(%rdi,%rcx,1),%xmm0
xorps  %xmm1,%xmm0
movups %xmm2,(%rdi,%rcx,1)
movups %xmm0,0x10(%rdi,%rcx,1)
add    $0x40,%r14
add    $0x40,%ebx
add    $0xfffffffffffffffe,%r11
jne    11d0 <add_Bytes+0xd0>
jmp    122e <add_Bytes+0x12e>
xor    %r14d,%r14d
test   $0x1,%r10b
je     125b <add_Bytes+0x15b>
movups (%rsi,%r14,1),%xmm0
movups 0x10(%rsi,%r14,1),%xmm1
lea    (%r14,%rdx,1),%ecx
movups (%rdi,%rcx,1),%xmm2
xorps  %xmm0,%xmm2
movups 0x10(%rdi,%rcx,1),%xmm0
xorps  %xmm1,%xmm0
movups %xmm2,(%rdi,%rcx,1)
movups %xmm0,0x10(%rdi,%rcx,1)
cmp    %rax,%r8
je     115f <add_Bytes+0x5f>
test   $0x18,%al
je     1111 <add_Bytes+0x11>
mov    %r8,%rcx
mov    %eax,%r8d
and    $0xfffffff8,%r8d
cs nopw 0x0(%rax,%rax,1)
mov    (%rsi,%rcx,1),%r10
lea    (%r9,%rcx,1),%ebx
xor    %r10,(%rdi,%rbx,1)
add    $0x8,%rcx
cmp    %rcx,%r8
jne    1280 <add_Bytes+0x180>
cmp    %rax,%r8
jne    1111 <add_Bytes+0x11>
jmp    115f <add_Bytes+0x5f>

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

LLVM IR (-O2):
define void @add_Bytes(i8* nocapture %0, i8* nocapture %1, i32 %2, i32 %3) {
%5 = icmp eq i32 %3, 0
br i1 %5, label %169, label %6
6: ; preds = %4
%7 = zext i32 %3 to i64
%8 = icmp ult i32 %3, 8
br i1 %8, label %129, label %9
9: ; preds = %6
%10 = add nsw i64 %7, -1
%11 = trunc i64 %10 to i32
%12 = xor i32 %2, -1
%13 = icmp ult i32 %12, %11
%14 = icmp ugt i64 %10, 4294967295
%15 = or i1 %13, %14
br i1 %15, label %129, label %16
16: ; preds = %9
%17 = getelementptr i8, i8* %1, i64 %7
%18 = zext i32 %2 to i64
%19 = getelementptr i8, i8* %0, i64 %18
%20 = add nuw nsw i64 %7, %18
%21 = getelementptr i8, i8* %0, i64 %20
%22 = icmp ugt i8* %21, %1
%23 = icmp ult i8* %19, %17
%24 = and i1 %22, %23
br i1 %24, label %129, label %25
25: ; preds = %16
%26 = icmp ult i32 %3, 32
br i1 %26, label %109, label %27
27: ; preds = %25
%28 = and i64 %7, 4294967264
%29 = add nsw i64 %28, -32
%30 = lshr exact i64 %29, 5
%31 = add nuw nsw i64 %30, 1
%32 = and i64 %31, 1
%33 = icmp eq i64 %29, 0
br i1 %33, label %81, label %34
34: ; preds = %27
%35 = and i64 %31, 1152921504606846974
br label %36
36: ; preds = %36, %34
%37 = phi i64 [ 0, %34 ], [ %78, %36 ]
%38 = phi i64 [ 0, %34 ], [ %79, %36 ]
%39 = trunc i64 %37 to i32
%40 = getelementptr inbounds i8, i8* %1, i64 %37
%41 = bitcast i8* %40 to <16 x i8>*
%42 = load <16 x i8>, <16 x i8>* %41
%43 = getelementptr inbounds i8, i8* %40, i64 16
%44 = bitcast i8* %43 to <16 x i8>*
%45 = load <16 x i8>, <16 x i8>* %44
%46 = add i32 %39, %2
%47 = zext i32 %46 to i64
%48 = getelementptr inbounds i8, i8* %0, i64 %47
%49 = bitcast i8* %48 to <16 x i8>*
%50 = load <16 x i8>, <16 x i8>* %49
%51 = getelementptr inbounds i8, i8* %48, i64 16
%52 = bitcast i8* %51 to <16 x i8>*
%53 = load <16 x i8>, <16 x i8>* %52
%54 = xor <16 x i8> %50, %42
%55 = xor <16 x i8> %53, %45
%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 = or i64 %37, 32
%59 = trunc i64 %58 to i32
%60 = getelementptr inbounds i8, i8* %1, i64 %58
%61 = bitcast i8* %60 to <16 x i8>*
%62 = load <16 x i8>, <16 x i8>* %61
%63 = getelementptr inbounds i8, i8* %60, i64 16
%64 = bitcast i8* %63 to <16 x i8>*
%65 = load <16 x i8>, <16 x i8>* %64
%66 = add i32 %59, %2
%67 = zext i32 %66 to i64
%68 = getelementptr inbounds i8, i8* %0, i64 %67
%69 = bitcast i8* %68 to <16 x i8>*
%70 = load <16 x i8>, <16 x i8>* %69
%71 = getelementptr inbounds i8, i8* %68, i64 16
%72 = bitcast i8* %71 to <16 x i8>*
%73 = load <16 x i8>, <16 x i8>* %72
%74 = xor <16 x i8> %70, %62
%75 = xor <16 x i8> %73, %65
%76 = bitcast i8* %68 to <16 x i8>*
store <16 x i8> %74, <16 x i8>* %76
%77 = bitcast i8* %71 to <16 x i8>*
store <16 x i8> %75, <16 x i8>* %77
%78 = add nuw i64 %37, 64
%79 = add i64 %38, 2
%80 = icmp eq i64 %79, %35
br i1 %80, label %81, label %36
81: ; preds = %36, %27
%82 = phi i64 [ 0, %27 ], [ %78, %36 ]
%83 = icmp eq i64 %32, 0
br i1 %83, label %104, label %84
84: ; preds = %81
%85 = trunc i64 %82 to i32
%86 = getelementptr inbounds i8, i8* %1, i64 %82
%87 = bitcast i8* %86 to <16 x i8>*
%88 = load <16 x i8>, <16 x i8>* %87
%89 = getelementptr inbounds i8, i8* %86, i64 16
%90 = bitcast i8* %89 to <16 x i8>*
%91 = load <16 x i8>, <16 x i8>* %90
%92 = add i32 %85, %2
%93 = zext i32 %92 to i64
%94 = getelementptr inbounds i8, i8* %0, i64 %93
%95 = bitcast i8* %94 to <16 x i8>*
%96 = load <16 x i8>, <16 x i8>* %95
%97 = getelementptr inbounds i8, i8* %94, i64 16
%98 = bitcast i8* %97 to <16 x i8>*
%99 = load <16 x i8>, <16 x i8>* %98
%100 = xor <16 x i8> %96, %88
%101 = xor <16 x i8> %99, %91
%102 = bitcast i8* %94 to <16 x i8>*
store <16 x i8> %100, <16 x i8>* %102
%103 = bitcast i8* %97 to <16 x i8>*
store <16 x i8> %101, <16 x i8>* %103
br label %104
104: ; preds = %81, %84
%105 = icmp eq i64 %28, %7
br i1 %105, label %169, label %106
106: ; preds = %104
%107 = and i64 %7, 24
%108 = icmp eq i64 %107, 0
br i1 %108, label %129, label %109
109: ; preds = %25, %106
%110 = phi i64 [ %28, %106 ], [ 0, %25 ]
%111 = and i64 %7, 4294967288
br label %112
112: ; preds = %112, %109
%113 = phi i64 [ %110, %109 ], [ %125, %112 ]
%114 = trunc i64 %113 to i32
%115 = getelementptr inbounds i8, i8* %1, i64 %113
%116 = bitcast i8* %115 to <8 x i8>*
%117 = load <8 x i8>, <8 x i8>* %116
%118 = add i32 %114, %2
%119 = zext i32 %118 to i64
%120 = getelementptr inbounds i8, i8* %0, i64 %119
%121 = bitcast i8* %120 to <8 x i8>*
%122 = load <8 x i8>, <8 x i8>* %121
%123 = xor <8 x i8> %122, %117
%124 = bitcast i8* %120 to <8 x i8>*
store <8 x i8> %123, <8 x i8>* %124
%125 = add nuw i64 %113, 8
%126 = icmp eq i64 %125, %111
br i1 %126, label %127, label %112
127: ; preds = %112
%128 = icmp eq i64 %111, %7
br i1 %128, label %169, label %129
129: ; preds = %16, %9, %6, %106, %127
%130 = phi i64 [ 0, %6 ], [ 0, %16 ], [ 0, %9 ], [ %28, %106 ], [ %111, %127 ]
%131 = xor i64 %130, -1
%132 = and i64 %7, 1
%133 = icmp eq i64 %132, 0
br i1 %133, label %144, label %134
134: ; preds = %129
%135 = getelementptr inbounds i8, i8* %1, i64 %130
%136 = load i8, i8* %135
%137 = trunc i64 %130 to i32
%138 = add i32 %137, %2
%139 = zext i32 %138 to i64
%140 = getelementptr inbounds i8, i8* %0, i64 %139
%141 = load i8, i8* %140
%142 = xor i8 %141, %136
store i8 %142, i8* %140
%143 = or i64 %130, 1
br label %144
144: ; preds = %134, %129
%145 = phi i64 [ %130, %129 ], [ %143, %134 ]
%146 = sub nsw i64 0, %7
%147 = icmp eq i64 %131, %146
br i1 %147, label %169, label %148
148: ; preds = %144, %148
%149 = phi i64 [ %167, %148 ], [ %145, %144 ]
%150 = getelementptr inbounds i8, i8* %1, i64 %149
%151 = load i8, i8* %150
%152 = trunc i64 %149 to i32
%153 = add i32 %152, %2
%154 = zext i32 %153 to i64
%155 = getelementptr inbounds i8, i8* %0, i64 %154
%156 = load i8, i8* %155
%157 = xor i8 %156, %151
store i8 %157, i8* %155
%158 = add nuw nsw i64 %149, 1
%159 = getelementptr inbounds i8, i8* %1, i64 %158
%160 = load i8, i8* %159
%161 = trunc i64 %158 to i32
%162 = add i32 %161, %2
%163 = zext i32 %162 to i64
%164 = getelementptr inbounds i8, i8* %0, i64 %163
%165 = load i8, i8* %164
%166 = xor i8 %165, %160
store i8 %166, i8* %164
%167 = add nuw nsw i64 %149, 2
%168 = icmp eq i64 %167, %7
br i1 %168, label %169, label %148
169: ; preds = %144, %148, %104, %127, %4
ret void
}