unsigned char aes_mul2(unsigned char in) {
  unsigned char out = 0x0;
  out |= (((in >> 7) & 0x1)) << 0;
  out |= (((in >> 0) & 0x1) ^ ((in >> 7) & 0x1)) << 1;
  out |= (((in >> 1) & 0x1)) << 2;
  out |= (((in >> 2) & 0x1) ^ ((in >> 7) & 0x1)) << 3;
  out |= (((in >> 3) & 0x1) ^ ((in >> 7) & 0x1)) << 4;
  out |= (((in >> 4) & 0x1)) << 5;
  out |= (((in >> 5) & 0x1)) << 6;
  out |= (((in >> 6) & 0x1)) << 7;
  return out;
}


x86 assembly (clang, -O0):
<aes_mul2>:
push   %rbp
mov    %rsp,%rbp
mov    %dil,%al
mov    %al,-0x1(%rbp)
movb   $0x0,-0x2(%rbp)
movzbl -0x1(%rbp),%ecx
sar    $0x7,%ecx
and    $0x1,%ecx
shl    $0x0,%ecx
movzbl -0x2(%rbp),%eax
or     %ecx,%eax
mov    %al,-0x2(%rbp)
movzbl -0x1(%rbp),%ecx
sar    $0x0,%ecx
and    $0x1,%ecx
movzbl -0x1(%rbp),%eax
sar    $0x7,%eax
and    $0x1,%eax
xor    %eax,%ecx
shl    $0x1,%ecx
movzbl -0x2(%rbp),%eax
or     %ecx,%eax
mov    %al,-0x2(%rbp)
movzbl -0x1(%rbp),%ecx
sar    $0x1,%ecx
and    $0x1,%ecx
shl    $0x2,%ecx
movzbl -0x2(%rbp),%eax
or     %ecx,%eax
mov    %al,-0x2(%rbp)
movzbl -0x1(%rbp),%ecx
sar    $0x2,%ecx
and    $0x1,%ecx
movzbl -0x1(%rbp),%eax
sar    $0x7,%eax
and    $0x1,%eax
xor    %eax,%ecx
shl    $0x3,%ecx
movzbl -0x2(%rbp),%eax
or     %ecx,%eax
mov    %al,-0x2(%rbp)
movzbl -0x1(%rbp),%ecx
sar    $0x3,%ecx
and    $0x1,%ecx
movzbl -0x1(%rbp),%eax
sar    $0x7,%eax
and    $0x1,%eax
xor    %eax,%ecx
shl    $0x4,%ecx
movzbl -0x2(%rbp),%eax
or     %ecx,%eax
mov    %al,-0x2(%rbp)
movzbl -0x1(%rbp),%ecx
sar    $0x4,%ecx
and    $0x1,%ecx
shl    $0x5,%ecx
movzbl -0x2(%rbp),%eax
or     %ecx,%eax
mov    %al,-0x2(%rbp)
movzbl -0x1(%rbp),%ecx
sar    $0x5,%ecx
and    $0x1,%ecx
shl    $0x6,%ecx
movzbl -0x2(%rbp),%eax
or     %ecx,%eax
mov    %al,-0x2(%rbp)
movzbl -0x1(%rbp),%ecx
sar    $0x6,%ecx
and    $0x1,%ecx
shl    $0x7,%ecx
movzbl -0x2(%rbp),%eax
or     %ecx,%eax
mov    %al,-0x2(%rbp)
movzbl -0x2(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<aes_mul2>:
mov    %edi,%ecx
shr    $0x7,%ecx
mov    %edi,%eax
and    $0x1,%eax
xor    %ecx,%eax
lea    (%rcx,%rax,2),%edx
lea    (%rdi,%rdi,1),%eax
mov    %eax,%esi
and    $0x4,%esi
or     %edx,%esi
mov    %edi,%edx
shr    $0x2,%edx
and    $0x1,%edx
xor    %ecx,%edx
shr    $0x3,%edi
and    $0x1,%edi
xor    %edi,%ecx
shl    $0x4,%ecx
lea    (%rsi,%rdx,8),%edx
and    $0xe0,%eax
or     %ecx,%eax
or     %edx,%eax
ret

LLVM IR (-O0):
define zeroext i8 @aes_mul2(i8 zeroext %0) {
%2 = alloca i8
%3 = alloca i8
store i8 %0, i8* %2
store i8 0, i8* %3
%4 = load i8, i8* %2
%5 = zext i8 %4 to i32
%6 = ashr i32 %5, 7
%7 = and i32 %6, 1
%8 = shl i32 %7, 0
%9 = load i8, i8* %3
%10 = zext i8 %9 to i32
%11 = or i32 %10, %8
%12 = trunc i32 %11 to i8
store i8 %12, i8* %3
%13 = load i8, i8* %2
%14 = zext i8 %13 to i32
%15 = ashr i32 %14, 0
%16 = and i32 %15, 1
%17 = load i8, i8* %2
%18 = zext i8 %17 to i32
%19 = ashr i32 %18, 7
%20 = and i32 %19, 1
%21 = xor i32 %16, %20
%22 = shl i32 %21, 1
%23 = load i8, i8* %3
%24 = zext i8 %23 to i32
%25 = or i32 %24, %22
%26 = trunc i32 %25 to i8
store i8 %26, i8* %3
%27 = load i8, i8* %2
%28 = zext i8 %27 to i32
%29 = ashr i32 %28, 1
%30 = and i32 %29, 1
%31 = shl i32 %30, 2
%32 = load i8, i8* %3
%33 = zext i8 %32 to i32
%34 = or i32 %33, %31
%35 = trunc i32 %34 to i8
store i8 %35, i8* %3
%36 = load i8, i8* %2
%37 = zext i8 %36 to i32
%38 = ashr i32 %37, 2
%39 = and i32 %38, 1
%40 = load i8, i8* %2
%41 = zext i8 %40 to i32
%42 = ashr i32 %41, 7
%43 = and i32 %42, 1
%44 = xor i32 %39, %43
%45 = shl i32 %44, 3
%46 = load i8, i8* %3
%47 = zext i8 %46 to i32
%48 = or i32 %47, %45
%49 = trunc i32 %48 to i8
store i8 %49, i8* %3
%50 = load i8, i8* %2
%51 = zext i8 %50 to i32
%52 = ashr i32 %51, 3
%53 = and i32 %52, 1
%54 = load i8, i8* %2
%55 = zext i8 %54 to i32
%56 = ashr i32 %55, 7
%57 = and i32 %56, 1
%58 = xor i32 %53, %57
%59 = shl i32 %58, 4
%60 = load i8, i8* %3
%61 = zext i8 %60 to i32
%62 = or i32 %61, %59
%63 = trunc i32 %62 to i8
store i8 %63, i8* %3
%64 = load i8, i8* %2
%65 = zext i8 %64 to i32
%66 = ashr i32 %65, 4
%67 = and i32 %66, 1
%68 = shl i32 %67, 5
%69 = load i8, i8* %3
%70 = zext i8 %69 to i32
%71 = or i32 %70, %68
%72 = trunc i32 %71 to i8
store i8 %72, i8* %3
%73 = load i8, i8* %2
%74 = zext i8 %73 to i32
%75 = ashr i32 %74, 5
%76 = and i32 %75, 1
%77 = shl i32 %76, 6
%78 = load i8, i8* %3
%79 = zext i8 %78 to i32
%80 = or i32 %79, %77
%81 = trunc i32 %80 to i8
store i8 %81, i8* %3
%82 = load i8, i8* %2
%83 = zext i8 %82 to i32
%84 = ashr i32 %83, 6
%85 = and i32 %84, 1
%86 = shl i32 %85, 7
%87 = load i8, i8* %3
%88 = zext i8 %87 to i32
%89 = or i32 %88, %86
%90 = trunc i32 %89 to i8
store i8 %90, i8* %3
%91 = load i8, i8* %3
ret i8 %91
}

LLVM IR (-O2):
define zeroext i8 @aes_mul2(i8 zeroext %0) {
%2 = zext i8 %0 to i32
%3 = lshr i32 %2, 7
%4 = and i32 %2, 1
%5 = xor i32 %4, %3
%6 = shl nuw nsw i32 %5, 1
%7 = or i32 %6, %3
%8 = shl nuw nsw i32 %2, 1
%9 = and i32 %8, 4
%10 = or i32 %7, %9
%11 = lshr i32 %2, 2
%12 = and i32 %11, 1
%13 = xor i32 %12, %3
%14 = shl nuw nsw i32 %13, 3
%15 = lshr i32 %2, 3
%16 = and i32 %15, 1
%17 = xor i32 %16, %3
%18 = shl nuw nsw i32 %17, 4
%19 = or i32 %10, %14
%20 = and i32 %8, 224
%21 = or i32 %20, %18
%22 = or i32 %21, %19
%23 = trunc i32 %22 to i8
ret i8 %23
}