#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 */
int /*<<< orphan*/ AddRoundKey(unsigned char **, unsigned char *);
int /*<<< orphan*/ InvMixColumns(unsigned char **);
int /*<<< orphan*/ InvShiftRows(unsigned char **);
int /*<<< orphan*/ InvSubBytes(unsigned char **);
int /*<<< orphan*/ KeyExpansion(unsigned char *, unsigned int *, int);
void aes_decrypt(unsigned char in[], unsigned char out[], unsigned char key[],
                 int keysize) {
  short i = 0;
  unsigned char state[4][4];
  state[0][0] = in[0];
  state[1][0] = in[1];
  state[2][0] = in[2];
  state[3][0] = in[3];
  state[0][1] = in[4];
  state[1][1] = in[5];
  state[2][1] = in[6];
  state[3][1] = in[7];
  state[0][2] = in[8];
  state[1][2] = in[9];
  state[2][2] = in[10];
  state[3][2] = in[11];
  state[0][3] = in[12];
  state[1][3] = in[13];
  state[2][3] = in[14];
  state[3][3] = in[15];
  unsigned int w[44];
  KeyExpansion(key, w, 128);
  AddRoundKey(state, (unsigned char *)&w[40]);
  for (i = 9; i > 0; i--) {
    InvShiftRows(state);
    InvSubBytes(state);
    AddRoundKey(state, (unsigned char *)&w[i * 4]);
    InvMixColumns(state);
  }
  InvShiftRows(state);
  InvSubBytes(state);
  AddRoundKey(state, (unsigned char *)&w[0]);
  out[0] = state[0][0];
  out[1] = state[1][0];
  out[2] = state[2][0];
  out[3] = state[3][0];
  out[4] = state[0][1];
  out[5] = state[1][1];
  out[6] = state[2][1];
  out[7] = state[3][1];
  out[8] = state[0][2];
  out[9] = state[1][2];
  out[10] = state[2][2];
  out[11] = state[3][2];
  out[12] = state[0][3];
  out[13] = state[1][3];
  out[14] = state[2][3];
  out[15] = state[3][3];
}


x86 assembly (clang, -O0):
<aes_decrypt>:
push   %rbp
mov    %rsp,%rbp
sub    $0xe0,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %ecx,-0x1c(%rbp)
movw   $0x0,-0x1e(%rbp)
mov    -0x8(%rbp),%rax
mov    (%rax),%al
mov    %al,-0x30(%rbp)
mov    -0x8(%rbp),%rax
mov    0x1(%rax),%al
mov    %al,-0x2c(%rbp)
mov    -0x8(%rbp),%rax
mov    0x2(%rax),%al
mov    %al,-0x28(%rbp)
mov    -0x8(%rbp),%rax
mov    0x3(%rax),%al
mov    %al,-0x24(%rbp)
mov    -0x8(%rbp),%rax
mov    0x4(%rax),%al
mov    %al,-0x2f(%rbp)
mov    -0x8(%rbp),%rax
mov    0x5(%rax),%al
mov    %al,-0x2b(%rbp)
mov    -0x8(%rbp),%rax
mov    0x6(%rax),%al
mov    %al,-0x27(%rbp)
mov    -0x8(%rbp),%rax
mov    0x7(%rax),%al
mov    %al,-0x23(%rbp)
mov    -0x8(%rbp),%rax
mov    0x8(%rax),%al
mov    %al,-0x2e(%rbp)
mov    -0x8(%rbp),%rax
mov    0x9(%rax),%al
mov    %al,-0x2a(%rbp)
mov    -0x8(%rbp),%rax
mov    0xa(%rax),%al
mov    %al,-0x26(%rbp)
mov    -0x8(%rbp),%rax
mov    0xb(%rax),%al
mov    %al,-0x22(%rbp)
mov    -0x8(%rbp),%rax
mov    0xc(%rax),%al
mov    %al,-0x2d(%rbp)
mov    -0x8(%rbp),%rax
mov    0xd(%rax),%al
mov    %al,-0x29(%rbp)
mov    -0x8(%rbp),%rax
mov    0xe(%rax),%al
mov    %al,-0x25(%rbp)
mov    -0x8(%rbp),%rax
mov    0xf(%rax),%al
mov    %al,-0x21(%rbp)
mov    -0x18(%rbp),%rdi
lea    -0xe0(%rbp),%rsi
mov    $0x80,%edx
call   1070 <KeyExpansion@plt>
lea    -0x30(%rbp),%rdi
lea    -0xe0(%rbp),%rsi
add    $0xa0,%rsi
call   1040 <AddRoundKey@plt>
movw   $0x9,-0x1e(%rbp)
movswl -0x1e(%rbp),%eax
cmp    $0x0,%eax
jle    129a <aes_decrypt+0x14a>
lea    -0x30(%rbp),%rdi
call   1050 <InvShiftRows@plt>
lea    -0x30(%rbp),%rdi
call   1060 <InvSubBytes@plt>
lea    -0x30(%rbp),%rdi
movswl -0x1e(%rbp),%eax
shl    $0x2,%eax
cltq
lea    -0xe0(%rbp),%rsi
shl    $0x2,%rax
add    %rax,%rsi
call   1040 <AddRoundKey@plt>
lea    -0x30(%rbp),%rdi
call   1030 <InvMixColumns@plt>
mov    -0x1e(%rbp),%ax
add    $0xffff,%ax
mov    %ax,-0x1e(%rbp)
jmp    1241 <aes_decrypt+0xf1>
lea    -0x30(%rbp),%rdi
call   1050 <InvShiftRows@plt>
lea    -0x30(%rbp),%rdi
call   1060 <InvSubBytes@plt>
lea    -0x30(%rbp),%rdi
lea    -0xe0(%rbp),%rsi
call   1040 <AddRoundKey@plt>
mov    -0x30(%rbp),%cl
mov    -0x10(%rbp),%rax
mov    %cl,(%rax)
mov    -0x2c(%rbp),%cl
mov    -0x10(%rbp),%rax
mov    %cl,0x1(%rax)
mov    -0x28(%rbp),%cl
mov    -0x10(%rbp),%rax
mov    %cl,0x2(%rax)
mov    -0x24(%rbp),%cl
mov    -0x10(%rbp),%rax
mov    %cl,0x3(%rax)
mov    -0x2f(%rbp),%cl
mov    -0x10(%rbp),%rax
mov    %cl,0x4(%rax)
mov    -0x2b(%rbp),%cl
mov    -0x10(%rbp),%rax
mov    %cl,0x5(%rax)
mov    -0x27(%rbp),%cl
mov    -0x10(%rbp),%rax
mov    %cl,0x6(%rax)
mov    -0x23(%rbp),%cl
mov    -0x10(%rbp),%rax
mov    %cl,0x7(%rax)
mov    -0x2e(%rbp),%cl
mov    -0x10(%rbp),%rax
mov    %cl,0x8(%rax)
mov    -0x2a(%rbp),%cl
mov    -0x10(%rbp),%rax
mov    %cl,0x9(%rax)
mov    -0x26(%rbp),%cl
mov    -0x10(%rbp),%rax
mov    %cl,0xa(%rax)
mov    -0x22(%rbp),%cl
mov    -0x10(%rbp),%rax
mov    %cl,0xb(%rax)
mov    -0x2d(%rbp),%cl
mov    -0x10(%rbp),%rax
mov    %cl,0xc(%rax)
mov    -0x29(%rbp),%cl
mov    -0x10(%rbp),%rax
mov    %cl,0xd(%rax)
mov    -0x25(%rbp),%cl
mov    -0x10(%rbp),%rax
mov    %cl,0xe(%rax)
mov    -0x21(%rbp),%cl
mov    -0x10(%rbp),%rax
mov    %cl,0xf(%rax)
add    $0xe0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<aes_decrypt>:
push   %r15
push   %r14
push   %rbx
sub    $0xc0,%rsp
mov    %rsi,%r15
movdqu (%rdi),%xmm0
pxor   %xmm3,%xmm3
movdqa %xmm0,%xmm1
punpckhbw %xmm3,%xmm1
pshufd $0xe7,%xmm1,%xmm2
pshuflw $0x72,%xmm2,%xmm2
punpcklbw %xmm3,%xmm0
pshufd $0xe7,%xmm0,%xmm3
pshuflw $0x72,%xmm3,%xmm3
punpckldq %xmm2,%xmm3
pshufd $0xe8,%xmm1,%xmm1
pshuflw $0xd8,%xmm1,%xmm1
pshufd $0xe8,%xmm0,%xmm0
pshuflw $0xd8,%xmm0,%xmm0
punpckldq %xmm1,%xmm0
packuswb %xmm3,%xmm0
movdqa %xmm0,(%rsp)
lea    0x10(%rsp),%r14
mov    %rdx,%rdi
mov    %r14,%rsi
mov    $0x80,%edx
call   1070 <KeyExpansion@plt>
lea    0xb0(%rsp),%rsi
mov    %rsp,%rbx
mov    %rbx,%rdi
call   1040 <AddRoundKey@plt>
mov    %rbx,%rdi
call   1050 <InvShiftRows@plt>
mov    %rbx,%rdi
call   1060 <InvSubBytes@plt>
lea    0xa0(%rsp),%rsi
mov    %rbx,%rdi
call   1040 <AddRoundKey@plt>
mov    %rbx,%rdi
call   1030 <InvMixColumns@plt>
mov    %rbx,%rdi
call   1050 <InvShiftRows@plt>
mov    %rbx,%rdi
call   1060 <InvSubBytes@plt>
lea    0x90(%rsp),%rsi
mov    %rbx,%rdi
call   1040 <AddRoundKey@plt>
mov    %rbx,%rdi
call   1030 <InvMixColumns@plt>
mov    %rbx,%rdi
call   1050 <InvShiftRows@plt>
mov    %rbx,%rdi
call   1060 <InvSubBytes@plt>
lea    0x80(%rsp),%rsi
mov    %rbx,%rdi
call   1040 <AddRoundKey@plt>
mov    %rbx,%rdi
call   1030 <InvMixColumns@plt>
mov    %rbx,%rdi
call   1050 <InvShiftRows@plt>
mov    %rbx,%rdi
call   1060 <InvSubBytes@plt>
lea    0x70(%rsp),%rsi
mov    %rbx,%rdi
call   1040 <AddRoundKey@plt>
mov    %rbx,%rdi
call   1030 <InvMixColumns@plt>
mov    %rbx,%rdi
call   1050 <InvShiftRows@plt>
mov    %rbx,%rdi
call   1060 <InvSubBytes@plt>
lea    0x60(%rsp),%rsi
mov    %rbx,%rdi
call   1040 <AddRoundKey@plt>
mov    %rbx,%rdi
call   1030 <InvMixColumns@plt>
mov    %rbx,%rdi
call   1050 <InvShiftRows@plt>
mov    %rbx,%rdi
call   1060 <InvSubBytes@plt>
lea    0x50(%rsp),%rsi
mov    %rbx,%rdi
call   1040 <AddRoundKey@plt>
mov    %rbx,%rdi
call   1030 <InvMixColumns@plt>
mov    %rbx,%rdi
call   1050 <InvShiftRows@plt>
mov    %rbx,%rdi
call   1060 <InvSubBytes@plt>
lea    0x40(%rsp),%rsi
mov    %rbx,%rdi
call   1040 <AddRoundKey@plt>
mov    %rbx,%rdi
call   1030 <InvMixColumns@plt>
mov    %rbx,%rdi
call   1050 <InvShiftRows@plt>
mov    %rbx,%rdi
call   1060 <InvSubBytes@plt>
lea    0x30(%rsp),%rsi
mov    %rbx,%rdi
call   1040 <AddRoundKey@plt>
mov    %rbx,%rdi
call   1030 <InvMixColumns@plt>
mov    %rbx,%rdi
call   1050 <InvShiftRows@plt>
mov    %rbx,%rdi
call   1060 <InvSubBytes@plt>
lea    0x20(%rsp),%rsi
mov    %rbx,%rdi
call   1040 <AddRoundKey@plt>
mov    %rbx,%rdi
call   1030 <InvMixColumns@plt>
mov    %rbx,%rdi
call   1050 <InvShiftRows@plt>
mov    %rbx,%rdi
call   1060 <InvSubBytes@plt>
mov    %rbx,%rdi
mov    %r14,%rsi
call   1040 <AddRoundKey@plt>
movdqa (%rsp),%xmm0
movdqa %xmm0,%xmm1
pxor   %xmm3,%xmm3
punpckhbw %xmm3,%xmm1
pshufd $0xe7,%xmm1,%xmm2
pshuflw $0x72,%xmm2,%xmm2
punpcklbw %xmm3,%xmm0
pshufd $0xe7,%xmm0,%xmm3
pshuflw $0x72,%xmm3,%xmm3
punpckldq %xmm2,%xmm3
pshufd $0xe8,%xmm1,%xmm1
pshuflw $0xd8,%xmm1,%xmm1
pshufd $0xe8,%xmm0,%xmm0
pshuflw $0xd8,%xmm0,%xmm0
punpckldq %xmm1,%xmm0
packuswb %xmm3,%xmm0
movdqu %xmm0,(%r15)
add    $0xc0,%rsp
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
define void @aes_decrypt(i8* %0, i8* %1, i8* %2, i32 %3) {
%5 = alloca i8*
%6 = alloca i8*
%7 = alloca i8*
%8 = alloca i32
%9 = alloca i16
%10 = alloca [4 x [4 x i8]]
%11 = alloca [44 x i32]
store i8* %0, i8** %5
store i8* %1, i8** %6
store i8* %2, i8** %7
store i32 %3, i32* %8
store i16 0, i16* %9
%12 = load i8*, i8** %5
%13 = getelementptr inbounds i8, i8* %12, i64 0
%14 = load i8, i8* %13
%15 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 0
%16 = getelementptr inbounds [4 x i8], [4 x i8]* %15, i64 0, i64 0
store i8 %14, i8* %16
%17 = load i8*, i8** %5
%18 = getelementptr inbounds i8, i8* %17, i64 1
%19 = load i8, i8* %18
%20 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 1
%21 = getelementptr inbounds [4 x i8], [4 x i8]* %20, i64 0, i64 0
store i8 %19, i8* %21
%22 = load i8*, i8** %5
%23 = getelementptr inbounds i8, i8* %22, i64 2
%24 = load i8, i8* %23
%25 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 2
%26 = getelementptr inbounds [4 x i8], [4 x i8]* %25, i64 0, i64 0
store i8 %24, i8* %26
%27 = load i8*, i8** %5
%28 = getelementptr inbounds i8, i8* %27, i64 3
%29 = load i8, i8* %28
%30 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 3
%31 = getelementptr inbounds [4 x i8], [4 x i8]* %30, i64 0, i64 0
store i8 %29, i8* %31
%32 = load i8*, i8** %5
%33 = getelementptr inbounds i8, i8* %32, i64 4
%34 = load i8, i8* %33
%35 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 0
%36 = getelementptr inbounds [4 x i8], [4 x i8]* %35, i64 0, i64 1
store i8 %34, i8* %36
%37 = load i8*, i8** %5
%38 = getelementptr inbounds i8, i8* %37, i64 5
%39 = load i8, i8* %38
%40 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 1
%41 = getelementptr inbounds [4 x i8], [4 x i8]* %40, i64 0, i64 1
store i8 %39, i8* %41
%42 = load i8*, i8** %5
%43 = getelementptr inbounds i8, i8* %42, i64 6
%44 = load i8, i8* %43
%45 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 2
%46 = getelementptr inbounds [4 x i8], [4 x i8]* %45, i64 0, i64 1
store i8 %44, i8* %46
%47 = load i8*, i8** %5
%48 = getelementptr inbounds i8, i8* %47, i64 7
%49 = load i8, i8* %48
%50 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 3
%51 = getelementptr inbounds [4 x i8], [4 x i8]* %50, i64 0, i64 1
store i8 %49, i8* %51
%52 = load i8*, i8** %5
%53 = getelementptr inbounds i8, i8* %52, i64 8
%54 = load i8, i8* %53
%55 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 0
%56 = getelementptr inbounds [4 x i8], [4 x i8]* %55, i64 0, i64 2
store i8 %54, i8* %56
%57 = load i8*, i8** %5
%58 = getelementptr inbounds i8, i8* %57, i64 9
%59 = load i8, i8* %58
%60 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 1
%61 = getelementptr inbounds [4 x i8], [4 x i8]* %60, i64 0, i64 2
store i8 %59, i8* %61
%62 = load i8*, i8** %5
%63 = getelementptr inbounds i8, i8* %62, i64 10
%64 = load i8, i8* %63
%65 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 2
%66 = getelementptr inbounds [4 x i8], [4 x i8]* %65, i64 0, i64 2
store i8 %64, i8* %66
%67 = load i8*, i8** %5
%68 = getelementptr inbounds i8, i8* %67, i64 11
%69 = load i8, i8* %68
%70 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 3
%71 = getelementptr inbounds [4 x i8], [4 x i8]* %70, i64 0, i64 2
store i8 %69, i8* %71
%72 = load i8*, i8** %5
%73 = getelementptr inbounds i8, i8* %72, i64 12
%74 = load i8, i8* %73
%75 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 0
%76 = getelementptr inbounds [4 x i8], [4 x i8]* %75, i64 0, i64 3
store i8 %74, i8* %76
%77 = load i8*, i8** %5
%78 = getelementptr inbounds i8, i8* %77, i64 13
%79 = load i8, i8* %78
%80 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 1
%81 = getelementptr inbounds [4 x i8], [4 x i8]* %80, i64 0, i64 3
store i8 %79, i8* %81
%82 = load i8*, i8** %5
%83 = getelementptr inbounds i8, i8* %82, i64 14
%84 = load i8, i8* %83
%85 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 2
%86 = getelementptr inbounds [4 x i8], [4 x i8]* %85, i64 0, i64 3
store i8 %84, i8* %86
%87 = load i8*, i8** %5
%88 = getelementptr inbounds i8, i8* %87, i64 15
%89 = load i8, i8* %88
%90 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 3
%91 = getelementptr inbounds [4 x i8], [4 x i8]* %90, i64 0, i64 3
store i8 %89, i8* %91
%92 = load i8*, i8** %7
%93 = getelementptr inbounds [44 x i32], [44 x i32]* %11, i64 0, i64 0
%94 = call i32 @KeyExpansion(i8* %92, i32* %93, i32 128)
%95 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 0
%96 = bitcast [4 x i8]* %95 to i8**
%97 = getelementptr inbounds [44 x i32], [44 x i32]* %11, i64 0, i64 40
%98 = bitcast i32* %97 to i8*
%99 = call i32 @AddRoundKey(i8** %96, i8* %98)
store i16 9, i16* %9
br label %100
100: ; preds = %123, %4
%101 = load i16, i16* %9
%102 = sext i16 %101 to i32
%103 = icmp sgt i32 %102, 0
br i1 %103, label %104, label %126
104: ; preds = %100
%105 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 0
%106 = bitcast [4 x i8]* %105 to i8**
%107 = call i32 @InvShiftRows(i8** %106)
%108 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 0
%109 = bitcast [4 x i8]* %108 to i8**
%110 = call i32 @InvSubBytes(i8** %109)
%111 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 0
%112 = bitcast [4 x i8]* %111 to i8**
%113 = load i16, i16* %9
%114 = sext i16 %113 to i32
%115 = mul nsw i32 %114, 4
%116 = sext i32 %115 to i64
%117 = getelementptr inbounds [44 x i32], [44 x i32]* %11, i64 0, i64 %116
%118 = bitcast i32* %117 to i8*
%119 = call i32 @AddRoundKey(i8** %112, i8* %118)
%120 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 0
%121 = bitcast [4 x i8]* %120 to i8**
%122 = call i32 @InvMixColumns(i8** %121)
br label %123
123: ; preds = %104
%124 = load i16, i16* %9
%125 = add i16 %124, -1
store i16 %125, i16* %9
br label %100
126: ; preds = %100
%127 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 0
%128 = bitcast [4 x i8]* %127 to i8**
%129 = call i32 @InvShiftRows(i8** %128)
%130 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 0
%131 = bitcast [4 x i8]* %130 to i8**
%132 = call i32 @InvSubBytes(i8** %131)
%133 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 0
%134 = bitcast [4 x i8]* %133 to i8**
%135 = getelementptr inbounds [44 x i32], [44 x i32]* %11, i64 0, i64 0
%136 = bitcast i32* %135 to i8*
%137 = call i32 @AddRoundKey(i8** %134, i8* %136)
%138 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 0
%139 = getelementptr inbounds [4 x i8], [4 x i8]* %138, i64 0, i64 0
%140 = load i8, i8* %139
%141 = load i8*, i8** %6
%142 = getelementptr inbounds i8, i8* %141, i64 0
store i8 %140, i8* %142
%143 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 1
%144 = getelementptr inbounds [4 x i8], [4 x i8]* %143, i64 0, i64 0
%145 = load i8, i8* %144
%146 = load i8*, i8** %6
%147 = getelementptr inbounds i8, i8* %146, i64 1
store i8 %145, i8* %147
%148 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 2
%149 = getelementptr inbounds [4 x i8], [4 x i8]* %148, i64 0, i64 0
%150 = load i8, i8* %149
%151 = load i8*, i8** %6
%152 = getelementptr inbounds i8, i8* %151, i64 2
store i8 %150, i8* %152
%153 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 3
%154 = getelementptr inbounds [4 x i8], [4 x i8]* %153, i64 0, i64 0
%155 = load i8, i8* %154
%156 = load i8*, i8** %6
%157 = getelementptr inbounds i8, i8* %156, i64 3
store i8 %155, i8* %157
%158 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 0
%159 = getelementptr inbounds [4 x i8], [4 x i8]* %158, i64 0, i64 1
%160 = load i8, i8* %159
%161 = load i8*, i8** %6
%162 = getelementptr inbounds i8, i8* %161, i64 4
store i8 %160, i8* %162
%163 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 1
%164 = getelementptr inbounds [4 x i8], [4 x i8]* %163, i64 0, i64 1
%165 = load i8, i8* %164
%166 = load i8*, i8** %6
%167 = getelementptr inbounds i8, i8* %166, i64 5
store i8 %165, i8* %167
%168 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 2
%169 = getelementptr inbounds [4 x i8], [4 x i8]* %168, i64 0, i64 1
%170 = load i8, i8* %169
%171 = load i8*, i8** %6
%172 = getelementptr inbounds i8, i8* %171, i64 6
store i8 %170, i8* %172
%173 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 3
%174 = getelementptr inbounds [4 x i8], [4 x i8]* %173, i64 0, i64 1
%175 = load i8, i8* %174
%176 = load i8*, i8** %6
%177 = getelementptr inbounds i8, i8* %176, i64 7
store i8 %175, i8* %177
%178 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 0
%179 = getelementptr inbounds [4 x i8], [4 x i8]* %178, i64 0, i64 2
%180 = load i8, i8* %179
%181 = load i8*, i8** %6
%182 = getelementptr inbounds i8, i8* %181, i64 8
store i8 %180, i8* %182
%183 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 1
%184 = getelementptr inbounds [4 x i8], [4 x i8]* %183, i64 0, i64 2
%185 = load i8, i8* %184
%186 = load i8*, i8** %6
%187 = getelementptr inbounds i8, i8* %186, i64 9
store i8 %185, i8* %187
%188 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 2
%189 = getelementptr inbounds [4 x i8], [4 x i8]* %188, i64 0, i64 2
%190 = load i8, i8* %189
%191 = load i8*, i8** %6
%192 = getelementptr inbounds i8, i8* %191, i64 10
store i8 %190, i8* %192
%193 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 3
%194 = getelementptr inbounds [4 x i8], [4 x i8]* %193, i64 0, i64 2
%195 = load i8, i8* %194
%196 = load i8*, i8** %6
%197 = getelementptr inbounds i8, i8* %196, i64 11
store i8 %195, i8* %197
%198 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 0
%199 = getelementptr inbounds [4 x i8], [4 x i8]* %198, i64 0, i64 3
%200 = load i8, i8* %199
%201 = load i8*, i8** %6
%202 = getelementptr inbounds i8, i8* %201, i64 12
store i8 %200, i8* %202
%203 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 1
%204 = getelementptr inbounds [4 x i8], [4 x i8]* %203, i64 0, i64 3
%205 = load i8, i8* %204
%206 = load i8*, i8** %6
%207 = getelementptr inbounds i8, i8* %206, i64 13
store i8 %205, i8* %207
%208 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 2
%209 = getelementptr inbounds [4 x i8], [4 x i8]* %208, i64 0, i64 3
%210 = load i8, i8* %209
%211 = load i8*, i8** %6
%212 = getelementptr inbounds i8, i8* %211, i64 14
store i8 %210, i8* %212
%213 = getelementptr inbounds [4 x [4 x i8]], [4 x [4 x i8]]* %10, i64 0, i64 3
%214 = getelementptr inbounds [4 x i8], [4 x i8]* %213, i64 0, i64 3
%215 = load i8, i8* %214
%216 = load i8*, i8** %6
%217 = getelementptr inbounds i8, i8* %216, i64 15
store i8 %215, i8* %217
ret void
}

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