#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*/ memcpy(unsigned char *, unsigned char const *, unsigned int);
void gf_mul(unsigned char *a, const unsigned char *x, const unsigned char *y) {
  int i;
  int j;
  unsigned int xlen = 16;
  unsigned char abits[128];
  unsigned char ybits[128];
  unsigned char prodbits[256];
  memcpy(a, x, xlen);
  for (i = 0; i < 128; ++i)
    abits[i] = (a[i / 8] >> (7 - (i % 8))) & 1;
  for (i = 0; i < 128; ++i)
    ybits[i] = (y[i / 8] >> (7 - (i % 8))) & 1;
  for (i = 0; i < 256; ++i)
    prodbits[i] = 0;
  for (i = 0; i < 128; ++i)
    for (j = 0; j < 128; ++j)
      prodbits[i + j] ^= abits[i] & ybits[j];
  for (i = 127; i >= 0; --i) {
    prodbits[i] ^= prodbits[i + 128];
    prodbits[i + 1] ^= prodbits[i + 128];
    prodbits[i + 2] ^= prodbits[i + 128];
    prodbits[i + 7] ^= prodbits[i + 128];
    prodbits[i + 128] ^= prodbits[i + 128];
  }
  for (i = 0; i < 16; ++i)
    a[i] = 0;
  for (i = 0; i < 128; ++i)
    a[i / 8] |= (prodbits[i] << (7 - (i % 8)));
}


x86 assembly (clang, -O0):
<gf_mul>:
push   %rbp
mov    %rsp,%rbp
sub    $0x260,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
movl   $0x10,-0x24(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x24(%rbp),%edx
call   1030 <memcpy@plt>
movl   $0x0,-0x1c(%rbp)
cmpl   $0x80,-0x1c(%rbp)
jge    11b6 <gf_mul+0xa6>
mov    -0x8(%rbp),%rax
mov    %rax,-0x240(%rbp)
mov    -0x1c(%rbp),%eax
mov    $0x8,%ecx
cltd
idiv   %ecx
mov    %eax,%ecx
mov    -0x240(%rbp),%rax
movslq %ecx,%rcx
movzbl (%rax,%rcx,1),%eax
mov    %eax,-0x234(%rbp)
mov    -0x1c(%rbp),%eax
mov    $0x8,%ecx
cltd
idiv   %ecx
mov    -0x234(%rbp),%eax
mov    $0x7,%ecx
sub    %edx,%ecx
sar    %cl,%eax
and    $0x1,%eax
mov    %al,%cl
movslq -0x1c(%rbp),%rax
mov    %cl,-0xb0(%rbp,%rax,1)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1145 <gf_mul+0x35>
movl   $0x0,-0x1c(%rbp)
cmpl   $0x80,-0x1c(%rbp)
jge    122e <gf_mul+0x11e>
mov    -0x18(%rbp),%rax
mov    %rax,-0x250(%rbp)
mov    -0x1c(%rbp),%eax
mov    $0x8,%ecx
cltd
idiv   %ecx
mov    %eax,%ecx
mov    -0x250(%rbp),%rax
movslq %ecx,%rcx
movzbl (%rax,%rcx,1),%eax
mov    %eax,-0x244(%rbp)
mov    -0x1c(%rbp),%eax
mov    $0x8,%ecx
cltd
idiv   %ecx
mov    -0x244(%rbp),%eax
mov    $0x7,%ecx
sub    %edx,%ecx
sar    %cl,%eax
and    $0x1,%eax
mov    %al,%cl
movslq -0x1c(%rbp),%rax
mov    %cl,-0x130(%rbp,%rax,1)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    11bd <gf_mul+0xad>
movl   $0x0,-0x1c(%rbp)
cmpl   $0x100,-0x1c(%rbp)
jge    125c <gf_mul+0x14c>
movslq -0x1c(%rbp),%rax
movb   $0x0,-0x230(%rbp,%rax,1)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1235 <gf_mul+0x125>
movl   $0x0,-0x1c(%rbp)
cmpl   $0x80,-0x1c(%rbp)
jge    12d8 <gf_mul+0x1c8>
movl   $0x0,-0x20(%rbp)
cmpl   $0x80,-0x20(%rbp)
jge    12c5 <gf_mul+0x1b5>
movslq -0x1c(%rbp),%rax
movzbl -0xb0(%rbp,%rax,1),%edx
ff
movslq -0x20(%rbp),%rax
movzbl -0x130(%rbp,%rax,1),%eax
ff
and    %eax,%edx
mov    -0x1c(%rbp),%eax
add    -0x20(%rbp),%eax
cltq
movzbl -0x230(%rbp,%rax,1),%ecx
ff
xor    %edx,%ecx
mov    %cl,-0x230(%rbp,%rax,1)
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    1277 <gf_mul+0x167>
jmp    12ca <gf_mul+0x1ba>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1263 <gf_mul+0x153>
movl   $0x7f,-0x1c(%rbp)
cmpl   $0x0,-0x1c(%rbp)
jl     13cc <gf_mul+0x2bc>
mov    -0x1c(%rbp),%eax
add    $0x80,%eax
cltq
movzbl -0x230(%rbp,%rax,1),%edx
ff
movslq -0x1c(%rbp),%rax
movzbl -0x230(%rbp,%rax,1),%ecx
ff
xor    %edx,%ecx
mov    %cl,-0x230(%rbp,%rax,1)
mov    -0x1c(%rbp),%eax
add    $0x80,%eax
cltq
movzbl -0x230(%rbp,%rax,1),%edx
ff
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
cltq
movzbl -0x230(%rbp,%rax,1),%ecx
ff
xor    %edx,%ecx
mov    %cl,-0x230(%rbp,%rax,1)
mov    -0x1c(%rbp),%eax
add    $0x80,%eax
cltq
movzbl -0x230(%rbp,%rax,1),%edx
ff
mov    -0x1c(%rbp),%eax
add    $0x2,%eax
cltq
movzbl -0x230(%rbp,%rax,1),%ecx
ff
xor    %edx,%ecx
mov    %cl,-0x230(%rbp,%rax,1)
mov    -0x1c(%rbp),%eax
add    $0x80,%eax
cltq
movzbl -0x230(%rbp,%rax,1),%edx
ff
mov    -0x1c(%rbp),%eax
add    $0x7,%eax
cltq
movzbl -0x230(%rbp,%rax,1),%ecx
ff
xor    %edx,%ecx
mov    %cl,-0x230(%rbp,%rax,1)
mov    -0x1c(%rbp),%eax
add    $0x80,%eax
cltq
movzbl -0x230(%rbp,%rax,1),%edx
ff
mov    -0x1c(%rbp),%eax
add    $0x80,%eax
cltq
movzbl -0x230(%rbp,%rax,1),%ecx
ff
xor    %edx,%ecx
mov    %cl,-0x230(%rbp,%rax,1)
mov    -0x1c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x1c(%rbp)
jmp    12df <gf_mul+0x1cf>
movl   $0x0,-0x1c(%rbp)
cmpl   $0x10,-0x1c(%rbp)
jge    13f7 <gf_mul+0x2e7>
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    13d3 <gf_mul+0x2c3>
movl   $0x0,-0x1c(%rbp)
cmpl   $0x80,-0x1c(%rbp)
jge    1464 <gf_mul+0x354>
movslq -0x1c(%rbp),%rax
movzbl -0x230(%rbp,%rax,1),%esi
ff
mov    -0x1c(%rbp),%eax
mov    $0x8,%ecx
cltd
idiv   %ecx
mov    $0x7,%ecx
sub    %edx,%ecx
shl    %cl,%esi
mov    -0x8(%rbp),%rax
mov    %rax,-0x258(%rbp)
mov    -0x1c(%rbp),%eax
mov    $0x8,%ecx
cltd
idiv   %ecx
mov    %eax,%ecx
mov    -0x258(%rbp),%rax
movslq %ecx,%rcx
movzbl (%rax,%rcx,1),%edx
or     %esi,%edx
mov    %dl,(%rax,%rcx,1)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    13fe <gf_mul+0x2ee>
add    $0x260,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<gf_mul>:
push   %r15
push   %r14
push   %rbx
sub    $0x200,%rsp
mov    %rdx,%r14
mov    %rdi,%r15
mov    $0x10,%edx
call   1030 <memcpy@plt>
xor    %edx,%edx
xchg   %ax,%ax
mov    %edx,%esi
shr    $0x3,%esi
movzbl (%r15,%rsi,1),%ebx
mov    %edx,%eax
and    $0x6,%al
mov    %eax,%ecx
xor    $0x7,%cl
shr    %cl,%bl
and    $0x1,%bl
mov    %bl,0x180(%rsp,%rdx,1)
movzbl (%r15,%rsi,1),%ebx
xor    $0x6,%al
mov    %eax,%ecx
shr    %cl,%bl
and    $0x1,%bl
mov    %bl,0x181(%rsp,%rdx,1)
add    $0x2,%rdx
cmp    $0x80,%rdx
jne    1130 <gf_mul+0x20>
xor    %edx,%edx
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
mov    %edx,%esi
shr    $0x3,%esi
movzbl (%r14,%rsi,1),%ebx
mov    %edx,%eax
and    $0x6,%al
mov    %eax,%ecx
xor    $0x7,%cl
shr    %cl,%bl
and    $0x1,%bl
mov    %bl,0x100(%rsp,%rdx,1)
movzbl (%r14,%rsi,1),%ebx
xor    $0x6,%al
mov    %eax,%ecx
shr    %cl,%bl
and    $0x1,%bl
mov    %bl,0x101(%rsp,%rdx,1)
add    $0x2,%rdx
cmp    $0x80,%rdx
jne    1180 <gf_mul+0x70>
pxor   %xmm0,%xmm0
movdqa %xmm0,0xf0(%rsp)
movdqa %xmm0,0xe0(%rsp)
movdqa %xmm0,0xd0(%rsp)
movdqa %xmm0,0xc0(%rsp)
movdqa %xmm0,0xb0(%rsp)
movdqa %xmm0,0xa0(%rsp)
movdqa %xmm0,0x90(%rsp)
movdqa %xmm0,0x80(%rsp)
movdqa %xmm0,0x70(%rsp)
movdqa %xmm0,0x60(%rsp)
movdqa %xmm0,0x50(%rsp)
movdqa %xmm0,0x40(%rsp)
movdqa %xmm0,0x30(%rsp)
movdqa %xmm0,0x20(%rsp)
movdqa %xmm0,0x10(%rsp)
movdqa %xmm0,(%rsp)
movdqa 0x100(%rsp),%xmm8
movdqa 0x110(%rsp),%xmm9
movdqa 0x120(%rsp),%xmm10
movdqa 0x130(%rsp),%xmm11
movdqa 0x140(%rsp),%xmm12
movdqa 0x150(%rsp),%xmm5
movdqa 0x160(%rsp),%xmm6
movdqa 0x170(%rsp),%xmm7
xor    %eax,%eax
nopl   0x0(%rax,%rax,1)
movzbl 0x180(%rsp,%rax,1),%ecx
movd   %ecx,%xmm0
punpcklbw %xmm0,%xmm0
pshuflw $0x0,%xmm0,%xmm0
pshufd $0x0,%xmm0,%xmm0
movdqa %xmm8,%xmm1
pand   %xmm0,%xmm1
movdqa %xmm9,%xmm2
pand   %xmm0,%xmm2
movdqu (%rsp,%rax,1),%xmm3
pxor   %xmm1,%xmm3
movdqu 0x10(%rsp,%rax,1),%xmm1
pxor   %xmm2,%xmm1
movdqu 0x20(%rsp,%rax,1),%xmm2
movdqu 0x30(%rsp,%rax,1),%xmm4
movdqu %xmm3,(%rsp,%rax,1)
movdqu %xmm1,0x10(%rsp,%rax,1)
movdqa %xmm10,%xmm1
pand   %xmm0,%xmm1
pxor   %xmm2,%xmm1
movdqa %xmm11,%xmm2
pand   %xmm0,%xmm2
pxor   %xmm4,%xmm2
movdqu %xmm1,0x20(%rsp,%rax,1)
movdqu %xmm2,0x30(%rsp,%rax,1)
movdqa %xmm12,%xmm1
pand   %xmm0,%xmm1
movdqa %xmm5,%xmm2
pand   %xmm0,%xmm2
movdqu 0x40(%rsp,%rax,1),%xmm3
pxor   %xmm1,%xmm3
movdqu 0x50(%rsp,%rax,1),%xmm1
pxor   %xmm2,%xmm1
movdqu %xmm3,0x40(%rsp,%rax,1)
movdqu %xmm1,0x50(%rsp,%rax,1)
movdqa %xmm6,%xmm1
pand   %xmm0,%xmm1
pand   %xmm7,%xmm0
movdqu 0x60(%rsp,%rax,1),%xmm2
pxor   %xmm1,%xmm2
movdqu 0x70(%rsp,%rax,1),%xmm1
pxor   %xmm0,%xmm1
movdqu %xmm2,0x60(%rsp,%rax,1)
movdqu %xmm1,0x70(%rsp,%rax,1)
add    $0x1,%rax
cmp    $0x80,%rax
jne    1290 <gf_mul+0x180>
mov    0x80(%rsp),%al
mov    0x81(%rsp),%dl
mov    $0x7f,%ecx
nopl   0x0(%rax)
movzbl 0x80(%rsp,%rcx,1),%ebx
movzbl (%rsp,%rcx,1),%esi
xor    %bl,%sil
mov    %sil,(%rsp,%rcx,1)
xor    %bl,%al
mov    %al,0x1(%rsp,%rcx,1)
xor    %bl,%dl
mov    %dl,0x2(%rsp,%rcx,1)
xor    %bl,0x7(%rsp,%rcx,1)
movb   $0x0,0x80(%rsp,%rcx,1)
mov    %eax,%edx
mov    %esi,%eax
add    $0xffffffffffffffff,%rcx
jb     1390 <gf_mul+0x280>
pxor   %xmm0,%xmm0
movdqu %xmm0,(%r15)
xor    %edx,%edx
movzbl (%rsp,%rdx,1),%edi
mov    %edx,%eax
and    $0x6,%al
mov    %eax,%ecx
xor    $0x7,%cl
shl    %cl,%dil
mov    %edx,%esi
shr    $0x3,%esi
or     (%r15,%rsi,1),%dil
mov    %dil,(%r15,%rsi,1)
movzbl 0x1(%rsp,%rdx,1),%ebx
xor    $0x6,%al
mov    %eax,%ecx
shl    %cl,%bl
or     %dil,%bl
mov    %bl,(%r15,%rsi,1)
add    $0x2,%rdx
cmp    $0x80,%rdx
jne    13d0 <gf_mul+0x2c0>
add    $0x200,%rsp
pop    %rbx
pop    %r14
pop    %r15
ret

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

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