void AddRoundKey(unsigned char state[][4], unsigned char w[]) {
  state[0][0] ^= w[0];
  state[1][0] ^= w[1];
  state[2][0] ^= w[2];
  state[3][0] ^= w[3];
  state[0][1] ^= w[4];
  state[1][1] ^= w[5];
  state[2][1] ^= w[6];
  state[3][1] ^= w[7];
  state[0][2] ^= w[8];
  state[1][2] ^= w[9];
  state[2][2] ^= w[10];
  state[3][2] ^= w[11];
  state[0][3] ^= w[12];
  state[1][3] ^= w[13];
  state[2][3] ^= w[14];
  state[3][3] ^= w[15];
}


x86 assembly (clang, -O0):
<AddRoundKey>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    -0x10(%rbp),%rax
movzbl (%rax),%edx
mov    -0x8(%rbp),%rax
movzbl (%rax),%ecx
xor    %edx,%ecx
mov    %cl,(%rax)
mov    -0x10(%rbp),%rax
movzbl 0x1(%rax),%edx
mov    -0x8(%rbp),%rax
movzbl 0x4(%rax),%ecx
xor    %edx,%ecx
mov    %cl,0x4(%rax)
mov    -0x10(%rbp),%rax
movzbl 0x2(%rax),%edx
mov    -0x8(%rbp),%rax
movzbl 0x8(%rax),%ecx
xor    %edx,%ecx
mov    %cl,0x8(%rax)
mov    -0x10(%rbp),%rax
movzbl 0x3(%rax),%edx
mov    -0x8(%rbp),%rax
movzbl 0xc(%rax),%ecx
xor    %edx,%ecx
mov    %cl,0xc(%rax)
mov    -0x10(%rbp),%rax
movzbl 0x4(%rax),%edx
mov    -0x8(%rbp),%rax
movzbl 0x1(%rax),%ecx
xor    %edx,%ecx
mov    %cl,0x1(%rax)
mov    -0x10(%rbp),%rax
movzbl 0x5(%rax),%edx
mov    -0x8(%rbp),%rax
movzbl 0x5(%rax),%ecx
xor    %edx,%ecx
mov    %cl,0x5(%rax)
mov    -0x10(%rbp),%rax
movzbl 0x6(%rax),%edx
mov    -0x8(%rbp),%rax
movzbl 0x9(%rax),%ecx
xor    %edx,%ecx
mov    %cl,0x9(%rax)
mov    -0x10(%rbp),%rax
movzbl 0x7(%rax),%edx
mov    -0x8(%rbp),%rax
movzbl 0xd(%rax),%ecx
xor    %edx,%ecx
mov    %cl,0xd(%rax)
mov    -0x10(%rbp),%rax
movzbl 0x8(%rax),%edx
mov    -0x8(%rbp),%rax
movzbl 0x2(%rax),%ecx
xor    %edx,%ecx
mov    %cl,0x2(%rax)
mov    -0x10(%rbp),%rax
movzbl 0x9(%rax),%edx
mov    -0x8(%rbp),%rax
movzbl 0x6(%rax),%ecx
xor    %edx,%ecx
mov    %cl,0x6(%rax)
mov    -0x10(%rbp),%rax
movzbl 0xa(%rax),%edx
mov    -0x8(%rbp),%rax
movzbl 0xa(%rax),%ecx
xor    %edx,%ecx
mov    %cl,0xa(%rax)
mov    -0x10(%rbp),%rax
movzbl 0xb(%rax),%edx
mov    -0x8(%rbp),%rax
movzbl 0xe(%rax),%ecx
xor    %edx,%ecx
mov    %cl,0xe(%rax)
mov    -0x10(%rbp),%rax
movzbl 0xc(%rax),%edx
mov    -0x8(%rbp),%rax
movzbl 0x3(%rax),%ecx
xor    %edx,%ecx
mov    %cl,0x3(%rax)
mov    -0x10(%rbp),%rax
movzbl 0xd(%rax),%edx
mov    -0x8(%rbp),%rax
movzbl 0x7(%rax),%ecx
xor    %edx,%ecx
mov    %cl,0x7(%rax)
mov    -0x10(%rbp),%rax
movzbl 0xe(%rax),%edx
mov    -0x8(%rbp),%rax
movzbl 0xb(%rax),%ecx
xor    %edx,%ecx
mov    %cl,0xb(%rax)
mov    -0x10(%rbp),%rax
movzbl 0xf(%rax),%edx
mov    -0x8(%rbp),%rax
movzbl 0xf(%rax),%ecx
xor    %edx,%ecx
mov    %cl,0xf(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<AddRoundKey>:
mov    (%rsi),%al
xor    %al,(%rdi)
mov    0x1(%rsi),%al
xor    %al,0x4(%rdi)
mov    0x2(%rsi),%al
xor    %al,0x8(%rdi)
mov    0x3(%rsi),%al
xor    %al,0xc(%rdi)
mov    0x4(%rsi),%al
xor    %al,0x1(%rdi)
mov    0x5(%rsi),%al
xor    %al,0x5(%rdi)
mov    0x6(%rsi),%al
xor    %al,0x9(%rdi)
mov    0x7(%rsi),%al
xor    %al,0xd(%rdi)
mov    0x8(%rsi),%al
xor    %al,0x2(%rdi)
mov    0x9(%rsi),%al
xor    %al,0x6(%rdi)
mov    0xa(%rsi),%al
xor    %al,0xa(%rdi)
mov    0xb(%rsi),%al
xor    %al,0xe(%rdi)
mov    0xc(%rsi),%al
xor    %al,0x3(%rdi)
mov    0xd(%rsi),%al
xor    %al,0x7(%rdi)
mov    0xe(%rsi),%al
xor    %al,0xb(%rdi)
mov    0xf(%rsi),%al
xor    %al,0xf(%rdi)
ret

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

LLVM IR (-O2):
define void @AddRoundKey([4 x i8]* nocapture %0, i8* nocapture %1) {
%3 = load i8, i8* %1
%4 = getelementptr inbounds [4 x i8], [4 x i8]* %0, i64 0, i64 0
%5 = load i8, i8* %4
%6 = xor i8 %5, %3
store i8 %6, i8* %4
%7 = getelementptr inbounds i8, i8* %1, i64 1
%8 = load i8, i8* %7
%9 = getelementptr inbounds [4 x i8], [4 x i8]* %0, i64 1, i64 0
%10 = load i8, i8* %9
%11 = xor i8 %10, %8
store i8 %11, i8* %9
%12 = getelementptr inbounds i8, i8* %1, i64 2
%13 = load i8, i8* %12
%14 = getelementptr inbounds [4 x i8], [4 x i8]* %0, i64 2, i64 0
%15 = load i8, i8* %14
%16 = xor i8 %15, %13
store i8 %16, i8* %14
%17 = getelementptr inbounds i8, i8* %1, i64 3
%18 = load i8, i8* %17
%19 = getelementptr inbounds [4 x i8], [4 x i8]* %0, i64 3, i64 0
%20 = load i8, i8* %19
%21 = xor i8 %20, %18
store i8 %21, i8* %19
%22 = getelementptr inbounds i8, i8* %1, i64 4
%23 = load i8, i8* %22
%24 = getelementptr inbounds [4 x i8], [4 x i8]* %0, i64 0, i64 1
%25 = load i8, i8* %24
%26 = xor i8 %25, %23
store i8 %26, i8* %24
%27 = getelementptr inbounds i8, i8* %1, i64 5
%28 = load i8, i8* %27
%29 = getelementptr inbounds [4 x i8], [4 x i8]* %0, i64 1, i64 1
%30 = load i8, i8* %29
%31 = xor i8 %30, %28
store i8 %31, i8* %29
%32 = getelementptr inbounds i8, i8* %1, i64 6
%33 = load i8, i8* %32
%34 = getelementptr inbounds [4 x i8], [4 x i8]* %0, i64 2, i64 1
%35 = load i8, i8* %34
%36 = xor i8 %35, %33
store i8 %36, i8* %34
%37 = getelementptr inbounds i8, i8* %1, i64 7
%38 = load i8, i8* %37
%39 = getelementptr inbounds [4 x i8], [4 x i8]* %0, i64 3, i64 1
%40 = load i8, i8* %39
%41 = xor i8 %40, %38
store i8 %41, i8* %39
%42 = getelementptr inbounds i8, i8* %1, i64 8
%43 = load i8, i8* %42
%44 = getelementptr inbounds [4 x i8], [4 x i8]* %0, i64 0, i64 2
%45 = load i8, i8* %44
%46 = xor i8 %45, %43
store i8 %46, i8* %44
%47 = getelementptr inbounds i8, i8* %1, i64 9
%48 = load i8, i8* %47
%49 = getelementptr inbounds [4 x i8], [4 x i8]* %0, i64 1, i64 2
%50 = load i8, i8* %49
%51 = xor i8 %50, %48
store i8 %51, i8* %49
%52 = getelementptr inbounds i8, i8* %1, i64 10
%53 = load i8, i8* %52
%54 = getelementptr inbounds [4 x i8], [4 x i8]* %0, i64 2, i64 2
%55 = load i8, i8* %54
%56 = xor i8 %55, %53
store i8 %56, i8* %54
%57 = getelementptr inbounds i8, i8* %1, i64 11
%58 = load i8, i8* %57
%59 = getelementptr inbounds [4 x i8], [4 x i8]* %0, i64 3, i64 2
%60 = load i8, i8* %59
%61 = xor i8 %60, %58
store i8 %61, i8* %59
%62 = getelementptr inbounds i8, i8* %1, i64 12
%63 = load i8, i8* %62
%64 = getelementptr inbounds [4 x i8], [4 x i8]* %0, i64 0, i64 3
%65 = load i8, i8* %64
%66 = xor i8 %65, %63
store i8 %66, i8* %64
%67 = getelementptr inbounds i8, i8* %1, i64 13
%68 = load i8, i8* %67
%69 = getelementptr inbounds [4 x i8], [4 x i8]* %0, i64 1, i64 3
%70 = load i8, i8* %69
%71 = xor i8 %70, %68
store i8 %71, i8* %69
%72 = getelementptr inbounds i8, i8* %1, i64 14
%73 = load i8, i8* %72
%74 = getelementptr inbounds [4 x i8], [4 x i8]* %0, i64 2, i64 3
%75 = load i8, i8* %74
%76 = xor i8 %75, %73
store i8 %76, i8* %74
%77 = getelementptr inbounds i8, i8* %1, i64 15
%78 = load i8, i8* %77
%79 = getelementptr inbounds [4 x i8], [4 x i8]* %0, i64 3, i64 3
%80 = load i8, i8* %79
%81 = xor i8 %80, %78
store i8 %81, i8* %79
ret void
}