#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 */
typedef unsigned char uint32_t;

/* Variables and functions */
unsigned char *calloc(size_t, int);
int /*<<< orphan*/ fprintf(int /*<<< orphan*/, char *, char *);
int /*<<< orphan*/ printf(char *, size_t);
int /*<<< orphan*/ stderr;
size_t strlen(char *);
uint32_t *utf8_to_unicode(unsigned char *src) {
  size_t len = strlen((char *)src);
  uint32_t *unicodes = calloc(len, sizeof(uint32_t));
  printf("len: %ld\n", len);
  int uni_ind = 0;
  for (int i = 0; i < len; i++) {
    if (src[i] < 0x80) {
      unicodes[uni_ind] = src[i];
      uni_ind++;
      continue;
    } else {
      if (src[i] >> 7 == 0x00) {
        unicodes[uni_ind] = src[i] & 0x7F;
      } else if (src[i] >> 5 == 0x06) {
        if (src[i + 1] >> 6 != 2)
          fprintf(stderr, "%s\n", "Invalid utf-8");
        unicodes[uni_ind] = ((src[i] & 0x1F) << 6) + (src[i + 1] & 0x3F);
        i++;
      } else if (src[i] >> 4 == 0x0E) {
        if (src[i + 1] >> 6 != 2 || src[i + 2] >> 6 != 2)
          fprintf(stderr, "%s\n", "Invalid utf-8");
        unicodes[uni_ind] = ((src[i] & 0x0F) << 12) +
                            ((src[i + 1] & 0x3F) << 6) + ((src[i + 2] & 0x3F));
        i += 2;
      } else if (src[i] >> 3 == 0x1E) {
        if (src[i + 1] >> 6 != 2 && src[i + 2] >> 6 != 2 &&
            src[i + 3] >> 6 != 2)
          fprintf(stderr, "%s\n", "Invalid utf-8");
        unicodes[uni_ind] = ((src[i] & 0x0F) << 18) +
                            ((src[i + 1] & 0x3F) << 12) +
                            ((src[i + 2] & 0x3F) << 6) + ((src[i + 3] & 0x3F));
        i += 3;
      }
      uni_ind++;
    }
  }
  return unicodes;
}


x86 assembly (clang, -O0):
<utf8_to_unicode>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    -0x8(%rbp),%rdi
call   1030 <strlen@plt>
mov    %rax,-0x10(%rbp)
mov    -0x10(%rbp),%rdi
mov    $0x1,%esi
call   1050 <calloc@plt>
mov    %rax,-0x18(%rbp)
mov    -0x10(%rbp),%rsi
lea    0xe8a(%rip),%rdi
call   1040 <printf@plt>
movl   $0x0,-0x1c(%rbp)
movl   $0x0,-0x20(%rbp)
movslq -0x20(%rbp),%rax
cmp    -0x10(%rbp),%rax
jae    148f <utf8_to_unicode+0x34f>
mov    -0x8(%rbp),%rax
movslq -0x20(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
cmp    $0x80,%eax
jge    11d2 <utf8_to_unicode+0x92>
mov    -0x8(%rbp),%rax
movslq -0x20(%rbp),%rcx
mov    (%rax,%rcx,1),%dl
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1481 <utf8_to_unicode+0x341>
mov    -0x8(%rbp),%rax
movslq -0x20(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
sar    $0x7,%eax
cmp    $0x0,%eax
jne    120b <utf8_to_unicode+0xcb>
mov    -0x8(%rbp),%rax
movslq -0x20(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
and    $0x7f,%eax
mov    %al,%dl
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
jmp    1473 <utf8_to_unicode+0x333>
mov    -0x8(%rbp),%rax
movslq -0x20(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
sar    $0x5,%eax
cmp    $0x6,%eax
jne    129f <utf8_to_unicode+0x15f>
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movzbl (%rax,%rcx,1),%eax
sar    $0x6,%eax
cmp    $0x2,%eax
je     125c <utf8_to_unicode+0x11c>
mov    0x2d99(%rip),%rax
mov    (%rax),%edi
lea    0xdba(%rip),%rsi
lea    0xdb7(%rip),%rdx
call   1060 <fprintf@plt>
mov    -0x8(%rbp),%rax
movslq -0x20(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
and    $0x1f,%eax
shl    $0x6,%eax
mov    -0x8(%rbp),%rcx
mov    -0x20(%rbp),%edx
add    $0x1,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
add    %ecx,%eax
mov    %al,%dl
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    146e <utf8_to_unicode+0x32e>
mov    -0x8(%rbp),%rax
movslq -0x20(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
sar    $0x4,%eax
cmp    $0xe,%eax
jne    1369 <utf8_to_unicode+0x229>
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movzbl (%rax,%rcx,1),%eax
sar    $0x6,%eax
cmp    $0x2,%eax
jne    12f1 <utf8_to_unicode+0x1b1>
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movzbl (%rax,%rcx,1),%eax
sar    $0x6,%eax
cmp    $0x2,%eax
je     130d <utf8_to_unicode+0x1cd>
mov    0x2ce8(%rip),%rax
mov    (%rax),%edi
lea    0xd09(%rip),%rsi
lea    0xd06(%rip),%rdx
call   1060 <fprintf@plt>
mov    -0x8(%rbp),%rax
movslq -0x20(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
and    $0xf,%eax
shl    $0xc,%eax
mov    -0x8(%rbp),%rcx
mov    -0x20(%rbp),%edx
add    $0x1,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
shl    $0x6,%ecx
add    %ecx,%eax
mov    -0x8(%rbp),%rcx
mov    -0x20(%rbp),%edx
add    $0x2,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
add    %ecx,%eax
mov    %al,%dl
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x20(%rbp),%eax
add    $0x2,%eax
mov    %eax,-0x20(%rbp)
jmp    1469 <utf8_to_unicode+0x329>
mov    -0x8(%rbp),%rax
movslq -0x20(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
sar    $0x3,%eax
cmp    $0x1e,%eax
jne    1464 <utf8_to_unicode+0x324>
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movzbl (%rax,%rcx,1),%eax
sar    $0x6,%eax
cmp    $0x2,%eax
je     13f4 <utf8_to_unicode+0x2b4>
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movzbl (%rax,%rcx,1),%eax
sar    $0x6,%eax
cmp    $0x2,%eax
je     13f4 <utf8_to_unicode+0x2b4>
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%ecx
add    $0x3,%ecx
movslq %ecx,%rcx
movzbl (%rax,%rcx,1),%eax
sar    $0x6,%eax
cmp    $0x2,%eax
je     13f4 <utf8_to_unicode+0x2b4>
mov    0x2c01(%rip),%rax
mov    (%rax),%edi
lea    0xc22(%rip),%rsi
lea    0xc1f(%rip),%rdx
call   1060 <fprintf@plt>
mov    -0x8(%rbp),%rax
movslq -0x20(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
and    $0xf,%eax
shl    $0x12,%eax
mov    -0x8(%rbp),%rcx
mov    -0x20(%rbp),%edx
add    $0x1,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
shl    $0xc,%ecx
add    %ecx,%eax
mov    -0x8(%rbp),%rcx
mov    -0x20(%rbp),%edx
add    $0x2,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
shl    $0x6,%ecx
add    %ecx,%eax
mov    -0x8(%rbp),%rcx
mov    -0x20(%rbp),%edx
add    $0x3,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
add    %ecx,%eax
mov    %al,%dl
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x20(%rbp),%eax
add    $0x3,%eax
mov    %eax,-0x20(%rbp)
jmp    1469 <utf8_to_unicode+0x329>
jmp    146e <utf8_to_unicode+0x32e>
jmp    1473 <utf8_to_unicode+0x333>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1481 <utf8_to_unicode+0x341>
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    1189 <utf8_to_unicode+0x49>
mov    -0x18(%rbp),%rax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<utf8_to_unicode>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
push   %rax
mov    %rdi,%rbx
call   1030 <strlen@plt>
mov    %rax,%r14
mov    %rax,%rdi
mov    $0x1,%esi
call   1050 <calloc@plt>
mov    %rax,(%rsp)
lea    0xe92(%rip),%rdi
mov    %r14,%rsi
call   1040 <printf@plt>
test   %r14,%r14
je     12c7 <utf8_to_unicode+0x187>
xor    %r13d,%r13d
mov    (%rsp),%r15
xor    %r12d,%r12d
nopl   0x0(%rax)
movzbl (%rbx,%r13,1),%eax
test   %al,%al
jns    12b0 <utf8_to_unicode+0x170>
movzbl %al,%ecx
mov    %ecx,%edx
and    $0xffffffe0,%edx
cmp    $0xc0,%edx
jne    11f5 <utf8_to_unicode+0xb5>
movslq %r12d,%r12
movzbl 0x1(%rbx,%r12,1),%ecx
add    $0x1,%r12
mov    %ecx,%edx
and    $0xc0,%dl
cmp    $0x80,%dl
je     11ea <utf8_to_unicode+0xaa>
mov    0x2e15(%rip),%rax
mov    (%rax),%edi
lea    0xe36(%rip),%rsi
lea    0xe33(%rip),%rdx
call   1060 <fprintf@plt>
movzbl (%rbx,%r13,1),%eax
movzbl (%rbx,%r12,1),%ecx
shl    $0x6,%al
and    $0x3f,%cl
jmp    12ae <utf8_to_unicode+0x16e>
mov    %ecx,%eax
and    $0xfffffff0,%eax
cmp    $0xe0,%eax
jne    124b <utf8_to_unicode+0x10b>
movslq %r12d,%rbp
movzbl 0x1(%rbp,%rbx,1),%ecx
mov    %ecx,%eax
and    $0xc0,%al
lea    0x2(%rbp),%r12
cmp    $0x80,%al
jne    1220 <utf8_to_unicode+0xe0>
movzbl (%rbx,%r12,1),%eax
and    $0xc0,%al
cmp    $0x80,%al
je     1241 <utf8_to_unicode+0x101>
mov    0x2db9(%rip),%rax
mov    (%rax),%edi
lea    0xdda(%rip),%rsi
lea    0xdd7(%rip),%rdx
call   1060 <fprintf@plt>
movzbl 0x1(%rbx,%rbp,1),%ecx
shl    $0x6,%cl
movzbl (%rbx,%r12,1),%eax
jmp    12ac <utf8_to_unicode+0x16c>
and    $0xfffffff8,%ecx
cmp    $0xf0,%ecx
jne    12b3 <utf8_to_unicode+0x173>
movslq %r12d,%r12
movzbl 0x1(%r12,%rbx,1),%eax
and    $0xc0,%al
cmp    $0x80,%al
je     1299 <utf8_to_unicode+0x159>
movzbl 0x2(%rbx,%r12,1),%eax
and    $0xc0,%al
cmp    $0x80,%al
je     1299 <utf8_to_unicode+0x159>
movzbl 0x3(%r12,%rbx,1),%eax
and    $0xc0,%al
cmp    $0x80,%al
je     1299 <utf8_to_unicode+0x159>
mov    0x2d5c(%rip),%rax
mov    (%rax),%edi
lea    0xd7d(%rip),%rsi
lea    0xd7a(%rip),%rdx
call   1060 <fprintf@plt>
movzbl 0x2(%rbx,%r12,1),%ecx
shl    $0x6,%cl
movzbl 0x3(%rbx,%r12,1),%eax
add    $0x3,%r12
and    $0x3f,%al
or     %cl,%al
mov    %al,(%r15)
add    $0x1,%r12d
movslq %r12d,%r13
add    $0x1,%r15
cmp    %r13,%r14
ja     1190 <utf8_to_unicode+0x50>
mov    (%rsp),%rax
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@.str = [10 x i8] c"len: %ld\0A\00"
@stderr = global i32 0
@.str.1 = [4 x i8] c"%s\0A\00"
@.str.2 = [14 x i8] c"Invalid utf-8\00"
define i8* @utf8_to_unicode(i8* %0) {
%2 = alloca i8*
%3 = alloca i64
%4 = alloca i8*
%5 = alloca i32
%6 = alloca i32
store i8* %0, i8** %2
%7 = load i8*, i8** %2
%8 = call i64 @strlen(i8* %7)
store i64 %8, i64* %3
%9 = load i64, i64* %3
%10 = call i8* @calloc(i64 %9, i32 1)
store i8* %10, i8** %4
%11 = load i64, i64* %3
%12 = call i32 @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i64 %11)
store i32 0, i32* %5
store i32 0, i32* %6
br label %13
13: ; preds = %268, %1
%14 = load i32, i32* %6
%15 = sext i32 %14 to i64
%16 = load i64, i64* %3
%17 = icmp ult i64 %15, %16
br i1 %17, label %18, label %271
18: ; preds = %13
%19 = load i8*, i8** %2
%20 = load i32, i32* %6
%21 = sext i32 %20 to i64
%22 = getelementptr inbounds i8, i8* %19, i64 %21
%23 = load i8, i8* %22
%24 = zext i8 %23 to i32
%25 = icmp slt i32 %24, 128
br i1 %25, label %26, label %38
26: ; preds = %18
%27 = load i8*, i8** %2
%28 = load i32, i32* %6
%29 = sext i32 %28 to i64
%30 = getelementptr inbounds i8, i8* %27, i64 %29
%31 = load i8, i8* %30
%32 = load i8*, i8** %4
%33 = load i32, i32* %5
%34 = sext i32 %33 to i64
%35 = getelementptr inbounds i8, i8* %32, i64 %34
store i8 %31, i8* %35
%36 = load i32, i32* %5
%37 = add nsw i32 %36, 1
store i32 %37, i32* %5
br label %268
38: ; preds = %18
%39 = load i8*, i8** %2
%40 = load i32, i32* %6
%41 = sext i32 %40 to i64
%42 = getelementptr inbounds i8, i8* %39, i64 %41
%43 = load i8, i8* %42
%44 = zext i8 %43 to i32
%45 = ashr i32 %44, 7
%46 = icmp eq i32 %45, 0
br i1 %46, label %47, label %60
47: ; preds = %38
%48 = load i8*, i8** %2
%49 = load i32, i32* %6
%50 = sext i32 %49 to i64
%51 = getelementptr inbounds i8, i8* %48, i64 %50
%52 = load i8, i8* %51
%53 = zext i8 %52 to i32
%54 = and i32 %53, 127
%55 = trunc i32 %54 to i8
%56 = load i8*, i8** %4
%57 = load i32, i32* %5
%58 = sext i32 %57 to i64
%59 = getelementptr inbounds i8, i8* %56, i64 %58
store i8 %55, i8* %59
br label %264
60: ; preds = %38
%61 = load i8*, i8** %2
%62 = load i32, i32* %6
%63 = sext i32 %62 to i64
%64 = getelementptr inbounds i8, i8* %61, i64 %63
%65 = load i8, i8* %64
%66 = zext i8 %65 to i32
%67 = ashr i32 %66, 5
%68 = icmp eq i32 %67, 6
br i1 %68, label %69, label %107
69: ; preds = %60
%70 = load i8*, i8** %2
%71 = load i32, i32* %6
%72 = add nsw i32 %71, 1
%73 = sext i32 %72 to i64
%74 = getelementptr inbounds i8, i8* %70, i64 %73
%75 = load i8, i8* %74
%76 = zext i8 %75 to i32
%77 = ashr i32 %76, 6
%78 = icmp ne i32 %77, 2
br i1 %78, label %79, label %82
79: ; preds = %69
%80 = load i32, i32* @stderr
%81 = call i32 @fprintf(i32 %80, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i64 0, i64 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.2, i64 0, i64 0))
br label %82
82: ; preds = %79, %69
%83 = load i8*, i8** %2
%84 = load i32, i32* %6
%85 = sext i32 %84 to i64
%86 = getelementptr inbounds i8, i8* %83, i64 %85
%87 = load i8, i8* %86
%88 = zext i8 %87 to i32
%89 = and i32 %88, 31
%90 = shl i32 %89, 6
%91 = load i8*, i8** %2
%92 = load i32, i32* %6
%93 = add nsw i32 %92, 1
%94 = sext i32 %93 to i64
%95 = getelementptr inbounds i8, i8* %91, i64 %94
%96 = load i8, i8* %95
%97 = zext i8 %96 to i32
%98 = and i32 %97, 63
%99 = add nsw i32 %90, %98
%100 = trunc i32 %99 to i8
%101 = load i8*, i8** %4
%102 = load i32, i32* %5
%103 = sext i32 %102 to i64
%104 = getelementptr inbounds i8, i8* %101, i64 %103
store i8 %100, i8* %104
%105 = load i32, i32* %6
%106 = add nsw i32 %105, 1
store i32 %106, i32* %6
br label %263
107: ; preds = %60
%108 = load i8*, i8** %2
%109 = load i32, i32* %6
%110 = sext i32 %109 to i64
%111 = getelementptr inbounds i8, i8* %108, i64 %110
%112 = load i8, i8* %111
%113 = zext i8 %112 to i32
%114 = ashr i32 %113, 4
%115 = icmp eq i32 %114, 14
br i1 %115, label %116, label %174
116: ; preds = %107
%117 = load i8*, i8** %2
%118 = load i32, i32* %6
%119 = add nsw i32 %118, 1
%120 = sext i32 %119 to i64
%121 = getelementptr inbounds i8, i8* %117, i64 %120
%122 = load i8, i8* %121
%123 = zext i8 %122 to i32
%124 = ashr i32 %123, 6
%125 = icmp ne i32 %124, 2
br i1 %125, label %136, label %126
126: ; preds = %116
%127 = load i8*, i8** %2
%128 = load i32, i32* %6
%129 = add nsw i32 %128, 2
%130 = sext i32 %129 to i64
%131 = getelementptr inbounds i8, i8* %127, i64 %130
%132 = load i8, i8* %131
%133 = zext i8 %132 to i32
%134 = ashr i32 %133, 6
%135 = icmp ne i32 %134, 2
br i1 %135, label %136, label %139
136: ; preds = %126, %116
%137 = load i32, i32* @stderr
%138 = call i32 @fprintf(i32 %137, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i64 0, i64 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.2, i64 0, i64 0))
br label %139
139: ; preds = %136, %126
%140 = load i8*, i8** %2
%141 = load i32, i32* %6
%142 = sext i32 %141 to i64
%143 = getelementptr inbounds i8, i8* %140, i64 %142
%144 = load i8, i8* %143
%145 = zext i8 %144 to i32
%146 = and i32 %145, 15
%147 = shl i32 %146, 12
%148 = load i8*, i8** %2
%149 = load i32, i32* %6
%150 = add nsw i32 %149, 1
%151 = sext i32 %150 to i64
%152 = getelementptr inbounds i8, i8* %148, i64 %151
%153 = load i8, i8* %152
%154 = zext i8 %153 to i32
%155 = and i32 %154, 63
%156 = shl i32 %155, 6
%157 = add nsw i32 %147, %156
%158 = load i8*, i8** %2
%159 = load i32, i32* %6
%160 = add nsw i32 %159, 2
%161 = sext i32 %160 to i64
%162 = getelementptr inbounds i8, i8* %158, i64 %161
%163 = load i8, i8* %162
%164 = zext i8 %163 to i32
%165 = and i32 %164, 63
%166 = add nsw i32 %157, %165
%167 = trunc i32 %166 to i8
%168 = load i8*, i8** %4
%169 = load i32, i32* %5
%170 = sext i32 %169 to i64
%171 = getelementptr inbounds i8, i8* %168, i64 %170
store i8 %167, i8* %171
%172 = load i32, i32* %6
%173 = add nsw i32 %172, 2
store i32 %173, i32* %6
br label %262
174: ; preds = %107
%175 = load i8*, i8** %2
%176 = load i32, i32* %6
%177 = sext i32 %176 to i64
%178 = getelementptr inbounds i8, i8* %175, i64 %177
%179 = load i8, i8* %178
%180 = zext i8 %179 to i32
%181 = ashr i32 %180, 3
%182 = icmp eq i32 %181, 30
br i1 %182, label %183, label %261
183: ; preds = %174
%184 = load i8*, i8** %2
%185 = load i32, i32* %6
%186 = add nsw i32 %185, 1
%187 = sext i32 %186 to i64
%188 = getelementptr inbounds i8, i8* %184, i64 %187
%189 = load i8, i8* %188
%190 = zext i8 %189 to i32
%191 = ashr i32 %190, 6
%192 = icmp ne i32 %191, 2
br i1 %192, label %193, label %216
193: ; preds = %183
%194 = load i8*, i8** %2
%195 = load i32, i32* %6
%196 = add nsw i32 %195, 2
%197 = sext i32 %196 to i64
%198 = getelementptr inbounds i8, i8* %194, i64 %197
%199 = load i8, i8* %198
%200 = zext i8 %199 to i32
%201 = ashr i32 %200, 6
%202 = icmp ne i32 %201, 2
br i1 %202, label %203, label %216
203: ; preds = %193
%204 = load i8*, i8** %2
%205 = load i32, i32* %6
%206 = add nsw i32 %205, 3
%207 = sext i32 %206 to i64
%208 = getelementptr inbounds i8, i8* %204, i64 %207
%209 = load i8, i8* %208
%210 = zext i8 %209 to i32
%211 = ashr i32 %210, 6
%212 = icmp ne i32 %211, 2
br i1 %212, label %213, label %216
213: ; preds = %203
%214 = load i32, i32* @stderr
%215 = call i32 @fprintf(i32 %214, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i64 0, i64 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.2, i64 0, i64 0))
br label %216
216: ; preds = %213, %203, %193, %183
%217 = load i8*, i8** %2
%218 = load i32, i32* %6
%219 = sext i32 %218 to i64
%220 = getelementptr inbounds i8, i8* %217, i64 %219
%221 = load i8, i8* %220
%222 = zext i8 %221 to i32
%223 = and i32 %222, 15
%224 = shl i32 %223, 18
%225 = load i8*, i8** %2
%226 = load i32, i32* %6
%227 = add nsw i32 %226, 1
%228 = sext i32 %227 to i64
%229 = getelementptr inbounds i8, i8* %225, i64 %228
%230 = load i8, i8* %229
%231 = zext i8 %230 to i32
%232 = and i32 %231, 63
%233 = shl i32 %232, 12
%234 = add nsw i32 %224, %233
%235 = load i8*, i8** %2
%236 = load i32, i32* %6
%237 = add nsw i32 %236, 2
%238 = sext i32 %237 to i64
%239 = getelementptr inbounds i8, i8* %235, i64 %238
%240 = load i8, i8* %239
%241 = zext i8 %240 to i32
%242 = and i32 %241, 63
%243 = shl i32 %242, 6
%244 = add nsw i32 %234, %243
%245 = load i8*, i8** %2
%246 = load i32, i32* %6
%247 = add nsw i32 %246, 3
%248 = sext i32 %247 to i64
%249 = getelementptr inbounds i8, i8* %245, i64 %248
%250 = load i8, i8* %249
%251 = zext i8 %250 to i32
%252 = and i32 %251, 63
%253 = add nsw i32 %244, %252
%254 = trunc i32 %253 to i8
%255 = load i8*, i8** %4
%256 = load i32, i32* %5
%257 = sext i32 %256 to i64
%258 = getelementptr inbounds i8, i8* %255, i64 %257
store i8 %254, i8* %258
%259 = load i32, i32* %6
%260 = add nsw i32 %259, 3
store i32 %260, i32* %6
br label %261
261: ; preds = %216, %174
br label %262
262: ; preds = %261, %139
br label %263
263: ; preds = %262, %82
br label %264
264: ; preds = %263, %47
%265 = load i32, i32* %5
%266 = add nsw i32 %265, 1
store i32 %266, i32* %5
br label %267
267: ; preds = %264
br label %268
268: ; preds = %267, %26
%269 = load i32, i32* %6
%270 = add nsw i32 %269, 1
store i32 %270, i32* %6
br label %13
271: ; preds = %13
%272 = load i8*, i8** %4
ret i8* %272
}

LLVM IR (-O2):
@.str = [10 x i8] c"len: %ld\0A\00"
@stderr = global i32 0
@.str.1 = [4 x i8] c"%s\0A\00"
@.str.2 = [14 x i8] c"Invalid utf-8\00"
define i8* @utf8_to_unicode(i8* nocapture %0) {
%2 = tail call i64 @strlen(i8* dereferenceable(1) %0)
%3 = tail call i8* @calloc(i64 %2, i32 1)
%4 = tail call i32 @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i64 %2)
%5 = icmp eq i64 %2, 0
br i1 %5, label %6, label %7
6: ; preds = %105, %1
ret i8* %3
7: ; preds = %1, %105
%8 = phi i64 [ %107, %105 ], [ 0, %1 ]
%9 = phi i64 [ %109, %105 ], [ 0, %1 ]
%10 = phi i32 [ %108, %105 ], [ 0, %1 ]
%11 = getelementptr inbounds i8, i8* %0, i64 %9
%12 = load i8, i8* %11
%13 = zext i8 %12 to i32
%14 = icmp sgt i8 %12, -1
br i1 %14, label %101, label %15
15: ; preds = %7
%16 = and i32 %13, 224
%17 = icmp eq i32 %16, 192
br i1 %17, label %18, label %36
18: ; preds = %15
%19 = add nsw i32 %10, 1
%20 = sext i32 %19 to i64
%21 = getelementptr inbounds i8, i8* %0, i64 %20
%22 = load i8, i8* %21
%23 = and i8 %22, -64
%24 = icmp eq i8 %23, -128
br i1 %24, label %30, label %25
25: ; preds = %18
%26 = load i32, i32* @stderr
%27 = tail call i32 @fprintf(i32 %26, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i64 0, i64 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.2, i64 0, i64 0))
%28 = load i8, i8* %11
%29 = load i8, i8* %21
br label %30
30: ; preds = %25, %18
%31 = phi i8 [ %29, %25 ], [ %22, %18 ]
%32 = phi i8 [ %28, %25 ], [ %12, %18 ]
%33 = shl i8 %32, 6
%34 = and i8 %31, 63
%35 = or i8 %34, %33
br label %101
36: ; preds = %15
%37 = and i32 %13, 240
%38 = icmp eq i32 %37, 224
br i1 %38, label %39, label %64
39: ; preds = %36
%40 = add nsw i32 %10, 1
%41 = sext i32 %40 to i64
%42 = getelementptr inbounds i8, i8* %0, i64 %41
%43 = load i8, i8* %42
%44 = and i8 %43, -64
%45 = icmp eq i8 %44, -128
%46 = add nsw i32 %10, 2
%47 = sext i32 %46 to i64
br i1 %45, label %48, label %53
48: ; preds = %39
%49 = getelementptr inbounds i8, i8* %0, i64 %47
%50 = load i8, i8* %49
%51 = and i8 %50, -64
%52 = icmp eq i8 %51, -128
br i1 %52, label %57, label %53
53: ; preds = %39, %48
%54 = load i32, i32* @stderr
%55 = tail call i32 @fprintf(i32 %54, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i64 0, i64 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.2, i64 0, i64 0))
%56 = load i8, i8* %42
br label %57
57: ; preds = %53, %48
%58 = phi i8 [ %56, %53 ], [ %43, %48 ]
%59 = shl i8 %58, 6
%60 = getelementptr inbounds i8, i8* %0, i64 %47
%61 = load i8, i8* %60
%62 = and i8 %61, 63
%63 = or i8 %62, %59
br label %101
64: ; preds = %36
%65 = and i32 %13, 248
%66 = icmp eq i32 %65, 240
br i1 %66, label %67, label %105
67: ; preds = %64
%68 = add nsw i32 %10, 1
%69 = sext i32 %68 to i64
%70 = getelementptr inbounds i8, i8* %0, i64 %69
%71 = load i8, i8* %70
%72 = and i8 %71, -64
%73 = icmp eq i8 %72, -128
%74 = add nsw i32 %10, 2
%75 = sext i32 %74 to i64
br i1 %73, label %91, label %76
76: ; preds = %67
%77 = getelementptr inbounds i8, i8* %0, i64 %75
%78 = load i8, i8* %77
%79 = and i8 %78, -64
%80 = icmp eq i8 %79, -128
br i1 %80, label %91, label %81
81: ; preds = %76
%82 = add nsw i32 %10, 3
%83 = sext i32 %82 to i64
%84 = getelementptr inbounds i8, i8* %0, i64 %83
%85 = load i8, i8* %84
%86 = and i8 %85, -64
%87 = icmp eq i8 %86, -128
br i1 %87, label %91, label %88
88: ; preds = %81
%89 = load i32, i32* @stderr
%90 = tail call i32 @fprintf(i32 %89, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i64 0, i64 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.2, i64 0, i64 0))
br label %91
91: ; preds = %67, %88, %81, %76
%92 = getelementptr inbounds i8, i8* %0, i64 %75
%93 = load i8, i8* %92
%94 = shl i8 %93, 6
%95 = add nsw i32 %10, 3
%96 = sext i32 %95 to i64
%97 = getelementptr inbounds i8, i8* %0, i64 %96
%98 = load i8, i8* %97
%99 = and i8 %98, 63
%100 = or i8 %99, %94
br label %101
101: ; preds = %7, %30, %91, %57
%102 = phi i8 [ %63, %57 ], [ %100, %91 ], [ %35, %30 ], [ %12, %7 ]
%103 = phi i32 [ %46, %57 ], [ %95, %91 ], [ %19, %30 ], [ %10, %7 ]
%104 = getelementptr inbounds i8, i8* %3, i64 %8
store i8 %102, i8* %104
br label %105
105: ; preds = %101, %64
%106 = phi i32 [ %10, %64 ], [ %103, %101 ]
%107 = add nuw i64 %8, 1
%108 = add nsw i32 %106, 1
%109 = sext i32 %108 to i64
%110 = icmp ugt i64 %2, %109
br i1 %110, label %7, label %6
}