#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 */
char *malloc(size_t);
char *strdup(char *);
char *base64_enc(const unsigned char *in, size_t insz, size_t *outsz) {
  static const int alphabet[] = {
      'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
      'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
      'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
      'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
      '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
  size_t i, o;
  char *out;
  if (insz == 0) {
    *outsz = 0;
    return strdup("");
  }
  *outsz = ((insz + 2) / 3) * 4;
  if (!(out = malloc((*outsz) + 1))) {
    *outsz = 0;
    return NULL;
  }
  for (i = 0, o = 0; i < insz; i += 3, o += 4) {
    int tmp;
    tmp = in[i] << 16;
    if (i + 1 < insz)
      tmp += in[i + 1] << 8;
    if (i + 2 < insz)
      tmp += in[i + 2];
    out[o] = alphabet[(tmp >> 18) & 0x3f];
    out[o + 1] = alphabet[(tmp >> 12) & 0x3f];
    out[o + 2] = alphabet[(tmp >> 6) & 0x3f];
    out[o + 3] = alphabet[tmp & 0x3f];
    if (i + 2 > insz)
      out[o + 2] = '=';
    if (i + 3 > insz)
      out[o + 3] = '=';
  }
  out[*outsz] = '\0';
  return out;
}


x86 assembly (clang, -O0):
<base64_enc>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
cmpq   $0x0,-0x18(%rbp)
jne    115f <base64_enc+0x3f>
mov    -0x20(%rbp),%rax
movq   $0x0,(%rax)
lea    0xfaf(%rip),%rdi
call   1040 <strdup@plt>
mov    %rax,-0x8(%rbp)
jmp    1335 <base64_enc+0x215>
mov    -0x18(%rbp),%rax
add    $0x2,%rax
mov    $0x3,%ecx
xor    %edx,%edx
div    %rcx
mov    %rax,%rcx
shl    $0x2,%rcx
mov    -0x20(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x20(%rbp),%rax
mov    (%rax),%rdi
add    $0x1,%rdi
call   1030 <malloc@plt>
mov    %rax,-0x38(%rbp)
cmp    $0x0,%rax
jne    11b5 <base64_enc+0x95>
mov    -0x20(%rbp),%rax
movq   $0x0,(%rax)
movq   $0x0,-0x8(%rbp)
jmp    1335 <base64_enc+0x215>
movq   $0x0,-0x28(%rbp)
movq   $0x0,-0x30(%rbp)
mov    -0x28(%rbp),%rax
cmp    -0x18(%rbp),%rax
jae    131e <base64_enc+0x1fe>
mov    -0x10(%rbp),%rax
mov    -0x28(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
shl    $0x10,%eax
mov    %eax,-0x3c(%rbp)
mov    -0x28(%rbp),%rax
add    $0x1,%rax
cmp    -0x18(%rbp),%rax
jae    120d <base64_enc+0xed>
mov    -0x10(%rbp),%rax
mov    -0x28(%rbp),%rcx
movzbl 0x1(%rax,%rcx,1),%eax
shl    $0x8,%eax
add    -0x3c(%rbp),%eax
mov    %eax,-0x3c(%rbp)
mov    -0x28(%rbp),%rax
add    $0x2,%rax
cmp    -0x18(%rbp),%rax
jae    1232 <base64_enc+0x112>
mov    -0x10(%rbp),%rax
mov    -0x28(%rbp),%rcx
movzbl 0x2(%rax,%rcx,1),%eax
add    -0x3c(%rbp),%eax
mov    %eax,-0x3c(%rbp)
mov    -0x3c(%rbp),%eax
sar    $0x12,%eax
and    $0x3f,%eax
movslq %eax,%rcx
lea    0xdbb(%rip),%rax
mov    (%rax,%rcx,4),%eax
mov    %al,%dl
mov    -0x38(%rbp),%rax
mov    -0x30(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x3c(%rbp),%eax
sar    $0xc,%eax
and    $0x3f,%eax
movslq %eax,%rcx
lea    0xd98(%rip),%rax
mov    (%rax,%rcx,4),%eax
mov    %al,%dl
mov    -0x38(%rbp),%rax
mov    -0x30(%rbp),%rcx
mov    %dl,0x1(%rax,%rcx,1)
mov    -0x3c(%rbp),%eax
sar    $0x6,%eax
and    $0x3f,%eax
movslq %eax,%rcx
lea    0xd74(%rip),%rax
mov    (%rax,%rcx,4),%eax
mov    %al,%dl
mov    -0x38(%rbp),%rax
mov    -0x30(%rbp),%rcx
mov    %dl,0x2(%rax,%rcx,1)
mov    -0x3c(%rbp),%eax
and    $0x3f,%eax
movslq %eax,%rcx
lea    0xd53(%rip),%rax
mov    (%rax,%rcx,4),%eax
mov    %al,%dl
mov    -0x38(%rbp),%rax
mov    -0x30(%rbp),%rcx
mov    %dl,0x3(%rax,%rcx,1)
mov    -0x28(%rbp),%rax
add    $0x2,%rax
cmp    -0x18(%rbp),%rax
jbe    12dd <base64_enc+0x1bd>
mov    -0x38(%rbp),%rax
mov    -0x30(%rbp),%rcx
movb   $0x3d,0x2(%rax,%rcx,1)
mov    -0x28(%rbp),%rax
add    $0x3,%rax
cmp    -0x18(%rbp),%rax
jbe    12fc <base64_enc+0x1dc>
mov    -0x38(%rbp),%rax
mov    -0x30(%rbp),%rcx
movb   $0x3d,0x3(%rax,%rcx,1)
jmp    1301 <base64_enc+0x1e1>
mov    -0x28(%rbp),%rax
add    $0x3,%rax
mov    %rax,-0x28(%rbp)
mov    -0x30(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x30(%rbp)
jmp    11c5 <base64_enc+0xa5>
mov    -0x38(%rbp),%rax
mov    -0x20(%rbp),%rcx
mov    (%rcx),%rcx
movb   $0x0,(%rax,%rcx,1)
mov    -0x38(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<base64_enc>:
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
mov    %rdx,%r12
test   %rsi,%rsi
je     1231 <base64_enc+0x111>
mov    %rsi,%r13
mov    %rdi,%r14
lea    0x2(%rsi),%rax
movabs $0xaaaaaaaaaaaaaaab,%rcx
aa aa aa
mul    %rcx
mov    %rdx,%r15
add    %rdx,%r15
and    $0xfffffffffffffffc,%r15
mov    %r15,(%r12)
lea    0x1(%r15),%rdi
call   1030 <malloc@plt>
test   %rax,%rax
je     124e <base64_enc+0x12e>
mov    %rax,%r9
add    $0x3,%r9
mov    $0x1,%edx
lea    0xe81(%rip),%r8
jmp    11a1 <base64_enc+0x81>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
add    $0x4,%r9
add    $0x3,%rdx
cmp    %r13,%rsi
jae    122a <base64_enc+0x10a>
movzbl -0x1(%r14,%rdx,1),%ecx
shl    $0x10,%ecx
cmp    %r13,%rdx
jae    11bb <base64_enc+0x9b>
movzbl (%r14,%rdx,1),%esi
shl    $0x8,%esi
or     %ecx,%esi
mov    %esi,%ecx
lea    0x1(%rdx),%rsi
cmp    %r13,%rsi
jae    11cc <base64_enc+0xac>
movzbl 0x1(%r14,%rdx,1),%ebx
add    %ebx,%ecx
mov    %ecx,%edi
shr    $0x12,%edi
and    $0x3f,%edi
movzbl (%r8,%rdi,4),%ebx
mov    %bl,-0x3(%r9)
mov    %ecx,%edi
shr    $0xc,%edi
and    $0x3f,%edi
movzbl (%r8,%rdi,4),%ebx
mov    %bl,-0x2(%r9)
mov    %ecx,%edi
shr    $0x6,%edi
and    $0x3f,%edi
movzbl (%r8,%rdi,4),%ebx
mov    %bl,-0x1(%r9)
and    $0x3f,%ecx
movzbl (%r8,%rcx,4),%ecx
mov    %cl,(%r9)
cmp    %r13,%rsi
jbe    1214 <base64_enc+0xf4>
movb   $0x3d,-0x1(%r9)
lea    0x2(%rdx),%rsi
cmp    %r13,%rsi
jbe    1190 <base64_enc+0x70>
movb   $0x3d,(%r9)
jmp    1190 <base64_enc+0x70>
movb   $0x0,(%rax,%r15,1)
jmp    1258 <base64_enc+0x138>
movq   $0x0,(%r12)
lea    0xec0(%rip),%rdi
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
jmp    1040 <strdup@plt>
movq   $0x0,(%r12)
xor    %eax,%eax
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
@base64_enc.alphabet = internal constant [64 x i32] [i32 65, i32 66, i32 67, i32 68, i32 69, i32 70, i32 71, i32 72, i32 73, i32 74, i32 75, i32 76, i32 77, i32 78, i32 79, i32 80, i32 81, i32 82, i32 83, i32 84, i32 85, i32 86, i32 87, i32 88, i32 89, i32 90, i32 97, i32 98, i32 99, i32 100, i32 101, i32 102, i32 103, i32 104, i32 105, i32 106, i32 107, i32 108, i32 109, i32 110, i32 111, i32 112, i32 113, i32 114, i32 115, i32 116, i32 117, i32 118, i32 119, i32 120, i32 121, i32 122, i32 48, i32 49, i32 50, i32 51, i32 52, i32 53, i32 54, i32 55, i32 56, i32 57, i32 43, i32 47]
@.str = [1 x i8] zeroinitializer
define i8* @base64_enc(i8* %0, i64 %1, i64* %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i64
%7 = alloca i64*
%8 = alloca i64
%9 = alloca i64
%10 = alloca i8*
%11 = alloca i32
store i8* %0, i8** %5
store i64 %1, i64* %6
store i64* %2, i64** %7
%12 = load i64, i64* %6
%13 = icmp eq i64 %12, 0
br i1 %13, label %14, label %17
14: ; preds = %3
%15 = load i64*, i64** %7
store i64 0, i64* %15
%16 = call i8* @strdup(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i64 0, i64 0))
store i8* %16, i8** %4
br label %144
17: ; preds = %3
%18 = load i64, i64* %6
%19 = add i64 %18, 2
%20 = udiv i64 %19, 3
%21 = mul i64 %20, 4
%22 = load i64*, i64** %7
store i64 %21, i64* %22
%23 = load i64*, i64** %7
%24 = load i64, i64* %23
%25 = add i64 %24, 1
%26 = call i8* @malloc(i64 %25)
store i8* %26, i8** %10
%27 = icmp ne i8* %26, null
br i1 %27, label %30, label %28
28: ; preds = %17
%29 = load i64*, i64** %7
store i64 0, i64* %29
store i8* null, i8** %4
br label %144
30: ; preds = %17
store i64 0, i64* %8
store i64 0, i64* %9
br label %31
31: ; preds = %133, %30
%32 = load i64, i64* %8
%33 = load i64, i64* %6
%34 = icmp ult i64 %32, %33
br i1 %34, label %35, label %138
35: ; preds = %31
%36 = load i8*, i8** %5
%37 = load i64, i64* %8
%38 = getelementptr inbounds i8, i8* %36, i64 %37
%39 = load i8, i8* %38
%40 = zext i8 %39 to i32
%41 = shl i32 %40, 16
store i32 %41, i32* %11
%42 = load i64, i64* %8
%43 = add i64 %42, 1
%44 = load i64, i64* %6
%45 = icmp ult i64 %43, %44
br i1 %45, label %46, label %56
46: ; preds = %35
%47 = load i8*, i8** %5
%48 = load i64, i64* %8
%49 = add i64 %48, 1
%50 = getelementptr inbounds i8, i8* %47, i64 %49
%51 = load i8, i8* %50
%52 = zext i8 %51 to i32
%53 = shl i32 %52, 8
%54 = load i32, i32* %11
%55 = add nsw i32 %54, %53
store i32 %55, i32* %11
br label %56
56: ; preds = %46, %35
%57 = load i64, i64* %8
%58 = add i64 %57, 2
%59 = load i64, i64* %6
%60 = icmp ult i64 %58, %59
br i1 %60, label %61, label %70
61: ; preds = %56
%62 = load i8*, i8** %5
%63 = load i64, i64* %8
%64 = add i64 %63, 2
%65 = getelementptr inbounds i8, i8* %62, i64 %64
%66 = load i8, i8* %65
%67 = zext i8 %66 to i32
%68 = load i32, i32* %11
%69 = add nsw i32 %68, %67
store i32 %69, i32* %11
br label %70
70: ; preds = %61, %56
%71 = load i32, i32* %11
%72 = ashr i32 %71, 18
%73 = and i32 %72, 63
%74 = sext i32 %73 to i64
%75 = getelementptr inbounds [64 x i32], [64 x i32]* @base64_enc.alphabet, i64 0, i64 %74
%76 = load i32, i32* %75
%77 = trunc i32 %76 to i8
%78 = load i8*, i8** %10
%79 = load i64, i64* %9
%80 = getelementptr inbounds i8, i8* %78, i64 %79
store i8 %77, i8* %80
%81 = load i32, i32* %11
%82 = ashr i32 %81, 12
%83 = and i32 %82, 63
%84 = sext i32 %83 to i64
%85 = getelementptr inbounds [64 x i32], [64 x i32]* @base64_enc.alphabet, i64 0, i64 %84
%86 = load i32, i32* %85
%87 = trunc i32 %86 to i8
%88 = load i8*, i8** %10
%89 = load i64, i64* %9
%90 = add i64 %89, 1
%91 = getelementptr inbounds i8, i8* %88, i64 %90
store i8 %87, i8* %91
%92 = load i32, i32* %11
%93 = ashr i32 %92, 6
%94 = and i32 %93, 63
%95 = sext i32 %94 to i64
%96 = getelementptr inbounds [64 x i32], [64 x i32]* @base64_enc.alphabet, i64 0, i64 %95
%97 = load i32, i32* %96
%98 = trunc i32 %97 to i8
%99 = load i8*, i8** %10
%100 = load i64, i64* %9
%101 = add i64 %100, 2
%102 = getelementptr inbounds i8, i8* %99, i64 %101
store i8 %98, i8* %102
%103 = load i32, i32* %11
%104 = and i32 %103, 63
%105 = sext i32 %104 to i64
%106 = getelementptr inbounds [64 x i32], [64 x i32]* @base64_enc.alphabet, i64 0, i64 %105
%107 = load i32, i32* %106
%108 = trunc i32 %107 to i8
%109 = load i8*, i8** %10
%110 = load i64, i64* %9
%111 = add i64 %110, 3
%112 = getelementptr inbounds i8, i8* %109, i64 %111
store i8 %108, i8* %112
%113 = load i64, i64* %8
%114 = add i64 %113, 2
%115 = load i64, i64* %6
%116 = icmp ugt i64 %114, %115
br i1 %116, label %117, label %122
117: ; preds = %70
%118 = load i8*, i8** %10
%119 = load i64, i64* %9
%120 = add i64 %119, 2
%121 = getelementptr inbounds i8, i8* %118, i64 %120
store i8 61, i8* %121
br label %122
122: ; preds = %117, %70
%123 = load i64, i64* %8
%124 = add i64 %123, 3
%125 = load i64, i64* %6
%126 = icmp ugt i64 %124, %125
br i1 %126, label %127, label %132
127: ; preds = %122
%128 = load i8*, i8** %10
%129 = load i64, i64* %9
%130 = add i64 %129, 3
%131 = getelementptr inbounds i8, i8* %128, i64 %130
store i8 61, i8* %131
br label %132
132: ; preds = %127, %122
br label %133
133: ; preds = %132
%134 = load i64, i64* %8
%135 = add i64 %134, 3
store i64 %135, i64* %8
%136 = load i64, i64* %9
%137 = add i64 %136, 4
store i64 %137, i64* %9
br label %31
138: ; preds = %31
%139 = load i8*, i8** %10
%140 = load i64*, i64** %7
%141 = load i64, i64* %140
%142 = getelementptr inbounds i8, i8* %139, i64 %141
store i8 0, i8* %142
%143 = load i8*, i8** %10
store i8* %143, i8** %4
br label %144
144: ; preds = %138, %28, %14
%145 = load i8*, i8** %4
ret i8* %145
}

LLVM IR (-O2):
@base64_enc.alphabet = internal unnamed_addr constant [64 x i32] [i32 65, i32 66, i32 67, i32 68, i32 69, i32 70, i32 71, i32 72, i32 73, i32 74, i32 75, i32 76, i32 77, i32 78, i32 79, i32 80, i32 81, i32 82, i32 83, i32 84, i32 85, i32 86, i32 87, i32 88, i32 89, i32 90, i32 97, i32 98, i32 99, i32 100, i32 101, i32 102, i32 103, i32 104, i32 105, i32 106, i32 107, i32 108, i32 109, i32 110, i32 111, i32 112, i32 113, i32 114, i32 115, i32 116, i32 117, i32 118, i32 119, i32 120, i32 121, i32 122, i32 48, i32 49, i32 50, i32 51, i32 52, i32 53, i32 54, i32 55, i32 56, i32 57, i32 43, i32 47]
@.str = [1 x i8] zeroinitializer
define noalias i8* @base64_enc(i8* nocapture %0, i64 %1, i64* nocapture %2) {
%4 = icmp eq i64 %1, 0
br i1 %4, label %5, label %7
5: ; preds = %3
store i64 0, i64* %2
%6 = tail call dereferenceable_or_null(1) i8* @strdup(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str, i64 0, i64 0))
br label %82
7: ; preds = %3
%8 = add i64 %1, 2
%9 = udiv i64 %8, 3
%10 = shl i64 %9, 2
store i64 %10, i64* %2
%11 = or i64 %10, 1
%12 = tail call i8* @malloc(i64 %11)
%13 = icmp eq i8* %12, null
br i1 %13, label %14, label %15
14: ; preds = %7
store i64 0, i64* %2
br label %82
15: ; preds = %7, %77
%16 = phi i64 [ %78, %77 ], [ 0, %7 ]
%17 = phi i64 [ %74, %77 ], [ 0, %7 ]
%18 = getelementptr inbounds i8, i8* %0, i64 %17
%19 = load i8, i8* %18
%20 = zext i8 %19 to i32
%21 = shl nuw nsw i32 %20, 16
%22 = add nuw i64 %17, 1
%23 = icmp ult i64 %22, %1
br i1 %23, label %24, label %30
24: ; preds = %15
%25 = getelementptr inbounds i8, i8* %0, i64 %22
%26 = load i8, i8* %25
%27 = zext i8 %26 to i32
%28 = shl nuw nsw i32 %27, 8
%29 = or i32 %28, %21
br label %30
30: ; preds = %24, %15
%31 = phi i32 [ %29, %24 ], [ %21, %15 ]
%32 = add i64 %17, 2
%33 = icmp ult i64 %32, %1
br i1 %33, label %34, label %39
34: ; preds = %30
%35 = getelementptr inbounds i8, i8* %0, i64 %32
%36 = load i8, i8* %35
%37 = zext i8 %36 to i32
%38 = add nsw i32 %31, %37
br label %39
39: ; preds = %34, %30
%40 = phi i32 [ %38, %34 ], [ %31, %30 ]
%41 = lshr i32 %40, 18
%42 = and i32 %41, 63
%43 = zext i32 %42 to i64
%44 = getelementptr inbounds [64 x i32], [64 x i32]* @base64_enc.alphabet, i64 0, i64 %43
%45 = load i32, i32* %44
%46 = trunc i32 %45 to i8
%47 = getelementptr inbounds i8, i8* %12, i64 %16
store i8 %46, i8* %47
%48 = lshr i32 %40, 12
%49 = and i32 %48, 63
%50 = zext i32 %49 to i64
%51 = getelementptr inbounds [64 x i32], [64 x i32]* @base64_enc.alphabet, i64 0, i64 %50
%52 = load i32, i32* %51
%53 = trunc i32 %52 to i8
%54 = or i64 %16, 1
%55 = getelementptr inbounds i8, i8* %12, i64 %54
store i8 %53, i8* %55
%56 = lshr i32 %40, 6
%57 = and i32 %56, 63
%58 = zext i32 %57 to i64
%59 = getelementptr inbounds [64 x i32], [64 x i32]* @base64_enc.alphabet, i64 0, i64 %58
%60 = load i32, i32* %59
%61 = trunc i32 %60 to i8
%62 = or i64 %16, 2
%63 = getelementptr inbounds i8, i8* %12, i64 %62
store i8 %61, i8* %63
%64 = and i32 %40, 63
%65 = zext i32 %64 to i64
%66 = getelementptr inbounds [64 x i32], [64 x i32]* @base64_enc.alphabet, i64 0, i64 %65
%67 = load i32, i32* %66
%68 = trunc i32 %67 to i8
%69 = or i64 %16, 3
%70 = getelementptr inbounds i8, i8* %12, i64 %69
store i8 %68, i8* %70
%71 = icmp ugt i64 %32, %1
br i1 %71, label %72, label %73
72: ; preds = %39
store i8 61, i8* %63
br label %73
73: ; preds = %72, %39
%74 = add i64 %17, 3
%75 = icmp ugt i64 %74, %1
br i1 %75, label %76, label %77
76: ; preds = %73
store i8 61, i8* %70
br label %77
77: ; preds = %76, %73
%78 = add i64 %16, 4
%79 = icmp ult i64 %74, %1
br i1 %79, label %15, label %80
80: ; preds = %77
%81 = getelementptr inbounds i8, i8* %12, i64 %10
store i8 0, i8* %81
br label %82
82: ; preds = %80, %14, %5
%83 = phi i8* [ %6, %5 ], [ %12, %80 ], [ null, %14 ]
ret i8* %83
}