char *unicode_to_utf8(char *d, int *s, int n) {
  int i, j;
  for (i = j = 0; i < n; i++) {
    if (s[i] <= 0x7f)
      d[j++] = s[i];
    else if (s[i] <= 0x7ff) {
      d[j++] = 0xc0 | ((s[i] >> 6) & 0x1f);
      d[j++] = 0x80 | (s[i] & 0x3f);
    } else if (s[i] <= 0xffff) {
      d[j++] = 0xe0 | ((s[i] >> 12) & 0xf);
      d[j++] = 0x80 | ((s[i] >> 6) & 0x3f);
      d[j++] = 0x80 | (s[i] & 0x3f);
    } else if (s[i] <= 0x1fffff) {
      d[j++] = 0xf0 | ((s[i] >> 18) & 0x7);
      d[j++] = 0x80 | ((s[i] >> 12) & 0x3f);
      d[j++] = 0x80 | ((s[i] >> 6) & 0x3f);
      d[j++] = 0x80 | (s[i] & 0x3f);
    } else if (s[i] <= 0x3ffffff) {
      d[j++] = 0xf8 | ((s[i] >> 24) & 0x3);
      d[j++] = 0x80 | ((s[i] >> 18) & 0x3f);
      d[j++] = 0x80 | ((s[i] >> 12) & 0x3f);
      d[j++] = 0x80 | ((s[i] >> 6) & 0x3f);
      d[j++] = 0x80 | (s[i] & 0x3f);
    } else {
      d[j++] = 0xf8 | ((s[i] >> 30) & 0x1);
      d[j++] = 0x80 | ((s[i] >> 24) & 0x3f);
      d[j++] = 0x80 | ((s[i] >> 18) & 0x3f);
      d[j++] = 0x80 | ((s[i] >> 12) & 0x3f);
      d[j++] = 0x80 | ((s[i] >> 6) & 0x3f);
      d[j++] = 0x80 | (s[i] & 0x3f);
    }
  }
  d[j] = '\0';
  return (d);
}


x86 assembly (clang, -O0):
<unicode_to_utf8>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
movl   $0x0,-0x1c(%rbp)
movl   $0x0,-0x18(%rbp)
mov    -0x18(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    1566 <unicode_to_utf8+0x466>
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
cmpl   $0x7f,(%rax,%rcx,4)
jg     1162 <unicode_to_utf8+0x62>
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x1c(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
jmp    1553 <unicode_to_utf8+0x453>
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
cmpl   $0x7ff,(%rax,%rcx,4)
jg     11d3 <unicode_to_utf8+0xd3>
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
sar    $0x6,%eax
and    $0x1f,%eax
or     $0xc0,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x1c(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x1c(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
jmp    154e <unicode_to_utf8+0x44e>
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
cmpl   $0xffff,(%rax,%rcx,4)
jg     1271 <unicode_to_utf8+0x171>
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
sar    $0xc,%eax
and    $0xf,%eax
or     $0xe0,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x1c(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
sar    $0x6,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x1c(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x1c(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
jmp    1549 <unicode_to_utf8+0x449>
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
cmpl   $0x1fffff,(%rax,%rcx,4)
jg     133c <unicode_to_utf8+0x23c>
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
sar    $0x12,%eax
and    $0x7,%eax
or     $0xf0,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x1c(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
sar    $0xc,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x1c(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
sar    $0x6,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x1c(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x1c(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
jmp    1544 <unicode_to_utf8+0x444>
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
cmpl   $0x3ffffff,(%rax,%rcx,4)
jg     1434 <unicode_to_utf8+0x334>
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
sar    $0x18,%eax
and    $0x3,%eax
or     $0xf8,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x1c(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
sar    $0x12,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x1c(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
sar    $0xc,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x1c(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
sar    $0x6,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x1c(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x1c(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
jmp    153f <unicode_to_utf8+0x43f>
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
sar    $0x1e,%eax
and    $0x1,%eax
or     $0xf8,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x1c(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
sar    $0x18,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x1c(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
sar    $0x12,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x1c(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
sar    $0xc,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x1c(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
sar    $0x6,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x1c(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x1c(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
jmp    1544 <unicode_to_utf8+0x444>
jmp    1549 <unicode_to_utf8+0x449>
jmp    154e <unicode_to_utf8+0x44e>
jmp    1553 <unicode_to_utf8+0x453>
jmp    1558 <unicode_to_utf8+0x458>
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    111d <unicode_to_utf8+0x1d>
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<unicode_to_utf8>:
mov    %rdi,%rax
xor    %r11d,%r11d
test   %edx,%edx
jle    12b9 <unicode_to_utf8+0x1b9>
mov    %edx,%r8d
xor    %edi,%edi
jmp    113e <unicode_to_utf8+0x3e>
cs nopw 0x0(%rax,%rax,1)
nop
mov    $0x1,%ecx
mov    %r11d,%r10d
add    %ecx,%r11d
movslq %r10d,%rcx
mov    %dl,(%rax,%rcx,1)
add    $0x1,%rdi
cmp    %rdi,%r8
je     12b6 <unicode_to_utf8+0x1b6>
mov    (%rsi,%rdi,4),%edx
cmp    $0x7f,%edx
jle    1120 <unicode_to_utf8+0x20>
mov    %r11d,%r9d
cmp    $0x7ff,%edx
ja     1170 <unicode_to_utf8+0x70>
shr    $0x6,%edx
or     $0xc0,%dl
lea    0x1(%r11),%r10d
mov    %dl,(%rax,%r9,1)
movzbl (%rsi,%rdi,4),%edx
and    $0x3f,%dl
or     $0x80,%dl
mov    $0x2,%ecx
jmp    1128 <unicode_to_utf8+0x28>
cmp    $0xffff,%edx
ja     11a8 <unicode_to_utf8+0xa8>
shr    $0xc,%edx
or     $0xe0,%dl
mov    %dl,(%rax,%r9,1)
mov    (%rsi,%rdi,4),%ecx
shr    $0x6,%ecx
and    $0x3f,%cl
or     $0x80,%cl
lea    0x2(%r11),%r10d
mov    %cl,0x1(%rax,%r9,1)
movzbl (%rsi,%rdi,4),%edx
and    $0x3f,%dl
or     $0x80,%dl
mov    $0x3,%ecx
jmp    1128 <unicode_to_utf8+0x28>
cmp    $0x1fffff,%edx
ja     11f4 <unicode_to_utf8+0xf4>
shr    $0x12,%edx
or     $0xf0,%dl
mov    %dl,(%rax,%r9,1)
mov    (%rsi,%rdi,4),%ecx
shr    $0xc,%ecx
and    $0x3f,%cl
or     $0x80,%cl
mov    %cl,0x1(%rax,%r9,1)
mov    (%rsi,%rdi,4),%ecx
shr    $0x6,%ecx
and    $0x3f,%cl
or     $0x80,%cl
lea    0x3(%r11),%r10d
mov    %cl,0x2(%rax,%r9,1)
movzbl (%rsi,%rdi,4),%edx
and    $0x3f,%dl
or     $0x80,%dl
mov    $0x4,%ecx
jmp    1128 <unicode_to_utf8+0x28>
cmp    $0x3ffffff,%edx
ja     1251 <unicode_to_utf8+0x151>
shr    $0x18,%edx
or     $0xf8,%dl
mov    %dl,(%rax,%r9,1)
mov    (%rsi,%rdi,4),%ecx
shr    $0x12,%ecx
and    $0x3f,%cl
or     $0x80,%cl
mov    %cl,0x1(%rax,%r9,1)
mov    (%rsi,%rdi,4),%ecx
shr    $0xc,%ecx
and    $0x3f,%cl
or     $0x80,%cl
mov    %cl,0x2(%rax,%r9,1)
mov    (%rsi,%rdi,4),%ecx
shr    $0x6,%ecx
and    $0x3f,%cl
or     $0x80,%cl
lea    0x4(%r11),%r10d
mov    %cl,0x3(%rax,%r9,1)
movzbl (%rsi,%rdi,4),%edx
and    $0x3f,%dl
or     $0x80,%dl
mov    $0x5,%ecx
jmp    1128 <unicode_to_utf8+0x28>
shr    $0x1e,%edx
or     $0xf8,%dl
mov    %dl,(%rax,%r9,1)
movzbl 0x3(%rsi,%rdi,4),%ecx
and    $0x3f,%cl
or     $0x80,%cl
mov    %cl,0x1(%rax,%r9,1)
mov    (%rsi,%rdi,4),%ecx
shr    $0x12,%ecx
and    $0x3f,%cl
or     $0x80,%cl
mov    %cl,0x2(%rax,%r9,1)
mov    (%rsi,%rdi,4),%ecx
shr    $0xc,%ecx
and    $0x3f,%cl
or     $0x80,%cl
mov    %cl,0x3(%rax,%r9,1)
mov    (%rsi,%rdi,4),%ecx
shr    $0x6,%ecx
and    $0x3f,%cl
or     $0x80,%cl
lea    0x5(%r11),%r10d
mov    %cl,0x4(%rax,%r9,1)
movzbl (%rsi,%rdi,4),%edx
and    $0x3f,%dl
or     $0x80,%dl
mov    $0x6,%ecx
jmp    1128 <unicode_to_utf8+0x28>
mov    %r11d,%r11d
movb   $0x0,(%rax,%r11,1)
ret

LLVM IR (-O0):
define i8* @unicode_to_utf8(i8* %0, i32* %1, i32 %2) {
%4 = alloca i8*
%5 = alloca i32*
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
store i8* %0, i8** %4
store i32* %1, i32** %5
store i32 %2, i32* %6
store i32 0, i32* %8
store i32 0, i32* %7
br label %9
9: ; preds = %345, %3
%10 = load i32, i32* %7
%11 = load i32, i32* %6
%12 = icmp slt i32 %10, %11
br i1 %12, label %13, label %348
13: ; preds = %9
%14 = load i32*, i32** %5
%15 = load i32, i32* %7
%16 = sext i32 %15 to i64
%17 = getelementptr inbounds i32, i32* %14, i64 %16
%18 = load i32, i32* %17
%19 = icmp sle i32 %18, 127
br i1 %19, label %20, label %32
20: ; preds = %13
%21 = load i32*, i32** %5
%22 = load i32, i32* %7
%23 = sext i32 %22 to i64
%24 = getelementptr inbounds i32, i32* %21, i64 %23
%25 = load i32, i32* %24
%26 = trunc i32 %25 to i8
%27 = load i8*, i8** %4
%28 = load i32, i32* %8
%29 = add nsw i32 %28, 1
store i32 %29, i32* %8
%30 = sext i32 %28 to i64
%31 = getelementptr inbounds i8, i8* %27, i64 %30
store i8 %26, i8* %31
br label %344
32: ; preds = %13
%33 = load i32*, i32** %5
%34 = load i32, i32* %7
%35 = sext i32 %34 to i64
%36 = getelementptr inbounds i32, i32* %33, i64 %35
%37 = load i32, i32* %36
%38 = icmp sle i32 %37, 2047
br i1 %38, label %39, label %67
39: ; preds = %32
%40 = load i32*, i32** %5
%41 = load i32, i32* %7
%42 = sext i32 %41 to i64
%43 = getelementptr inbounds i32, i32* %40, i64 %42
%44 = load i32, i32* %43
%45 = ashr i32 %44, 6
%46 = and i32 %45, 31
%47 = or i32 192, %46
%48 = trunc i32 %47 to i8
%49 = load i8*, i8** %4
%50 = load i32, i32* %8
%51 = add nsw i32 %50, 1
store i32 %51, i32* %8
%52 = sext i32 %50 to i64
%53 = getelementptr inbounds i8, i8* %49, i64 %52
store i8 %48, i8* %53
%54 = load i32*, i32** %5
%55 = load i32, i32* %7
%56 = sext i32 %55 to i64
%57 = getelementptr inbounds i32, i32* %54, i64 %56
%58 = load i32, i32* %57
%59 = and i32 %58, 63
%60 = or i32 128, %59
%61 = trunc i32 %60 to i8
%62 = load i8*, i8** %4
%63 = load i32, i32* %8
%64 = add nsw i32 %63, 1
store i32 %64, i32* %8
%65 = sext i32 %63 to i64
%66 = getelementptr inbounds i8, i8* %62, i64 %65
store i8 %61, i8* %66
br label %343
67: ; preds = %32
%68 = load i32*, i32** %5
%69 = load i32, i32* %7
%70 = sext i32 %69 to i64
%71 = getelementptr inbounds i32, i32* %68, i64 %70
%72 = load i32, i32* %71
%73 = icmp sle i32 %72, 65535
br i1 %73, label %74, label %116
74: ; preds = %67
%75 = load i32*, i32** %5
%76 = load i32, i32* %7
%77 = sext i32 %76 to i64
%78 = getelementptr inbounds i32, i32* %75, i64 %77
%79 = load i32, i32* %78
%80 = ashr i32 %79, 12
%81 = and i32 %80, 15
%82 = or i32 224, %81
%83 = trunc i32 %82 to i8
%84 = load i8*, i8** %4
%85 = load i32, i32* %8
%86 = add nsw i32 %85, 1
store i32 %86, i32* %8
%87 = sext i32 %85 to i64
%88 = getelementptr inbounds i8, i8* %84, i64 %87
store i8 %83, i8* %88
%89 = load i32*, i32** %5
%90 = load i32, i32* %7
%91 = sext i32 %90 to i64
%92 = getelementptr inbounds i32, i32* %89, i64 %91
%93 = load i32, i32* %92
%94 = ashr i32 %93, 6
%95 = and i32 %94, 63
%96 = or i32 128, %95
%97 = trunc i32 %96 to i8
%98 = load i8*, i8** %4
%99 = load i32, i32* %8
%100 = add nsw i32 %99, 1
store i32 %100, i32* %8
%101 = sext i32 %99 to i64
%102 = getelementptr inbounds i8, i8* %98, i64 %101
store i8 %97, i8* %102
%103 = load i32*, i32** %5
%104 = load i32, i32* %7
%105 = sext i32 %104 to i64
%106 = getelementptr inbounds i32, i32* %103, i64 %105
%107 = load i32, i32* %106
%108 = and i32 %107, 63
%109 = or i32 128, %108
%110 = trunc i32 %109 to i8
%111 = load i8*, i8** %4
%112 = load i32, i32* %8
%113 = add nsw i32 %112, 1
store i32 %113, i32* %8
%114 = sext i32 %112 to i64
%115 = getelementptr inbounds i8, i8* %111, i64 %114
store i8 %110, i8* %115
br label %342
116: ; preds = %67
%117 = load i32*, i32** %5
%118 = load i32, i32* %7
%119 = sext i32 %118 to i64
%120 = getelementptr inbounds i32, i32* %117, i64 %119
%121 = load i32, i32* %120
%122 = icmp sle i32 %121, 2097151
br i1 %122, label %123, label %179
123: ; preds = %116
%124 = load i32*, i32** %5
%125 = load i32, i32* %7
%126 = sext i32 %125 to i64
%127 = getelementptr inbounds i32, i32* %124, i64 %126
%128 = load i32, i32* %127
%129 = ashr i32 %128, 18
%130 = and i32 %129, 7
%131 = or i32 240, %130
%132 = trunc i32 %131 to i8
%133 = load i8*, i8** %4
%134 = load i32, i32* %8
%135 = add nsw i32 %134, 1
store i32 %135, i32* %8
%136 = sext i32 %134 to i64
%137 = getelementptr inbounds i8, i8* %133, i64 %136
store i8 %132, i8* %137
%138 = load i32*, i32** %5
%139 = load i32, i32* %7
%140 = sext i32 %139 to i64
%141 = getelementptr inbounds i32, i32* %138, i64 %140
%142 = load i32, i32* %141
%143 = ashr i32 %142, 12
%144 = and i32 %143, 63
%145 = or i32 128, %144
%146 = trunc i32 %145 to i8
%147 = load i8*, i8** %4
%148 = load i32, i32* %8
%149 = add nsw i32 %148, 1
store i32 %149, i32* %8
%150 = sext i32 %148 to i64
%151 = getelementptr inbounds i8, i8* %147, i64 %150
store i8 %146, i8* %151
%152 = load i32*, i32** %5
%153 = load i32, i32* %7
%154 = sext i32 %153 to i64
%155 = getelementptr inbounds i32, i32* %152, i64 %154
%156 = load i32, i32* %155
%157 = ashr i32 %156, 6
%158 = and i32 %157, 63
%159 = or i32 128, %158
%160 = trunc i32 %159 to i8
%161 = load i8*, i8** %4
%162 = load i32, i32* %8
%163 = add nsw i32 %162, 1
store i32 %163, i32* %8
%164 = sext i32 %162 to i64
%165 = getelementptr inbounds i8, i8* %161, i64 %164
store i8 %160, i8* %165
%166 = load i32*, i32** %5
%167 = load i32, i32* %7
%168 = sext i32 %167 to i64
%169 = getelementptr inbounds i32, i32* %166, i64 %168
%170 = load i32, i32* %169
%171 = and i32 %170, 63
%172 = or i32 128, %171
%173 = trunc i32 %172 to i8
%174 = load i8*, i8** %4
%175 = load i32, i32* %8
%176 = add nsw i32 %175, 1
store i32 %176, i32* %8
%177 = sext i32 %175 to i64
%178 = getelementptr inbounds i8, i8* %174, i64 %177
store i8 %173, i8* %178
br label %341
179: ; preds = %116
%180 = load i32*, i32** %5
%181 = load i32, i32* %7
%182 = sext i32 %181 to i64
%183 = getelementptr inbounds i32, i32* %180, i64 %182
%184 = load i32, i32* %183
%185 = icmp sle i32 %184, 67108863
br i1 %185, label %186, label %256
186: ; preds = %179
%187 = load i32*, i32** %5
%188 = load i32, i32* %7
%189 = sext i32 %188 to i64
%190 = getelementptr inbounds i32, i32* %187, i64 %189
%191 = load i32, i32* %190
%192 = ashr i32 %191, 24
%193 = and i32 %192, 3
%194 = or i32 248, %193
%195 = trunc i32 %194 to i8
%196 = load i8*, i8** %4
%197 = load i32, i32* %8
%198 = add nsw i32 %197, 1
store i32 %198, i32* %8
%199 = sext i32 %197 to i64
%200 = getelementptr inbounds i8, i8* %196, i64 %199
store i8 %195, i8* %200
%201 = load i32*, i32** %5
%202 = load i32, i32* %7
%203 = sext i32 %202 to i64
%204 = getelementptr inbounds i32, i32* %201, i64 %203
%205 = load i32, i32* %204
%206 = ashr i32 %205, 18
%207 = and i32 %206, 63
%208 = or i32 128, %207
%209 = trunc i32 %208 to i8
%210 = load i8*, i8** %4
%211 = load i32, i32* %8
%212 = add nsw i32 %211, 1
store i32 %212, i32* %8
%213 = sext i32 %211 to i64
%214 = getelementptr inbounds i8, i8* %210, i64 %213
store i8 %209, i8* %214
%215 = load i32*, i32** %5
%216 = load i32, i32* %7
%217 = sext i32 %216 to i64
%218 = getelementptr inbounds i32, i32* %215, i64 %217
%219 = load i32, i32* %218
%220 = ashr i32 %219, 12
%221 = and i32 %220, 63
%222 = or i32 128, %221
%223 = trunc i32 %222 to i8
%224 = load i8*, i8** %4
%225 = load i32, i32* %8
%226 = add nsw i32 %225, 1
store i32 %226, i32* %8
%227 = sext i32 %225 to i64
%228 = getelementptr inbounds i8, i8* %224, i64 %227
store i8 %223, i8* %228
%229 = load i32*, i32** %5
%230 = load i32, i32* %7
%231 = sext i32 %230 to i64
%232 = getelementptr inbounds i32, i32* %229, i64 %231
%233 = load i32, i32* %232
%234 = ashr i32 %233, 6
%235 = and i32 %234, 63
%236 = or i32 128, %235
%237 = trunc i32 %236 to i8
%238 = load i8*, i8** %4
%239 = load i32, i32* %8
%240 = add nsw i32 %239, 1
store i32 %240, i32* %8
%241 = sext i32 %239 to i64
%242 = getelementptr inbounds i8, i8* %238, i64 %241
store i8 %237, i8* %242
%243 = load i32*, i32** %5
%244 = load i32, i32* %7
%245 = sext i32 %244 to i64
%246 = getelementptr inbounds i32, i32* %243, i64 %245
%247 = load i32, i32* %246
%248 = and i32 %247, 63
%249 = or i32 128, %248
%250 = trunc i32 %249 to i8
%251 = load i8*, i8** %4
%252 = load i32, i32* %8
%253 = add nsw i32 %252, 1
store i32 %253, i32* %8
%254 = sext i32 %252 to i64
%255 = getelementptr inbounds i8, i8* %251, i64 %254
store i8 %250, i8* %255
br label %340
256: ; preds = %179
%257 = load i32*, i32** %5
%258 = load i32, i32* %7
%259 = sext i32 %258 to i64
%260 = getelementptr inbounds i32, i32* %257, i64 %259
%261 = load i32, i32* %260
%262 = ashr i32 %261, 30
%263 = and i32 %262, 1
%264 = or i32 248, %263
%265 = trunc i32 %264 to i8
%266 = load i8*, i8** %4
%267 = load i32, i32* %8
%268 = add nsw i32 %267, 1
store i32 %268, i32* %8
%269 = sext i32 %267 to i64
%270 = getelementptr inbounds i8, i8* %266, i64 %269
store i8 %265, i8* %270
%271 = load i32*, i32** %5
%272 = load i32, i32* %7
%273 = sext i32 %272 to i64
%274 = getelementptr inbounds i32, i32* %271, i64 %273
%275 = load i32, i32* %274
%276 = ashr i32 %275, 24
%277 = and i32 %276, 63
%278 = or i32 128, %277
%279 = trunc i32 %278 to i8
%280 = load i8*, i8** %4
%281 = load i32, i32* %8
%282 = add nsw i32 %281, 1
store i32 %282, i32* %8
%283 = sext i32 %281 to i64
%284 = getelementptr inbounds i8, i8* %280, i64 %283
store i8 %279, i8* %284
%285 = load i32*, i32** %5
%286 = load i32, i32* %7
%287 = sext i32 %286 to i64
%288 = getelementptr inbounds i32, i32* %285, i64 %287
%289 = load i32, i32* %288
%290 = ashr i32 %289, 18
%291 = and i32 %290, 63
%292 = or i32 128, %291
%293 = trunc i32 %292 to i8
%294 = load i8*, i8** %4
%295 = load i32, i32* %8
%296 = add nsw i32 %295, 1
store i32 %296, i32* %8
%297 = sext i32 %295 to i64
%298 = getelementptr inbounds i8, i8* %294, i64 %297
store i8 %293, i8* %298
%299 = load i32*, i32** %5
%300 = load i32, i32* %7
%301 = sext i32 %300 to i64
%302 = getelementptr inbounds i32, i32* %299, i64 %301
%303 = load i32, i32* %302
%304 = ashr i32 %303, 12
%305 = and i32 %304, 63
%306 = or i32 128, %305
%307 = trunc i32 %306 to i8
%308 = load i8*, i8** %4
%309 = load i32, i32* %8
%310 = add nsw i32 %309, 1
store i32 %310, i32* %8
%311 = sext i32 %309 to i64
%312 = getelementptr inbounds i8, i8* %308, i64 %311
store i8 %307, i8* %312
%313 = load i32*, i32** %5
%314 = load i32, i32* %7
%315 = sext i32 %314 to i64
%316 = getelementptr inbounds i32, i32* %313, i64 %315
%317 = load i32, i32* %316
%318 = ashr i32 %317, 6
%319 = and i32 %318, 63
%320 = or i32 128, %319
%321 = trunc i32 %320 to i8
%322 = load i8*, i8** %4
%323 = load i32, i32* %8
%324 = add nsw i32 %323, 1
store i32 %324, i32* %8
%325 = sext i32 %323 to i64
%326 = getelementptr inbounds i8, i8* %322, i64 %325
store i8 %321, i8* %326
%327 = load i32*, i32** %5
%328 = load i32, i32* %7
%329 = sext i32 %328 to i64
%330 = getelementptr inbounds i32, i32* %327, i64 %329
%331 = load i32, i32* %330
%332 = and i32 %331, 63
%333 = or i32 128, %332
%334 = trunc i32 %333 to i8
%335 = load i8*, i8** %4
%336 = load i32, i32* %8
%337 = add nsw i32 %336, 1
store i32 %337, i32* %8
%338 = sext i32 %336 to i64
%339 = getelementptr inbounds i8, i8* %335, i64 %338
store i8 %334, i8* %339
br label %340
340: ; preds = %256, %186
br label %341
341: ; preds = %340, %123
br label %342
342: ; preds = %341, %74
br label %343
343: ; preds = %342, %39
br label %344
344: ; preds = %343, %20
br label %345
345: ; preds = %344
%346 = load i32, i32* %7
%347 = add nsw i32 %346, 1
store i32 %347, i32* %7
br label %9
348: ; preds = %9
%349 = load i8*, i8** %4
%350 = load i32, i32* %8
%351 = sext i32 %350 to i64
%352 = getelementptr inbounds i8, i8* %349, i64 %351
store i8 0, i8* %352
%353 = load i8*, i8** %4
ret i8* %353
}

LLVM IR (-O2):
define i8* @unicode_to_utf8(i8* returned writeonly %0, i32* nocapture %1, i32 %2) {
%4 = icmp sgt i32 %2, 0
br i1 %4, label %5, label %169
5: ; preds = %3
%6 = zext i32 %2 to i64
br label %7
7: ; preds = %5, %158
%8 = phi i64 [ 0, %5 ], [ %165, %158 ]
%9 = phi i32 [ 0, %5 ], [ %162, %158 ]
%10 = getelementptr inbounds i32, i32* %1, i64 %8
%11 = load i32, i32* %10
%12 = icmp slt i32 %11, 128
br i1 %12, label %13, label %15
13: ; preds = %7
%14 = trunc i32 %11 to i8
br label %158
15: ; preds = %7
%16 = icmp ult i32 %11, 2048
br i1 %16, label %17, label %28
17: ; preds = %15
%18 = lshr i32 %11, 6
%19 = trunc i32 %18 to i8
%20 = or i8 %19, -64
%21 = add nuw nsw i32 %9, 1
%22 = zext i32 %9 to i64
%23 = getelementptr inbounds i8, i8* %0, i64 %22
store i8 %20, i8* %23
%24 = load i32, i32* %10
%25 = trunc i32 %24 to i8
%26 = and i8 %25, 63
%27 = or i8 %26, -128
br label %158
28: ; preds = %15
%29 = icmp ult i32 %11, 65536
br i1 %29, label %30, label %49
30: ; preds = %28
%31 = lshr i32 %11, 12
%32 = trunc i32 %31 to i8
%33 = or i8 %32, -32
%34 = add nuw nsw i32 %9, 1
%35 = zext i32 %9 to i64
%36 = getelementptr inbounds i8, i8* %0, i64 %35
store i8 %33, i8* %36
%37 = load i32, i32* %10
%38 = lshr i32 %37, 6
%39 = trunc i32 %38 to i8
%40 = and i8 %39, 63
%41 = or i8 %40, -128
%42 = add nuw nsw i32 %9, 2
%43 = zext i32 %34 to i64
%44 = getelementptr inbounds i8, i8* %0, i64 %43
store i8 %41, i8* %44
%45 = load i32, i32* %10
%46 = trunc i32 %45 to i8
%47 = and i8 %46, 63
%48 = or i8 %47, -128
br label %158
49: ; preds = %28
%50 = icmp ult i32 %11, 2097152
br i1 %50, label %51, label %78
51: ; preds = %49
%52 = lshr i32 %11, 18
%53 = trunc i32 %52 to i8
%54 = or i8 %53, -16
%55 = add nuw nsw i32 %9, 1
%56 = zext i32 %9 to i64
%57 = getelementptr inbounds i8, i8* %0, i64 %56
store i8 %54, i8* %57
%58 = load i32, i32* %10
%59 = lshr i32 %58, 12
%60 = trunc i32 %59 to i8
%61 = and i8 %60, 63
%62 = or i8 %61, -128
%63 = add nuw nsw i32 %9, 2
%64 = zext i32 %55 to i64
%65 = getelementptr inbounds i8, i8* %0, i64 %64
store i8 %62, i8* %65
%66 = load i32, i32* %10
%67 = lshr i32 %66, 6
%68 = trunc i32 %67 to i8
%69 = and i8 %68, 63
%70 = or i8 %69, -128
%71 = add nuw nsw i32 %9, 3
%72 = zext i32 %63 to i64
%73 = getelementptr inbounds i8, i8* %0, i64 %72
store i8 %70, i8* %73
%74 = load i32, i32* %10
%75 = trunc i32 %74 to i8
%76 = and i8 %75, 63
%77 = or i8 %76, -128
br label %158
78: ; preds = %49
%79 = icmp ult i32 %11, 67108864
br i1 %79, label %80, label %115
80: ; preds = %78
%81 = lshr i32 %11, 24
%82 = trunc i32 %81 to i8
%83 = or i8 %82, -8
%84 = add nuw nsw i32 %9, 1
%85 = zext i32 %9 to i64
%86 = getelementptr inbounds i8, i8* %0, i64 %85
store i8 %83, i8* %86
%87 = load i32, i32* %10
%88 = lshr i32 %87, 18
%89 = trunc i32 %88 to i8
%90 = and i8 %89, 63
%91 = or i8 %90, -128
%92 = add nuw nsw i32 %9, 2
%93 = zext i32 %84 to i64
%94 = getelementptr inbounds i8, i8* %0, i64 %93
store i8 %91, i8* %94
%95 = load i32, i32* %10
%96 = lshr i32 %95, 12
%97 = trunc i32 %96 to i8
%98 = and i8 %97, 63
%99 = or i8 %98, -128
%100 = add nuw nsw i32 %9, 3
%101 = zext i32 %92 to i64
%102 = getelementptr inbounds i8, i8* %0, i64 %101
store i8 %99, i8* %102
%103 = load i32, i32* %10
%104 = lshr i32 %103, 6
%105 = trunc i32 %104 to i8
%106 = and i8 %105, 63
%107 = or i8 %106, -128
%108 = add nuw nsw i32 %9, 4
%109 = zext i32 %100 to i64
%110 = getelementptr inbounds i8, i8* %0, i64 %109
store i8 %107, i8* %110
%111 = load i32, i32* %10
%112 = trunc i32 %111 to i8
%113 = and i8 %112, 63
%114 = or i8 %113, -128
br label %158
115: ; preds = %78
%116 = lshr i32 %11, 30
%117 = trunc i32 %116 to i8
%118 = or i8 %117, -8
%119 = add nuw nsw i32 %9, 1
%120 = zext i32 %9 to i64
%121 = getelementptr inbounds i8, i8* %0, i64 %120
store i8 %118, i8* %121
%122 = load i32, i32* %10
%123 = lshr i32 %122, 24
%124 = trunc i32 %123 to i8
%125 = and i8 %124, 63
%126 = or i8 %125, -128
%127 = add nuw nsw i32 %9, 2
%128 = zext i32 %119 to i64
%129 = getelementptr inbounds i8, i8* %0, i64 %128
store i8 %126, i8* %129
%130 = load i32, i32* %10
%131 = lshr i32 %130, 18
%132 = trunc i32 %131 to i8
%133 = and i8 %132, 63
%134 = or i8 %133, -128
%135 = add nuw nsw i32 %9, 3
%136 = zext i32 %127 to i64
%137 = getelementptr inbounds i8, i8* %0, i64 %136
store i8 %134, i8* %137
%138 = load i32, i32* %10
%139 = lshr i32 %138, 12
%140 = trunc i32 %139 to i8
%141 = and i8 %140, 63
%142 = or i8 %141, -128
%143 = add nuw nsw i32 %9, 4
%144 = zext i32 %135 to i64
%145 = getelementptr inbounds i8, i8* %0, i64 %144
store i8 %142, i8* %145
%146 = load i32, i32* %10
%147 = lshr i32 %146, 6
%148 = trunc i32 %147 to i8
%149 = and i8 %148, 63
%150 = or i8 %149, -128
%151 = add nuw nsw i32 %9, 5
%152 = zext i32 %143 to i64
%153 = getelementptr inbounds i8, i8* %0, i64 %152
store i8 %150, i8* %153
%154 = load i32, i32* %10
%155 = trunc i32 %154 to i8
%156 = and i8 %155, 63
%157 = or i8 %156, -128
br label %158
158: ; preds = %13, %30, %80, %115, %51, %17
%159 = phi i32 [ 1, %13 ], [ 3, %30 ], [ 5, %80 ], [ 6, %115 ], [ 4, %51 ], [ 2, %17 ]
%160 = phi i32 [ %9, %13 ], [ %42, %30 ], [ %108, %80 ], [ %151, %115 ], [ %71, %51 ], [ %21, %17 ]
%161 = phi i8 [ %14, %13 ], [ %48, %30 ], [ %114, %80 ], [ %157, %115 ], [ %77, %51 ], [ %27, %17 ]
%162 = add nuw nsw i32 %9, %159
%163 = sext i32 %160 to i64
%164 = getelementptr inbounds i8, i8* %0, i64 %163
store i8 %161, i8* %164
%165 = add nuw nsw i64 %8, 1
%166 = icmp eq i64 %165, %6
br i1 %166, label %167, label %7
167: ; preds = %158
%168 = zext i32 %162 to i64
br label %169
169: ; preds = %167, %3
%170 = phi i64 [ 0, %3 ], [ %168, %167 ]
%171 = getelementptr inbounds i8, i8* %0, i64 %170
store i8 0, i8* %171
ret i8* %0
}