#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 */
scalar_t__ add_char(int /*<<< orphan*/, char, int, char *);
int /*<<< orphan*/ free(char *);
scalar_t__ malloc(size_t);
int /*<<< orphan*/ memcpy(char *, char *, size_t);
size_t strlen(char const *);
int b64_encode(char *target, size_t tlen, const char *source, size_t slen) {
  const char *inp;
  char *outp;
  char *outend;
  const char *inend;
  char *tmpbuf = NULL;
  int done = 0;
  char enc;
  int buf;
  if (slen == 0)
    slen = strlen(source);
  inp = source;
  if (source == target) {
    tmpbuf = (char *)malloc(tlen);
    if (tmpbuf == NULL)
      return (-1);
    outp = tmpbuf;
  } else
    outp = target;
  outend = outp + tlen;
  inend = inp + slen;
  for (; (inp < inend) && !done;) {
    enc = *(inp++);
    buf = (enc & 0x03) << 4;
    enc = (enc & 0xFC) >> 2;
    if (add_char(outp++, enc, done, outend)) {
      if (tmpbuf != NULL) {
        free(tmpbuf);
        tmpbuf = NULL;
      };
      return (-1);
    }
    enc = buf | ((*inp & 0xF0) >> 4);
    if (add_char(outp++, enc, done, outend)) {
      if (tmpbuf != NULL) {
        free(tmpbuf);
        tmpbuf = NULL;
      };
      return (-1);
    }
    if (inp == inend)
      done = 1;
    buf = (*(inp++) << 2) & 0x3C;
    enc = buf | ((*inp & 0xC0) >> 6);
    if (add_char(outp++, enc, done, outend)) {
      if (tmpbuf != NULL) {
        free(tmpbuf);
        tmpbuf = NULL;
      };
      return (-1);
    }
    if (inp == inend)
      done = 1;
    enc = ((int)*(inp++)) & 0x3F;
    if (add_char(outp++, enc, done, outend)) {
      if (tmpbuf != NULL) {
        free(tmpbuf);
        tmpbuf = NULL;
      };
      return (-1);
    }
    if (inp == inend)
      done = 1;
  }
  if (outp < outend)
    *outp = 0;
  if (target == source) {
    memcpy(target, tmpbuf, tlen);
    free(tmpbuf);
  }
  return (outp - target);
}


x86 assembly (clang, -O0):
<b64_encode>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %rcx,-0x28(%rbp)
movq   $0x0,-0x50(%rbp)
movl   $0x0,-0x54(%rbp)
cmpq   $0x0,-0x28(%rbp)
jne    118f <b64_encode+0x3f>
mov    -0x20(%rbp),%rdi
call   1050 <strlen@plt>
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x20(%rbp),%rax
cmp    -0x10(%rbp),%rax
jne    11d6 <b64_encode+0x86>
mov    -0x18(%rbp),%rdi
call   1070 <malloc@plt>
mov    %rax,-0x50(%rbp)
cmpq   $0x0,-0x50(%rbp)
jne    11c9 <b64_encode+0x79>
movl   $0xffffffff,-0x4(%rbp)
jmp    149b <b64_encode+0x34b>
mov    -0x50(%rbp),%rax
mov    %rax,-0x38(%rbp)
jmp    11de <b64_encode+0x8e>
mov    -0x10(%rbp),%rax
mov    %rax,-0x38(%rbp)
mov    -0x38(%rbp),%rax
add    -0x18(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x30(%rbp),%rax
add    -0x28(%rbp),%rax
mov    %rax,-0x48(%rbp)
mov    -0x30(%rbp),%rcx
xor    %eax,%eax
cmp    -0x48(%rbp),%rcx
mov    %al,-0x5d(%rbp)
jae    1215 <b64_encode+0xc5>
cmpl   $0x0,-0x54(%rbp)
setne  %al
xor    $0xff,%al
mov    %al,-0x5d(%rbp)
mov    -0x5d(%rbp),%al
test   $0x1,%al
jne    1225 <b64_encode+0xd5>
jmp    1450 <b64_encode+0x300>
mov    -0x30(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x30(%rbp)
mov    (%rax),%al
mov    %al,-0x55(%rbp)
movsbl -0x55(%rbp),%eax
and    $0x3,%eax
shl    $0x4,%eax
mov    %eax,-0x5c(%rbp)
movsbl -0x55(%rbp),%eax
and    $0xfc,%eax
sar    $0x2,%eax
mov    %al,-0x55(%rbp)
mov    -0x38(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x38(%rbp)
mov    %eax,%edi
mov    -0x55(%rbp),%al
mov    -0x54(%rbp),%edx
mov    -0x40(%rbp),%rcx
movsbl %al,%esi
call   1040 <add_char@plt>
cmp    $0x0,%rax
je     12aa <b64_encode+0x15a>
cmpq   $0x0,-0x50(%rbp)
je     129e <b64_encode+0x14e>
mov    -0x50(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x50(%rbp)
movl   $0xffffffff,-0x4(%rbp)
jmp    149b <b64_encode+0x34b>
mov    -0x5c(%rbp),%eax
mov    -0x30(%rbp),%rcx
movsbl (%rcx),%ecx
and    $0xf0,%ecx
sar    $0x4,%ecx
or     %ecx,%eax
mov    %al,-0x55(%rbp)
mov    -0x38(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x38(%rbp)
mov    %eax,%edi
mov    -0x55(%rbp),%al
mov    -0x54(%rbp),%edx
mov    -0x40(%rbp),%rcx
movsbl %al,%esi
call   1040 <add_char@plt>
cmp    $0x0,%rax
je     1317 <b64_encode+0x1c7>
cmpq   $0x0,-0x50(%rbp)
je     130b <b64_encode+0x1bb>
mov    -0x50(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x50(%rbp)
movl   $0xffffffff,-0x4(%rbp)
jmp    149b <b64_encode+0x34b>
mov    -0x30(%rbp),%rax
cmp    -0x48(%rbp),%rax
jne    132c <b64_encode+0x1dc>
movl   $0x1,-0x54(%rbp)
mov    -0x30(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x30(%rbp)
movsbl (%rax),%eax
shl    $0x2,%eax
and    $0x3c,%eax
mov    %eax,-0x5c(%rbp)
mov    -0x5c(%rbp),%eax
mov    -0x30(%rbp),%rcx
movsbl (%rcx),%ecx
and    $0xc0,%ecx
sar    $0x6,%ecx
or     %ecx,%eax
mov    %al,-0x55(%rbp)
mov    -0x38(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x38(%rbp)
mov    %eax,%edi
mov    -0x55(%rbp),%al
mov    -0x54(%rbp),%edx
mov    -0x40(%rbp),%rcx
movsbl %al,%esi
call   1040 <add_char@plt>
cmp    $0x0,%rax
je     13b4 <b64_encode+0x264>
cmpq   $0x0,-0x50(%rbp)
je     13a8 <b64_encode+0x258>
mov    -0x50(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x50(%rbp)
movl   $0xffffffff,-0x4(%rbp)
jmp    149b <b64_encode+0x34b>
mov    -0x30(%rbp),%rax
cmp    -0x48(%rbp),%rax
jne    13c9 <b64_encode+0x279>
movl   $0x1,-0x54(%rbp)
mov    -0x30(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x30(%rbp)
movsbl (%rax),%eax
and    $0x3f,%eax
mov    %al,-0x55(%rbp)
mov    -0x38(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x38(%rbp)
mov    %eax,%edi
mov    -0x55(%rbp),%al
mov    -0x54(%rbp),%edx
mov    -0x40(%rbp),%rcx
movsbl %al,%esi
call   1040 <add_char@plt>
cmp    $0x0,%rax
je     1436 <b64_encode+0x2e6>
cmpq   $0x0,-0x50(%rbp)
je     142a <b64_encode+0x2da>
mov    -0x50(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x50(%rbp)
movl   $0xffffffff,-0x4(%rbp)
jmp    149b <b64_encode+0x34b>
mov    -0x30(%rbp),%rax
cmp    -0x48(%rbp),%rax
jne    144b <b64_encode+0x2fb>
movl   $0x1,-0x54(%rbp)
jmp    11f6 <b64_encode+0xa6>
mov    -0x38(%rbp),%rax
cmp    -0x40(%rbp),%rax
jae    1465 <b64_encode+0x315>
mov    -0x38(%rbp),%rax
movb   $0x0,(%rax)
mov    -0x10(%rbp),%rax
cmp    -0x20(%rbp),%rax
jne    148d <b64_encode+0x33d>
mov    -0x10(%rbp),%rdi
mov    -0x50(%rbp),%rsi
mov    -0x18(%rbp),%rdx
call   1060 <memcpy@plt>
mov    -0x50(%rbp),%rdi
call   1030 <free@plt>
mov    -0x38(%rbp),%rax
mov    -0x10(%rbp),%rcx
sub    %rcx,%rax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<b64_encode>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x38,%rsp
mov    %rdx,%r13
mov    %rsi,%r14
mov    %rdi,%rbx
mov    %rcx,%r12
test   %rcx,%rcx
je     117b <b64_encode+0x2b>
cmp    %rbx,%r13
je     118b <b64_encode+0x3b>
xor    %eax,%eax
mov    %rbx,%rbp
jmp    119f <b64_encode+0x4f>
mov    %r13,%rdi
call   1050 <strlen@plt>
mov    %rax,%r12
cmp    %rbx,%r13
jne    1174 <b64_encode+0x24>
mov    %r14,%rdi
call   1070 <malloc@plt>
mov    %rax,%rbp
test   %rax,%rax
je     1309 <b64_encode+0x1b9>
mov    %rax,(%rsp)
mov    %rbx,0x20(%rsp)
mov    %r14,0x18(%rsp)
lea    (%r14,%rbp,1),%rax
mov    %rax,0x8(%rsp)
test   %r12,%r12
mov    %r13,0x10(%rsp)
jle    12bd <b64_encode+0x16d>
mov    %r12,%rbx
add    %r13,%rbx
mov    %ebp,%r14d
mov    %rbx,0x28(%rsp)
mov    0x8(%rsp),%r15
nopw   0x0(%rax,%rax,1)
mov    %rbp,0x30(%rsp)
movzbl 0x0(%r13),%ebx
mov    %ebx,%eax
shr    $0x2,%al
movzbl %al,%esi
mov    %r14d,%edi
xor    %edx,%edx
mov    %r15,%rcx
call   1040 <add_char@plt>
test   %rax,%rax
jne    12f4 <b64_encode+0x1a4>
movzbl 0x1(%r13),%eax
shl    $0x4,%bl
shr    $0x4,%al
or     %bl,%al
and    $0x3f,%al
lea    0x1(%r14),%edi
movzbl %al,%esi
xor    %edx,%edx
mov    %r15,%rcx
call   1040 <add_char@plt>
test   %rax,%rax
jne    12f4 <b64_encode+0x1a4>
lea    0x1(%r13),%rbp
xor    %r12d,%r12d
mov    0x28(%rsp),%rbx
cmp    %rbx,%rbp
sete   %r12b
movzbl 0x1(%r13),%eax
movzbl 0x2(%r13),%ecx
shr    $0x6,%cl
shl    $0x2,%al
or     %cl,%al
and    $0x3f,%al
lea    0x2(%r14),%edi
movzbl %al,%esi
mov    %r12d,%edx
mov    %r15,%rcx
call   1040 <add_char@plt>
test   %rax,%rax
jne    12f4 <b64_encode+0x1a4>
lea    0x1(%rbp),%r13
cmp    %rbx,%r13
mov    $0x1,%eax
cmove  %eax,%r12d
movzbl 0x1(%rbp),%esi
lea    0x3(%r14),%edi
and    $0x3f,%esi
mov    %r12d,%edx
mov    %r15,%rcx
call   1040 <add_char@plt>
test   %rax,%rax
jne    12f4 <b64_encode+0x1a4>
mov    0x30(%rsp),%rbp
add    $0x4,%rbp
add    $0x1,%r13
cmp    %rbx,%r13
jae    12bd <b64_encode+0x16d>
add    $0x4,%r14d
test   %r12d,%r12d
je     11e0 <b64_encode+0x90>
cmp    0x8(%rsp),%rbp
jae    12c8 <b64_encode+0x178>
movb   $0x0,0x0(%rbp)
mov    0x20(%rsp),%rbx
mov    0x10(%rsp),%rdi
cmp    %rbx,%rdi
mov    0x18(%rsp),%rdx
jne    12f0 <b64_encode+0x1a0>
mov    (%rsp),%r14
mov    %r14,%rsi
call   1060 <memcpy@plt>
mov    %r14,%rdi
call   1030 <free@plt>
sub    %ebx,%ebp
jmp    130e <b64_encode+0x1be>
mov    $0xffffffff,%ebp
mov    (%rsp),%rdi
test   %rdi,%rdi
je     130e <b64_encode+0x1be>
call   1030 <free@plt>
jmp    130e <b64_encode+0x1be>
mov    $0xffffffff,%ebp
mov    %ebp,%eax
add    $0x38,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

LLVM IR (-O2):
define i32 @b64_encode(i8* %0, i64 %1, i8* %2, i64 %3) {
%5 = icmp eq i64 %3, 0
br i1 %5, label %6, label %8
6: ; preds = %4
%7 = tail call i64 @strlen(i8* dereferenceable(1) %2)
br label %8
8: ; preds = %6, %4
%9 = phi i64 [ %7, %6 ], [ %3, %4 ]
%10 = icmp eq i8* %2, %0
br i1 %10, label %11, label %15
11: ; preds = %8
%12 = tail call i64 @malloc(i64 %1)
%13 = inttoptr i64 %12 to i8*
%14 = icmp eq i64 %12, 0
br i1 %14, label %102, label %15
15: ; preds = %8, %11
%16 = phi i8* [ %13, %11 ], [ %0, %8 ]
%17 = phi i8* [ %13, %11 ], [ null, %8 ]
%18 = getelementptr inbounds i8, i8* %16, i64 %1
%19 = getelementptr inbounds i8, i8* %2, i64 %9
%20 = icmp sgt i64 %9, 0
br i1 %20, label %21, label %89
21: ; preds = %15, %84
%22 = phi i8* [ %85, %84 ], [ %16, %15 ]
%23 = phi i8* [ %73, %84 ], [ %2, %15 ]
%24 = getelementptr inbounds i8, i8* %23, i64 1
%25 = load i8, i8* %23
%26 = lshr i8 %25, 2
%27 = ptrtoint i8* %22 to i64
%28 = trunc i64 %27 to i32
%29 = tail call i64 @add_char(i32 %28, i8 signext %26, i32 0, i8* %18)
%30 = icmp eq i64 %29, 0
br i1 %30, label %35, label %31
31: ; preds = %21
%32 = icmp eq i8* %17, null
br i1 %32, label %102, label %33
33: ; preds = %31
%34 = tail call i32 @free(i8* %17)
br label %102
35: ; preds = %21
%36 = getelementptr inbounds i8, i8* %22, i64 1
%37 = shl i8 %25, 4
%38 = and i8 %37, 48
%39 = load i8, i8* %24
%40 = lshr i8 %39, 4
%41 = or i8 %40, %38
%42 = ptrtoint i8* %36 to i64
%43 = trunc i64 %42 to i32
%44 = tail call i64 @add_char(i32 %43, i8 signext %41, i32 0, i8* %18)
%45 = icmp eq i64 %44, 0
br i1 %45, label %50, label %46
46: ; preds = %35
%47 = icmp eq i8* %17, null
br i1 %47, label %102, label %48
48: ; preds = %46
%49 = tail call i32 @free(i8* %17)
br label %102
50: ; preds = %35
%51 = getelementptr inbounds i8, i8* %22, i64 2
%52 = icmp eq i8* %24, %19
%53 = zext i1 %52 to i32
%54 = getelementptr inbounds i8, i8* %23, i64 2
%55 = load i8, i8* %24
%56 = shl i8 %55, 2
%57 = and i8 %56, 60
%58 = load i8, i8* %54
%59 = lshr i8 %58, 6
%60 = or i8 %57, %59
%61 = ptrtoint i8* %51 to i64
%62 = trunc i64 %61 to i32
%63 = tail call i64 @add_char(i32 %62, i8 signext %60, i32 %53, i8* %18)
%64 = icmp eq i64 %63, 0
br i1 %64, label %69, label %65
65: ; preds = %50
%66 = icmp eq i8* %17, null
br i1 %66, label %102, label %67
67: ; preds = %65
%68 = tail call i32 @free(i8* %17)
br label %102
69: ; preds = %50
%70 = getelementptr inbounds i8, i8* %22, i64 3
%71 = icmp eq i8* %54, %19
%72 = select i1 %71, i32 1, i32 %53
%73 = getelementptr inbounds i8, i8* %23, i64 3
%74 = load i8, i8* %54
%75 = and i8 %74, 63
%76 = ptrtoint i8* %70 to i64
%77 = trunc i64 %76 to i32
%78 = tail call i64 @add_char(i32 %77, i8 signext %75, i32 %72, i8* %18)
%79 = icmp eq i64 %78, 0
br i1 %79, label %84, label %80
80: ; preds = %69
%81 = icmp eq i8* %17, null
br i1 %81, label %102, label %82
82: ; preds = %80
%83 = tail call i32 @free(i8* %17)
br label %102
84: ; preds = %69
%85 = getelementptr inbounds i8, i8* %22, i64 4
%86 = icmp ult i8* %73, %19
%87 = icmp eq i32 %72, 0
%88 = and i1 %86, %87
br i1 %88, label %21, label %89
89: ; preds = %84, %15
%90 = phi i8* [ %16, %15 ], [ %85, %84 ]
%91 = icmp ult i8* %90, %18
br i1 %91, label %92, label %93
92: ; preds = %89
store i8 0, i8* %90
br label %93
93: ; preds = %92, %89
br i1 %10, label %94, label %97
94: ; preds = %93
%95 = tail call i32 @memcpy(i8* %2, i8* %17, i64 %1)
%96 = tail call i32 @free(i8* %17)
br label %97
97: ; preds = %94, %93
%98 = ptrtoint i8* %90 to i64
%99 = ptrtoint i8* %0 to i64
%100 = sub i64 %98, %99
%101 = trunc i64 %100 to i32
br label %102
102: ; preds = %80, %82, %65, %67, %46, %48, %31, %33, %11, %97
%103 = phi i32 [ %101, %97 ], [ -1, %11 ], [ -1, %33 ], [ -1, %31 ], [ -1, %48 ], [ -1, %46 ], [ -1, %67 ], [ -1, %65 ], [ -1, %82 ], [ -1, %80 ]
ret i32 %103
}