#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 */
typedef int uint8_t;

/* Variables and functions */
void mix_columns(uint8_t *state) {
  uint8_t a[4];
  uint8_t b[4];
  uint8_t h;
  for (uint8_t k = 0; k < 4; k++) {
    for (uint8_t i = 0; i < 4; i++) {
      a[i] = state[i + 4 * k];
      h = state[i + 4 * k] & 0x80;
      b[i] = state[i + 4 * k] << 1;
      if (h == 0x80) {
        b[i] ^= 0x1b;
      }
    }
    state[4 * k] = b[0] ^ a[3] ^ a[2] ^ b[1] ^ a[1];
    state[1 + 4 * k] = b[1] ^ a[0] ^ a[3] ^ b[2] ^ a[2];
    state[2 + 4 * k] = b[2] ^ a[1] ^ a[0] ^ b[3] ^ a[3];
    state[3 + 4 * k] = b[3] ^ a[2] ^ a[1] ^ b[0] ^ a[0];
  }
}


x86 assembly (clang, -O0):
<mix_columns>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
movl   $0x0,-0x38(%rbp)
cmpl   $0x4,-0x38(%rbp)
jge    1246 <mix_columns+0x146>
movl   $0x0,-0x3c(%rbp)
cmpl   $0x4,-0x3c(%rbp)
jge    11b3 <mix_columns+0xb3>
mov    -0x8(%rbp),%rax
mov    -0x3c(%rbp),%ecx
mov    -0x38(%rbp),%edx
shl    $0x2,%edx
add    %edx,%ecx
movslq %ecx,%rcx
mov    (%rax,%rcx,4),%ecx
movslq -0x3c(%rbp),%rax
mov    %ecx,-0x20(%rbp,%rax,4)
mov    -0x8(%rbp),%rax
mov    -0x3c(%rbp),%ecx
mov    -0x38(%rbp),%edx
shl    $0x2,%edx
add    %edx,%ecx
movslq %ecx,%rcx
mov    (%rax,%rcx,4),%eax
and    $0x80,%eax
mov    %eax,-0x34(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x3c(%rbp),%ecx
mov    -0x38(%rbp),%edx
shl    $0x2,%edx
add    %edx,%ecx
movslq %ecx,%rcx
mov    (%rax,%rcx,4),%ecx
shl    $0x1,%ecx
movslq -0x3c(%rbp),%rax
mov    %ecx,-0x30(%rbp,%rax,4)
cmpl   $0x80,-0x34(%rbp)
jne    11a0 <mix_columns+0xa0>
movslq -0x3c(%rbp),%rax
mov    -0x30(%rbp,%rax,4),%ecx
xor    $0x1b,%ecx
mov    %ecx,-0x30(%rbp,%rax,4)
jmp    11a5 <mix_columns+0xa5>
mov    -0x3c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x3c(%rbp)
jmp    1120 <mix_columns+0x20>
mov    -0x30(%rbp),%edx
xor    -0x14(%rbp),%edx
xor    -0x18(%rbp),%edx
xor    -0x2c(%rbp),%edx
xor    -0x1c(%rbp),%edx
mov    -0x8(%rbp),%rax
mov    -0x38(%rbp),%ecx
shl    $0x2,%ecx
movslq %ecx,%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x2c(%rbp),%edx
xor    -0x20(%rbp),%edx
xor    -0x14(%rbp),%edx
xor    -0x28(%rbp),%edx
xor    -0x18(%rbp),%edx
mov    -0x8(%rbp),%rax
mov    -0x38(%rbp),%ecx
shl    $0x2,%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x28(%rbp),%edx
xor    -0x1c(%rbp),%edx
xor    -0x20(%rbp),%edx
xor    -0x24(%rbp),%edx
xor    -0x14(%rbp),%edx
mov    -0x8(%rbp),%rax
mov    -0x38(%rbp),%ecx
shl    $0x2,%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x24(%rbp),%edx
xor    -0x18(%rbp),%edx
xor    -0x1c(%rbp),%edx
xor    -0x30(%rbp),%edx
xor    -0x20(%rbp),%edx
mov    -0x8(%rbp),%rax
mov    -0x38(%rbp),%ecx
shl    $0x2,%ecx
add    $0x3,%ecx
movslq %ecx,%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x38(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x38(%rbp)
jmp    110f <mix_columns+0xf>
pop    %rbp
ret

x86 assembly (clang, -O2):
<mix_columns>:
movups (%rdi),%xmm5
movups 0x10(%rdi),%xmm9
movups 0x20(%rdi),%xmm1
movups 0x30(%rdi),%xmm7
movaps %xmm1,%xmm4
unpcklps %xmm7,%xmm4
movaps %xmm5,%xmm0
movss  0x14(%rdi),%xmm8
shufps $0xd4,%xmm5,%xmm8
movss  0x18(%rdi),%xmm12
shufps $0xe4,%xmm5,%xmm12
movss  0x1c(%rdi),%xmm3
shufps $0xf4,%xmm5,%xmm3
unpcklps %xmm9,%xmm5
movaps %xmm5,%xmm6
movlhps %xmm4,%xmm6
unpckhpd %xmm4,%xmm5
unpckhps %xmm7,%xmm1
unpckhps %xmm9,%xmm0
movaps %xmm0,%xmm11
movlhps %xmm1,%xmm11
unpckhpd %xmm1,%xmm0
movss  0x24(%rdi),%xmm1
movss  0x34(%rdi),%xmm7
movlhps %xmm1,%xmm7
shufps $0x22,%xmm7,%xmm8
movss  0x28(%rdi),%xmm1
movss  0x38(%rdi),%xmm7
movlhps %xmm1,%xmm7
shufps $0x22,%xmm7,%xmm12
movss  0x2c(%rdi),%xmm1
movss  0x3c(%rdi),%xmm7
movlhps %xmm1,%xmm7
shufps $0x22,%xmm7,%xmm3
movaps %xmm6,%xmm10
movaps %xmm12,%xmm1
xorps  %xmm3,%xmm1
movaps %xmm1,%xmm9
xorps  %xmm6,%xmm1
xorps  %xmm8,%xmm3
xorps  %xmm6,%xmm3
xorps  %xmm8,%xmm12
xorps  %xmm6,%xmm12
paddd  %xmm6,%xmm6
movdqa 0xe45(%rip),%xmm7
pslld  $0x18,%xmm10
psrad  $0x1f,%xmm10
movdqa %xmm10,%xmm4
pandn  %xmm6,%xmm4
pxor   %xmm7,%xmm6
pand   %xmm10,%xmm6
por    %xmm4,%xmm6
movaps %xmm5,%xmm4
paddd  %xmm5,%xmm4
pslld  $0x18,%xmm5
psrad  $0x1f,%xmm5
movdqa %xmm5,%xmm2
pandn  %xmm4,%xmm2
pxor   %xmm7,%xmm4
pand   %xmm5,%xmm4
por    %xmm2,%xmm4
movaps %xmm11,%xmm2
paddd  %xmm11,%xmm2
pslld  $0x18,%xmm11
psrad  $0x1f,%xmm11
movdqa %xmm11,%xmm5
pandn  %xmm2,%xmm5
pxor   %xmm7,%xmm2
pand   %xmm11,%xmm2
por    %xmm5,%xmm2
movaps %xmm0,%xmm5
paddd  %xmm0,%xmm5
pxor   %xmm5,%xmm7
pslld  $0x18,%xmm0
psrad  $0x1f,%xmm0
pand   %xmm0,%xmm7
pandn  %xmm5,%xmm0
por    %xmm7,%xmm0
xorps  %xmm6,%xmm9
xorps  %xmm4,%xmm1
xorps  %xmm8,%xmm4
xorps  %xmm9,%xmm4
xorps  %xmm2,%xmm1
xorps  %xmm2,%xmm3
xorps  %xmm0,%xmm3
xorps  %xmm6,%xmm12
xorps  %xmm0,%xmm12
movaps %xmm4,%xmm0
unpcklps %xmm1,%xmm0
movaps %xmm3,%xmm2
unpcklps %xmm12,%xmm2
movaps %xmm0,%xmm5
unpckhpd %xmm2,%xmm5
movlhps %xmm2,%xmm0
unpckhps %xmm1,%xmm4
unpckhps %xmm12,%xmm3
movaps %xmm4,%xmm1
unpckhpd %xmm3,%xmm1
movlhps %xmm3,%xmm4
movups %xmm4,0x20(%rdi)
movups %xmm1,0x30(%rdi)
movups %xmm0,(%rdi)
movups %xmm5,0x10(%rdi)
ret

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

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