#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 */
unsigned char gf256_mul(unsigned char, unsigned char);
unsigned char gf256_squ(unsigned char);
unsigned char gf256_inv(unsigned char a) {
  unsigned char a2 = gf256_squ(a);
  unsigned char a4 = gf256_squ(a2);
  unsigned char a8 = gf256_squ(a4);
  unsigned char a4_2 = gf256_mul(a4, a2);
  unsigned char a8_4_2 = gf256_mul(a4_2, a8);
  unsigned char a64_ = gf256_squ(a8_4_2);
  a64_ = gf256_squ(a64_);
  a64_ = gf256_squ(a64_);
  unsigned char a64_2 = gf256_mul(a64_, a8_4_2);
  unsigned char a128_ = gf256_squ(a64_2);
  return gf256_mul(a2, a128_);
}


x86 assembly (clang, -O0):
<gf256_inv>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
mov    %dil,%al
mov    %al,-0x1(%rbp)
movzbl -0x1(%rbp),%edi
call   1030 <gf256_squ@plt>
mov    %al,-0x2(%rbp)
movzbl -0x2(%rbp),%edi
call   1030 <gf256_squ@plt>
mov    %al,-0x3(%rbp)
movzbl -0x3(%rbp),%edi
call   1030 <gf256_squ@plt>
mov    %al,-0x4(%rbp)
mov    -0x3(%rbp),%al
movzbl %al,%edi
movzbl -0x2(%rbp),%esi
call   1040 <gf256_mul@plt>
mov    %al,-0x5(%rbp)
mov    -0x5(%rbp),%al
movzbl %al,%edi
movzbl -0x4(%rbp),%esi
call   1040 <gf256_mul@plt>
mov    %al,-0x6(%rbp)
movzbl -0x6(%rbp),%edi
call   1030 <gf256_squ@plt>
mov    %al,-0x7(%rbp)
movzbl -0x7(%rbp),%edi
call   1030 <gf256_squ@plt>
mov    %al,-0x7(%rbp)
movzbl -0x7(%rbp),%edi
call   1030 <gf256_squ@plt>
mov    %al,-0x7(%rbp)
mov    -0x7(%rbp),%al
movzbl %al,%edi
movzbl -0x6(%rbp),%esi
call   1040 <gf256_mul@plt>
mov    %al,-0x8(%rbp)
movzbl -0x8(%rbp),%edi
call   1030 <gf256_squ@plt>
mov    %al,-0x9(%rbp)
mov    -0x2(%rbp),%al
movzbl %al,%edi
movzbl -0x9(%rbp),%esi
call   1040 <gf256_mul@plt>
movzbl %al,%eax
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<gf256_inv>:
push   %rbp
push   %r14
push   %rbx
call   1030 <gf256_squ@plt>
movzbl %al,%r14d
mov    %r14d,%edi
call   1030 <gf256_squ@plt>
movzbl %al,%ebp
mov    %ebp,%edi
call   1030 <gf256_squ@plt>
mov    %eax,%ebx
mov    %ebp,%edi
mov    %r14d,%esi
call   1040 <gf256_mul@plt>
movzbl %al,%edi
movzbl %bl,%esi
call   1040 <gf256_mul@plt>
movzbl %al,%ebx
mov    %ebx,%edi
call   1030 <gf256_squ@plt>
movzbl %al,%edi
call   1030 <gf256_squ@plt>
movzbl %al,%edi
call   1030 <gf256_squ@plt>
movzbl %al,%edi
mov    %ebx,%esi
call   1040 <gf256_mul@plt>
movzbl %al,%edi
call   1030 <gf256_squ@plt>
movzbl %al,%esi
mov    %r14d,%edi
pop    %rbx
pop    %r14
pop    %rbp
jmp    1040 <gf256_mul@plt>

LLVM IR (-O0):
define zeroext i8 @gf256_inv(i8 zeroext %0) {
%2 = alloca i8
%3 = alloca i8
%4 = alloca i8
%5 = alloca i8
%6 = alloca i8
%7 = alloca i8
%8 = alloca i8
%9 = alloca i8
%10 = alloca i8
store i8 %0, i8* %2
%11 = load i8, i8* %2
%12 = call zeroext i8 @gf256_squ(i8 zeroext %11)
store i8 %12, i8* %3
%13 = load i8, i8* %3
%14 = call zeroext i8 @gf256_squ(i8 zeroext %13)
store i8 %14, i8* %4
%15 = load i8, i8* %4
%16 = call zeroext i8 @gf256_squ(i8 zeroext %15)
store i8 %16, i8* %5
%17 = load i8, i8* %4
%18 = load i8, i8* %3
%19 = call zeroext i8 @gf256_mul(i8 zeroext %17, i8 zeroext %18)
store i8 %19, i8* %6
%20 = load i8, i8* %6
%21 = load i8, i8* %5
%22 = call zeroext i8 @gf256_mul(i8 zeroext %20, i8 zeroext %21)
store i8 %22, i8* %7
%23 = load i8, i8* %7
%24 = call zeroext i8 @gf256_squ(i8 zeroext %23)
store i8 %24, i8* %8
%25 = load i8, i8* %8
%26 = call zeroext i8 @gf256_squ(i8 zeroext %25)
store i8 %26, i8* %8
%27 = load i8, i8* %8
%28 = call zeroext i8 @gf256_squ(i8 zeroext %27)
store i8 %28, i8* %8
%29 = load i8, i8* %8
%30 = load i8, i8* %7
%31 = call zeroext i8 @gf256_mul(i8 zeroext %29, i8 zeroext %30)
store i8 %31, i8* %9
%32 = load i8, i8* %9
%33 = call zeroext i8 @gf256_squ(i8 zeroext %32)
store i8 %33, i8* %10
%34 = load i8, i8* %3
%35 = load i8, i8* %10
%36 = call zeroext i8 @gf256_mul(i8 zeroext %34, i8 zeroext %35)
ret i8 %36
}

LLVM IR (-O2):
define zeroext i8 @gf256_inv(i8 zeroext %0) {
%2 = tail call zeroext i8 @gf256_squ(i8 zeroext %0)
%3 = tail call zeroext i8 @gf256_squ(i8 zeroext %2)
%4 = tail call zeroext i8 @gf256_squ(i8 zeroext %3)
%5 = tail call zeroext i8 @gf256_mul(i8 zeroext %3, i8 zeroext %2)
%6 = tail call zeroext i8 @gf256_mul(i8 zeroext %5, i8 zeroext %4)
%7 = tail call zeroext i8 @gf256_squ(i8 zeroext %6)
%8 = tail call zeroext i8 @gf256_squ(i8 zeroext %7)
%9 = tail call zeroext i8 @gf256_squ(i8 zeroext %8)
%10 = tail call zeroext i8 @gf256_mul(i8 zeroext %9, i8 zeroext %6)
%11 = tail call zeroext i8 @gf256_squ(i8 zeroext %10)
%12 = tail call zeroext i8 @gf256_mul(i8 zeroext %2, i8 zeroext %11)
ret i8 %12
}