void theta(unsigned short *A) {
  unsigned int x, y;
  unsigned short C[5], D[5];
  for (x = 0; x < 5; x++) {
    C[x] = 0;
    for (y = 0; y < 5; y++)
      C[x] ^= A[(((x) % 5) + 5 * ((y) % 5))];
  }
  for (x = 0; x < 5; x++)
    D[x] = ((1 != 0) ? ((((unsigned short)C[(x + 1) % 5]) << 1) ^
                        (((unsigned short)C[(x + 1) % 5]) >>
                         (sizeof(unsigned short) * 8 - 1)))
                     : C[(x + 1) % 5]) ^
           C[(x + 4) % 5];
  for (x = 0; x < 5; x++)
    for (y = 0; y < 5; y++)
      A[(((x) % 5) + 5 * ((y) % 5))] ^= D[x];
}


x86 assembly (clang, -O0):
<theta>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
movl   $0x0,-0xc(%rbp)
cmpl   $0x5,-0xc(%rbp)
jae    119b <theta+0x9b>
mov    -0xc(%rbp),%eax
movw   $0x0,-0x1a(%rbp,%rax,2)
movl   $0x0,-0x10(%rbp)
cmpl   $0x5,-0x10(%rbp)
jae    1188 <theta+0x88>
mov    -0x8(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0xc(%rbp),%eax
mov    $0x5,%ecx
xor    %edx,%edx
div    %ecx
mov    %edx,-0x28(%rbp)
mov    -0x10(%rbp),%eax
mov    $0x5,%ecx
xor    %edx,%edx
div    %ecx
mov    -0x30(%rbp),%rax
mov    %edx,%ecx
mov    -0x28(%rbp),%edx
imul   $0x5,%ecx,%ecx
add    %ecx,%edx
mov    %edx,%ecx
movzwl (%rax,%rcx,2),%edx
mov    -0xc(%rbp),%eax
movzwl -0x1a(%rbp,%rax,2),%ecx
xor    %edx,%ecx
mov    %cx,-0x1a(%rbp,%rax,2)
mov    -0x10(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x10(%rbp)
jmp    112a <theta+0x2a>
jmp    118d <theta+0x8d>
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    110f <theta+0xf>
movl   $0x0,-0xc(%rbp)
cmpl   $0x5,-0xc(%rbp)
jae    121d <theta+0x11d>
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    $0x5,%ecx
xor    %edx,%edx
div    %ecx
mov    %edx,%eax
movzwl -0x1a(%rbp,%rax,2),%eax
shl    $0x1,%eax
mov    %eax,-0x38(%rbp)
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    $0x5,%ecx
xor    %edx,%edx
div    %ecx
mov    -0x38(%rbp),%eax
mov    %edx,%ecx
movzwl -0x1a(%rbp,%rcx,2),%ecx
sar    $0xf,%ecx
xor    %ecx,%eax
mov    %eax,-0x34(%rbp)
mov    -0xc(%rbp),%eax
add    $0x4,%eax
mov    $0x5,%ecx
xor    %edx,%edx
div    %ecx
mov    -0x34(%rbp),%eax
mov    %edx,%ecx
movzwl -0x1a(%rbp,%rcx,2),%ecx
xor    %ecx,%eax
mov    %ax,%cx
mov    -0xc(%rbp),%eax
mov    %cx,-0x24(%rbp,%rax,2)
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    11a2 <theta+0xa2>
movl   $0x0,-0xc(%rbp)
cmpl   $0x5,-0xc(%rbp)
jae    12a5 <theta+0x1a5>
movl   $0x0,-0x10(%rbp)
cmpl   $0x5,-0x10(%rbp)
jae    1292 <theta+0x192>
mov    -0xc(%rbp),%eax
movzwl -0x24(%rbp,%rax,2),%esi
mov    -0x8(%rbp),%rax
mov    %rax,-0x48(%rbp)
mov    -0xc(%rbp),%eax
mov    $0x5,%ecx
xor    %edx,%edx
div    %ecx
mov    %edx,-0x3c(%rbp)
mov    -0x10(%rbp),%eax
mov    $0x5,%ecx
xor    %edx,%edx
div    %ecx
mov    -0x48(%rbp),%rax
mov    %edx,%ecx
mov    -0x3c(%rbp),%edx
imul   $0x5,%ecx,%ecx
add    %ecx,%edx
mov    %edx,%ecx
movzwl (%rax,%rcx,2),%edx
xor    %esi,%edx
mov    %dx,(%rax,%rcx,2)
mov    -0x10(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x10(%rbp)
jmp    1235 <theta+0x135>
jmp    1297 <theta+0x197>
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    1224 <theta+0x124>
pop    %rbp
ret

x86 assembly (clang, -O2):
<theta>:
movdqu (%rdi),%xmm2
movdqu 0x10(%rdi),%xmm1
movdqu 0x20(%rdi),%xmm0
pextrw $0x4,%xmm0,%edx
pextrw $0x1,%xmm2,%eax
pextrw $0x6,%xmm2,%ecx
xor    %eax,%ecx
pextrw $0x3,%xmm1,%eax
movd   %xmm0,%esi
xor    %eax,%esi
xor    %ecx,%esi
pextrw $0x5,%xmm0,%ecx
xor    %esi,%ecx
movdqa %xmm1,%xmm3
punpcklwd %xmm2,%xmm3
pshufd $0x6c,%xmm3,%xmm3
pshufhw $0xe6,%xmm3,%xmm3
pshufd $0xe8,%xmm3,%xmm3
pshuflw $0x63,%xmm3,%xmm3
pshufd $0x27,%xmm2,%xmm4
pshuflw $0xe7,%xmm4,%xmm4
pshufd $0xe8,%xmm4,%xmm4
pshuflw $0xe1,%xmm4,%xmm4
pshufd $0x27,%xmm1,%xmm5
pshuflw $0xe8,%xmm5,%xmm5
pshufd $0xe2,%xmm5,%xmm5
pxor   %xmm4,%xmm5
pxor   %xmm3,%xmm5
pshufd $0xee,%xmm1,%xmm3
movdqa %xmm0,%xmm4
punpcklwd %xmm3,%xmm4
pshufd $0xc6,%xmm4,%xmm3
pshuflw $0xe8,%xmm3,%xmm3
pshufd $0xec,%xmm3,%xmm3
pshuflw $0xe1,%xmm3,%xmm3
pxor   %xmm5,%xmm3
movzwl 0x30(%rdi),%eax
pshufd $0xff,%xmm0,%xmm4
pinsrw $0x2,%eax,%xmm4
pinsrw $0x3,%edx,%xmm4
pxor   %xmm3,%xmm4
pextrw $0x3,%xmm4,%edx
movd   %edx,%xmm3
pinsrw $0x1,%ecx,%xmm3
mov    %ecx,%edx
rol    %dx
pextrw $0x2,%xmm4,%ecx
movdqa %xmm4,%xmm5
psrlw  $0xf,%xmm5
movdqa %xmm4,%xmm6
psllw  $0x1,%xmm6
por    %xmm5,%xmm6
xor    %edx,%ecx
shufps $0xe4,%xmm4,%xmm6
punpckldq %xmm4,%xmm3
pxor   %xmm6,%xmm3
movd   %ecx,%xmm4
movdqa %xmm3,%xmm5
punpcklwd %xmm4,%xmm5
pshufd $0x6c,%xmm5,%xmm4
pshufhw $0x27,%xmm4,%xmm4
pshufd $0xd8,%xmm4,%xmm4
pshufhw $0xe8,%xmm4,%xmm4
pshufd $0x2c,%xmm4,%xmm4
pshuflw $0xe1,%xmm4,%xmm4
pshufhw $0x6c,%xmm4,%xmm4
pextrw $0x3,%xmm3,%edx
pxor   %xmm2,%xmm4
pshufd $0x55,%xmm3,%xmm2
pinsrw $0x2,%ecx,%xmm2
movdqu %xmm4,(%rdi)
punpcklwd %xmm3,%xmm2
pshufd $0x6c,%xmm2,%xmm2
pshufhw $0x27,%xmm2,%xmm2
pshufd $0xd8,%xmm2,%xmm2
pshuflw $0x24,%xmm2,%xmm2
pshufd $0xdc,%xmm2,%xmm2
pshuflw $0x78,%xmm2,%xmm2
pxor   %xmm1,%xmm2
movdqu %xmm2,0x10(%rdi)
pinsrw $0x4,%ecx,%xmm3
pshufd $0x6c,%xmm3,%xmm1
pshufhw $0xe8,%xmm1,%xmm1
pshufd $0x2c,%xmm1,%xmm1
pshufhw $0x78,%xmm1,%xmm1
pxor   %xmm0,%xmm1
movdqu %xmm1,0x20(%rdi)
xor    %eax,%edx
mov    %dx,0x30(%rdi)
ret

LLVM IR (-O0):
define void @theta(i16* %0) {
%2 = alloca i16*
%3 = alloca i32
%4 = alloca i32
%5 = alloca [5 x i16]
%6 = alloca [5 x i16]
store i16* %0, i16** %2
store i32 0, i32* %3
br label %7
7: ; preds = %40, %1
%8 = load i32, i32* %3
%9 = icmp ult i32 %8, 5
br i1 %9, label %10, label %43
10: ; preds = %7
%11 = load i32, i32* %3
%12 = zext i32 %11 to i64
%13 = getelementptr inbounds [5 x i16], [5 x i16]* %5, i64 0, i64 %12
store i16 0, i16* %13
store i32 0, i32* %4
br label %14
14: ; preds = %36, %10
%15 = load i32, i32* %4
%16 = icmp ult i32 %15, 5
br i1 %16, label %17, label %39
17: ; preds = %14
%18 = load i16*, i16** %2
%19 = load i32, i32* %3
%20 = urem i32 %19, 5
%21 = load i32, i32* %4
%22 = urem i32 %21, 5
%23 = mul i32 5, %22
%24 = add i32 %20, %23
%25 = zext i32 %24 to i64
%26 = getelementptr inbounds i16, i16* %18, i64 %25
%27 = load i16, i16* %26
%28 = zext i16 %27 to i32
%29 = load i32, i32* %3
%30 = zext i32 %29 to i64
%31 = getelementptr inbounds [5 x i16], [5 x i16]* %5, i64 0, i64 %30
%32 = load i16, i16* %31
%33 = zext i16 %32 to i32
%34 = xor i32 %33, %28
%35 = trunc i32 %34 to i16
store i16 %35, i16* %31
br label %36
36: ; preds = %17
%37 = load i32, i32* %4
%38 = add i32 %37, 1
store i32 %38, i32* %4
br label %14
39: ; preds = %14
br label %40
40: ; preds = %39
%41 = load i32, i32* %3
%42 = add i32 %41, 1
store i32 %42, i32* %3
br label %7
43: ; preds = %7
store i32 0, i32* %3
br label %44
44: ; preds = %77, %43
%45 = load i32, i32* %3
%46 = icmp ult i32 %45, 5
br i1 %46, label %47, label %80
47: ; preds = %44
%48 = load i32, i32* %3
%49 = add i32 %48, 1
%50 = urem i32 %49, 5
%51 = zext i32 %50 to i64
%52 = getelementptr inbounds [5 x i16], [5 x i16]* %5, i64 0, i64 %51
%53 = load i16, i16* %52
%54 = zext i16 %53 to i32
%55 = shl i32 %54, 1
%56 = load i32, i32* %3
%57 = add i32 %56, 1
%58 = urem i32 %57, 5
%59 = zext i32 %58 to i64
%60 = getelementptr inbounds [5 x i16], [5 x i16]* %5, i64 0, i64 %59
%61 = load i16, i16* %60
%62 = zext i16 %61 to i32
%63 = ashr i32 %62, 15
%64 = xor i32 %55, %63
%65 = load i32, i32* %3
%66 = add i32 %65, 4
%67 = urem i32 %66, 5
%68 = zext i32 %67 to i64
%69 = getelementptr inbounds [5 x i16], [5 x i16]* %5, i64 0, i64 %68
%70 = load i16, i16* %69
%71 = zext i16 %70 to i32
%72 = xor i32 %64, %71
%73 = trunc i32 %72 to i16
%74 = load i32, i32* %3
%75 = zext i32 %74 to i64
%76 = getelementptr inbounds [5 x i16], [5 x i16]* %6, i64 0, i64 %75
store i16 %73, i16* %76
br label %77
77: ; preds = %47
%78 = load i32, i32* %3
%79 = add i32 %78, 1
store i32 %79, i32* %3
br label %44
80: ; preds = %44
store i32 0, i32* %3
br label %81
81: ; preds = %111, %80
%82 = load i32, i32* %3
%83 = icmp ult i32 %82, 5
br i1 %83, label %84, label %114
84: ; preds = %81
store i32 0, i32* %4
br label %85
85: ; preds = %107, %84
%86 = load i32, i32* %4
%87 = icmp ult i32 %86, 5
br i1 %87, label %88, label %110
88: ; preds = %85
%89 = load i32, i32* %3
%90 = zext i32 %89 to i64
%91 = getelementptr inbounds [5 x i16], [5 x i16]* %6, i64 0, i64 %90
%92 = load i16, i16* %91
%93 = zext i16 %92 to i32
%94 = load i16*, i16** %2
%95 = load i32, i32* %3
%96 = urem i32 %95, 5
%97 = load i32, i32* %4
%98 = urem i32 %97, 5
%99 = mul i32 5, %98
%100 = add i32 %96, %99
%101 = zext i32 %100 to i64
%102 = getelementptr inbounds i16, i16* %94, i64 %101
%103 = load i16, i16* %102
%104 = zext i16 %103 to i32
%105 = xor i32 %104, %93
%106 = trunc i32 %105 to i16
store i16 %106, i16* %102
br label %107
107: ; preds = %88
%108 = load i32, i32* %4
%109 = add i32 %108, 1
store i32 %109, i32* %4
br label %85
110: ; preds = %85
br label %111
111: ; preds = %110
%112 = load i32, i32* %3
%113 = add i32 %112, 1
store i32 %113, i32* %3
br label %81
114: ; preds = %81
ret void
}

LLVM IR (-O2):
define void @theta(i16* nocapture %0) {
%2 = bitcast i16* %0 to <8 x i16>*
%3 = load <8 x i16>, <8 x i16>* %2
%4 = getelementptr inbounds i16, i16* %0, i64 8
%5 = bitcast i16* %4 to <8 x i16>*
%6 = load <8 x i16>, <8 x i16>* %5
%7 = getelementptr inbounds i16, i16* %0, i64 16
%8 = bitcast i16* %7 to <8 x i16>*
%9 = load <8 x i16>, <8 x i16>* %8
%10 = extractelement <8 x i16> %9, i64 4
%11 = extractelement <8 x i16> %3, i64 1
%12 = extractelement <8 x i16> %3, i64 6
%13 = xor i16 %11, %12
%14 = extractelement <8 x i16> %6, i64 3
%15 = xor i16 %13, %14
%16 = extractelement <8 x i16> %9, i64 0
%17 = xor i16 %15, %16
%18 = extractelement <8 x i16> %9, i64 5
%19 = xor i16 %17, %18
%20 = extractelement <8 x i16> %9, i64 6
%21 = extractelement <8 x i16> %9, i64 7
%22 = shufflevector <8 x i16> %6, <8 x i16> %3, <4 x i32> <i32 10, i32 0, i32 1, i32 8>
%23 = shufflevector <8 x i16> %3, <8 x i16> undef, <4 x i32> <i32 7, i32 3, i32 4, i32 5>
%24 = xor <4 x i16> %22, %23
%25 = shufflevector <8 x i16> %6, <8 x i16> undef, <4 x i32> <i32 4, i32 5, i32 6, i32 2>
%26 = xor <4 x i16> %24, %25
%27 = shufflevector <8 x i16> %9, <8 x i16> %6, <4 x i32> <i32 1, i32 2, i32 3, i32 15>
%28 = xor <4 x i16> %26, %27
%29 = getelementptr inbounds i16, i16* %0, i64 24
%30 = load i16, i16* %29
%31 = insertelement <4 x i16> poison, i16 %20, i64 0
%32 = insertelement <4 x i16> %31, i16 %21, i64 1
%33 = insertelement <4 x i16> %32, i16 %30, i64 2
%34 = insertelement <4 x i16> %33, i16 %10, i64 3
%35 = xor <4 x i16> %28, %34
%36 = tail call i16 @llvm.fshl.i16(i16 %19, i16 %19, i16 1)
%37 = extractelement <4 x i16> %35, i64 2
%38 = xor i16 %36, %37
%39 = call <4 x i16> @llvm.fshl.v4i16(<4 x i16> %35, <4 x i16> %35, <4 x i16> <i16 1, i16 1, i16 1, i16 1>)
%40 = extractelement <4 x i16> %35, i64 3
%41 = insertelement <4 x i16> poison, i16 %40, i64 0
%42 = insertelement <4 x i16> %41, i16 %19, i64 1
%43 = shufflevector <4 x i16> %42, <4 x i16> %35, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
%44 = xor <4 x i16> %39, %43
%45 = shufflevector <4 x i16> %44, <4 x i16> poison, <8 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>
%46 = insertelement <8 x i16> poison, i16 %38, i64 0
%47 = shufflevector <4 x i16> %44, <4 x i16> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 undef, i32 undef, i32 undef, i32 undef>
%48 = shufflevector <8 x i16> %46, <8 x i16> %47, <8 x i32> <i32 0, i32 8, i32 9, i32 10, i32 11, i32 undef, i32 undef, i32 undef>
%49 = shufflevector <8 x i16> %48, <8 x i16> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 0, i32 1, i32 2>
%50 = xor <8 x i16> %3, %49
%51 = bitcast i16* %0 to <8 x i16>*
store <8 x i16> %50, <8 x i16>* %51
%52 = extractelement <4 x i16> %44, i64 2
%53 = insertelement <8 x i16> poison, i16 %52, i64 0
%54 = extractelement <4 x i16> %44, i64 3
%55 = insertelement <8 x i16> %53, i16 %54, i64 1
%56 = insertelement <8 x i16> %55, i16 %38, i64 2
%57 = extractelement <4 x i16> %44, i64 0
%58 = extractelement <4 x i16> %44, i64 1
%59 = shufflevector <8 x i16> %56, <8 x i16> %45, <8 x i32> <i32 0, i32 1, i32 2, i32 8, i32 9, i32 undef, i32 undef, i32 undef>
%60 = shufflevector <8 x i16> %59, <8 x i16> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 0, i32 1, i32 2>
%61 = xor <8 x i16> %6, %60
%62 = bitcast i16* %4 to <8 x i16>*
store <8 x i16> %61, <8 x i16>* %62
%63 = insertelement <8 x i16> poison, i16 %57, i64 0
%64 = insertelement <8 x i16> %63, i16 %58, i64 1
%65 = insertelement <8 x i16> %64, i16 %52, i64 2
%66 = insertelement <8 x i16> %65, i16 %54, i64 3
%67 = insertelement <8 x i16> %66, i16 %38, i64 4
%68 = shufflevector <8 x i16> %67, <8 x i16> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 0, i32 1, i32 2>
%69 = xor <8 x i16> %9, %68
%70 = bitcast i16* %7 to <8 x i16>*
store <8 x i16> %69, <8 x i16>* %70
%71 = xor i16 %30, %54
store i16 %71, i16* %29
ret void
}