#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 */
int /*<<< orphan*/ assert(int /*<<< orphan*/);
int UCS2UTF8(unsigned int ucs, char *dest) {
  char *p = dest;
  if (ucs <= 0x7f) {
    if (!p)
      return 1;
    *p++ = ucs & 0x7f;
  } else if (ucs <= 0x7ff) {
    if (!p)
      return 2;
    *p++ = 0xC0 | (ucs >> 6);
    *p++ = 0x08 | (ucs & 0x3f);
  } else if (ucs <= 0xFFFF) {
    if (!p)
      return 3;
    *p++ = 0xE0 | (ucs >> 12);
    *p++ = 0x80 | ((ucs >> 6) & 0x3f);
    *p++ = 0x80 | (ucs & 0x3f);
  } else if (ucs <= 0x10FFFF) {
    if (!p)
      return 4;
    *p++ = 0xF0 | (ucs >> 18);
    *p++ = 0x80 | ((ucs >> 12) & 0x3f);
    *p++ = 0x80 | ((ucs >> 6) & 0x3f);
    *p++ = 0x80 | (ucs & 0x3f);
  } else if (ucs <= 0x3ffffff) {
    if (!p)
      return 5;
    *p++ = 0xF8 | (ucs >> 24);
    *p++ = 0x80 | ((ucs >> 18) & 0x3f);
    *p++ = 0x80 | ((ucs >> 12) & 0x3f);
    *p++ = 0x80 | ((ucs >> 6) & 0x3f);
    *p++ = 0x80 | (ucs & 0x3f);
  } else if (ucs <= 0x7fffffff) {
    if (!p)
      return 6;
    *p++ = 0xF8 | (ucs >> 30);
    *p++ = 0x80 | ((ucs >> 24) & 0x3f);
    *p++ = 0x80 | ((ucs >> 18) & 0x3f);
    *p++ = 0x80 | ((ucs >> 12) & 0x3f);
    *p++ = 0x80 | ((ucs >> 6) & 0x3f);
    *p++ = 0x80 | (ucs & 0x3f);
  } else {
    assert(0);
  }
  return p - dest;
}


x86 assembly (clang, -O0):
<UCS2UTF8>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %edi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x18(%rbp)
cmpl   $0x7f,-0x8(%rbp)
ja     1166 <UCS2UTF8+0x56>
cmpq   $0x0,-0x18(%rbp)
jne    1148 <UCS2UTF8+0x38>
movl   $0x1,-0x4(%rbp)
jmp    14d5 <UCS2UTF8+0x3c5>
mov    -0x8(%rbp),%eax
and    $0x7f,%eax
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x18(%rbp)
mov    %cl,(%rax)
jmp    14c7 <UCS2UTF8+0x3b7>
cmpl   $0x7ff,-0x8(%rbp)
ja     11c9 <UCS2UTF8+0xb9>
cmpq   $0x0,-0x18(%rbp)
jne    118a <UCS2UTF8+0x7a>
movl   $0x2,-0x4(%rbp)
jmp    14d5 <UCS2UTF8+0x3c5>
mov    -0x8(%rbp),%eax
shr    $0x6,%eax
or     $0xc0,%eax
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x18(%rbp)
mov    %cl,(%rax)
mov    -0x8(%rbp),%eax
and    $0x3f,%eax
or     $0x8,%eax
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x18(%rbp)
mov    %cl,(%rax)
jmp    14c2 <UCS2UTF8+0x3b2>
cmpl   $0xffff,-0x8(%rbp)
ja     124f <UCS2UTF8+0x13f>
cmpq   $0x0,-0x18(%rbp)
jne    11ed <UCS2UTF8+0xdd>
movl   $0x3,-0x4(%rbp)
jmp    14d5 <UCS2UTF8+0x3c5>
mov    -0x8(%rbp),%eax
shr    $0xc,%eax
or     $0xe0,%eax
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x18(%rbp)
mov    %cl,(%rax)
mov    -0x8(%rbp),%eax
shr    $0x6,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x18(%rbp)
mov    %cl,(%rax)
mov    -0x8(%rbp),%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x18(%rbp)
mov    %cl,(%rax)
jmp    14bd <UCS2UTF8+0x3ad>
cmpl   $0x10ffff,-0x8(%rbp)
ja     12f6 <UCS2UTF8+0x1e6>
cmpq   $0x0,-0x18(%rbp)
jne    1273 <UCS2UTF8+0x163>
movl   $0x4,-0x4(%rbp)
jmp    14d5 <UCS2UTF8+0x3c5>
mov    -0x8(%rbp),%eax
shr    $0x12,%eax
or     $0xf0,%eax
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x18(%rbp)
mov    %cl,(%rax)
mov    -0x8(%rbp),%eax
shr    $0xc,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x18(%rbp)
mov    %cl,(%rax)
mov    -0x8(%rbp),%eax
shr    $0x6,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x18(%rbp)
mov    %cl,(%rax)
mov    -0x8(%rbp),%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x18(%rbp)
mov    %cl,(%rax)
jmp    14b8 <UCS2UTF8+0x3a8>
cmpl   $0x3ffffff,-0x8(%rbp)
ja     13be <UCS2UTF8+0x2ae>
cmpq   $0x0,-0x18(%rbp)
jne    131a <UCS2UTF8+0x20a>
movl   $0x5,-0x4(%rbp)
jmp    14d5 <UCS2UTF8+0x3c5>
mov    -0x8(%rbp),%eax
shr    $0x18,%eax
or     $0xf8,%eax
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x18(%rbp)
mov    %cl,(%rax)
mov    -0x8(%rbp),%eax
shr    $0x12,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x18(%rbp)
mov    %cl,(%rax)
mov    -0x8(%rbp),%eax
shr    $0xc,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x18(%rbp)
mov    %cl,(%rax)
mov    -0x8(%rbp),%eax
shr    $0x6,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x18(%rbp)
mov    %cl,(%rax)
mov    -0x8(%rbp),%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x18(%rbp)
mov    %cl,(%rax)
jmp    14b3 <UCS2UTF8+0x3a3>
cmpl   $0x7fffffff,-0x8(%rbp)
ja     14a7 <UCS2UTF8+0x397>
cmpq   $0x0,-0x18(%rbp)
jne    13e2 <UCS2UTF8+0x2d2>
movl   $0x6,-0x4(%rbp)
jmp    14d5 <UCS2UTF8+0x3c5>
mov    -0x8(%rbp),%eax
shr    $0x1e,%eax
or     $0xf8,%eax
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x18(%rbp)
mov    %cl,(%rax)
mov    -0x8(%rbp),%eax
shr    $0x18,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x18(%rbp)
mov    %cl,(%rax)
mov    -0x8(%rbp),%eax
shr    $0x12,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x18(%rbp)
mov    %cl,(%rax)
mov    -0x8(%rbp),%eax
shr    $0xc,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x18(%rbp)
mov    %cl,(%rax)
mov    -0x8(%rbp),%eax
shr    $0x6,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x18(%rbp)
mov    %cl,(%rax)
mov    -0x8(%rbp),%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %al,%cl
mov    -0x18(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x18(%rbp)
mov    %cl,(%rax)
jmp    14ae <UCS2UTF8+0x39e>
xor    %edi,%edi
call   1030 <assert@plt>
jmp    14b3 <UCS2UTF8+0x3a3>
jmp    14b8 <UCS2UTF8+0x3a8>
jmp    14bd <UCS2UTF8+0x3ad>
jmp    14c2 <UCS2UTF8+0x3b2>
jmp    14c7 <UCS2UTF8+0x3b7>
mov    -0x18(%rbp),%rax
mov    -0x10(%rbp),%rcx
sub    %rcx,%rax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<UCS2UTF8>:
push   %rbx
mov    %rsi,%rbx
cmp    $0x7f,%edi
ja     112a <UCS2UTF8+0x1a>
test   %rbx,%rbx
je     1194 <UCS2UTF8+0x84>
lea    0x1(%rbx),%rax
mov    %dil,(%rbx)
jmp    12ac <UCS2UTF8+0x19c>
cmp    $0x7ff,%edi
ja     1159 <UCS2UTF8+0x49>
test   %rbx,%rbx
je     11e2 <UCS2UTF8+0xd2>
mov    %edi,%eax
shr    $0x6,%eax
or     $0xc0,%al
mov    %al,(%rbx)
and    $0x37,%dil
or     $0x8,%dil
lea    0x2(%rbx),%rax
mov    %dil,0x1(%rbx)
jmp    12ac <UCS2UTF8+0x19c>
cmp    $0xffff,%edi
ja     119b <UCS2UTF8+0x8b>
test   %rbx,%rbx
je     1239 <UCS2UTF8+0x129>
mov    %edi,%eax
shr    $0xc,%eax
or     $0xe0,%al
mov    %al,(%rbx)
mov    %edi,%eax
shr    $0x6,%eax
and    $0x3f,%al
or     $0x80,%al
mov    %al,0x1(%rbx)
and    $0x3f,%dil
or     $0x80,%dil
lea    0x3(%rbx),%rax
mov    %dil,0x2(%rbx)
jmp    12ac <UCS2UTF8+0x19c>
mov    $0x1,%eax
pop    %rbx
ret
cmp    $0x10ffff,%edi
ja     11e9 <UCS2UTF8+0xd9>
test   %rbx,%rbx
je     1294 <UCS2UTF8+0x184>
mov    %edi,%eax
shr    $0x12,%eax
or     $0xf0,%al
mov    %al,(%rbx)
mov    %edi,%eax
shr    $0xc,%eax
and    $0x3f,%al
or     $0x80,%al
mov    %al,0x1(%rbx)
mov    %edi,%eax
shr    $0x6,%eax
and    $0x3f,%al
or     $0x80,%al
mov    %al,0x2(%rbx)
and    $0x3f,%dil
or     $0x80,%dil
lea    0x4(%rbx),%rax
mov    %dil,0x3(%rbx)
jmp    12ac <UCS2UTF8+0x19c>
mov    $0x2,%eax
pop    %rbx
ret
cmp    $0x3ffffff,%edi
ja     1240 <UCS2UTF8+0x130>
test   %rbx,%rbx
je     129b <UCS2UTF8+0x18b>
mov    %edi,%eax
shr    $0x18,%eax
or     $0xf8,%al
mov    %al,(%rbx)
mov    %edi,%eax
shr    $0x12,%eax
and    $0x3f,%al
or     $0x80,%al
mov    %al,0x1(%rbx)
mov    %edi,%eax
shr    $0xc,%eax
and    $0x3f,%al
or     $0x80,%al
mov    %al,0x2(%rbx)
mov    %edi,%eax
shr    $0x6,%eax
and    $0x3f,%al
or     $0x80,%al
mov    %al,0x3(%rbx)
and    $0x3f,%dil
or     $0x80,%dil
lea    0x5(%rbx),%rax
mov    %dil,0x4(%rbx)
jmp    12ac <UCS2UTF8+0x19c>
mov    $0x3,%eax
pop    %rbx
ret
test   %edi,%edi
js     12a2 <UCS2UTF8+0x192>
test   %rbx,%rbx
je     12b0 <UCS2UTF8+0x1a0>
mov    %edi,%eax
shr    $0x1e,%eax
or     $0xf8,%al
mov    %al,(%rbx)
mov    %edi,%eax
shr    $0x18,%eax
and    $0x3f,%al
or     $0x80,%al
mov    %al,0x1(%rbx)
mov    %edi,%eax
shr    $0x12,%eax
and    $0x3f,%al
or     $0x80,%al
mov    %al,0x2(%rbx)
mov    %edi,%eax
shr    $0xc,%eax
and    $0x3f,%al
or     $0x80,%al
mov    %al,0x3(%rbx)
mov    %edi,%eax
shr    $0x6,%eax
and    $0x3f,%al
or     $0x80,%al
mov    %al,0x4(%rbx)
and    $0x3f,%dil
or     $0x80,%dil
lea    0x6(%rbx),%rax
mov    %dil,0x5(%rbx)
jmp    12ac <UCS2UTF8+0x19c>
mov    $0x4,%eax
pop    %rbx
ret
mov    $0x5,%eax
pop    %rbx
ret
xor    %edi,%edi
call   1030 <assert@plt>
mov    %rbx,%rax
sub    %ebx,%eax
pop    %rbx
ret
mov    $0x6,%eax
pop    %rbx
ret

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

LLVM IR (-O2):
define i32 @UCS2UTF8(i32 %0, i8* %1) {
%3 = icmp ult i32 %0, 128
br i1 %3, label %4, label %9
4: ; preds = %2
%5 = icmp eq i8* %1, null
br i1 %5, label %132, label %6
6: ; preds = %4
%7 = trunc i32 %0 to i8
%8 = getelementptr inbounds i8, i8* %1, i64 1
store i8 %7, i8* %1
br label %126
9: ; preds = %2
%10 = icmp ult i32 %0, 2048
br i1 %10, label %11, label %22
11: ; preds = %9
%12 = icmp eq i8* %1, null
br i1 %12, label %132, label %13
13: ; preds = %11
%14 = lshr i32 %0, 6
%15 = trunc i32 %14 to i8
%16 = or i8 %15, -64
%17 = getelementptr inbounds i8, i8* %1, i64 1
store i8 %16, i8* %1
%18 = trunc i32 %0 to i8
%19 = and i8 %18, 55
%20 = or i8 %19, 8
%21 = getelementptr inbounds i8, i8* %1, i64 2
store i8 %20, i8* %17
br label %126
22: ; preds = %9
%23 = icmp ult i32 %0, 65536
br i1 %23, label %24, label %40
24: ; preds = %22
%25 = icmp eq i8* %1, null
br i1 %25, label %132, label %26
26: ; preds = %24
%27 = lshr i32 %0, 12
%28 = trunc i32 %27 to i8
%29 = or i8 %28, -32
%30 = getelementptr inbounds i8, i8* %1, i64 1
store i8 %29, i8* %1
%31 = lshr i32 %0, 6
%32 = trunc i32 %31 to i8
%33 = and i8 %32, 63
%34 = or i8 %33, -128
%35 = getelementptr inbounds i8, i8* %1, i64 2
store i8 %34, i8* %30
%36 = trunc i32 %0 to i8
%37 = and i8 %36, 63
%38 = or i8 %37, -128
%39 = getelementptr inbounds i8, i8* %1, i64 3
store i8 %38, i8* %35
br label %126
40: ; preds = %22
%41 = icmp ult i32 %0, 1114112
br i1 %41, label %42, label %63
42: ; preds = %40
%43 = icmp eq i8* %1, null
br i1 %43, label %132, label %44
44: ; preds = %42
%45 = lshr i32 %0, 18
%46 = trunc i32 %45 to i8
%47 = or i8 %46, -16
%48 = getelementptr inbounds i8, i8* %1, i64 1
store i8 %47, i8* %1
%49 = lshr i32 %0, 12
%50 = trunc i32 %49 to i8
%51 = and i8 %50, 63
%52 = or i8 %51, -128
%53 = getelementptr inbounds i8, i8* %1, i64 2
store i8 %52, i8* %48
%54 = lshr i32 %0, 6
%55 = trunc i32 %54 to i8
%56 = and i8 %55, 63
%57 = or i8 %56, -128
%58 = getelementptr inbounds i8, i8* %1, i64 3
store i8 %57, i8* %53
%59 = trunc i32 %0 to i8
%60 = and i8 %59, 63
%61 = or i8 %60, -128
%62 = getelementptr inbounds i8, i8* %1, i64 4
store i8 %61, i8* %58
br label %126
63: ; preds = %40
%64 = icmp ult i32 %0, 67108864
br i1 %64, label %65, label %91
65: ; preds = %63
%66 = icmp eq i8* %1, null
br i1 %66, label %132, label %67
67: ; preds = %65
%68 = lshr i32 %0, 24
%69 = trunc i32 %68 to i8
%70 = or i8 %69, -8
%71 = getelementptr inbounds i8, i8* %1, i64 1
store i8 %70, i8* %1
%72 = lshr i32 %0, 18
%73 = trunc i32 %72 to i8
%74 = and i8 %73, 63
%75 = or i8 %74, -128
%76 = getelementptr inbounds i8, i8* %1, i64 2
store i8 %75, i8* %71
%77 = lshr i32 %0, 12
%78 = trunc i32 %77 to i8
%79 = and i8 %78, 63
%80 = or i8 %79, -128
%81 = getelementptr inbounds i8, i8* %1, i64 3
store i8 %80, i8* %76
%82 = lshr i32 %0, 6
%83 = trunc i32 %82 to i8
%84 = and i8 %83, 63
%85 = or i8 %84, -128
%86 = getelementptr inbounds i8, i8* %1, i64 4
store i8 %85, i8* %81
%87 = trunc i32 %0 to i8
%88 = and i8 %87, 63
%89 = or i8 %88, -128
%90 = getelementptr inbounds i8, i8* %1, i64 5
store i8 %89, i8* %86
br label %126
91: ; preds = %63
%92 = icmp sgt i32 %0, -1
br i1 %92, label %93, label %124
93: ; preds = %91
%94 = icmp eq i8* %1, null
br i1 %94, label %132, label %95
95: ; preds = %93
%96 = lshr i32 %0, 30
%97 = trunc i32 %96 to i8
%98 = or i8 %97, -8
%99 = getelementptr inbounds i8, i8* %1, i64 1
store i8 %98, i8* %1
%100 = lshr i32 %0, 24
%101 = trunc i32 %100 to i8
%102 = and i8 %101, 63
%103 = or i8 %102, -128
%104 = getelementptr inbounds i8, i8* %1, i64 2
store i8 %103, i8* %99
%105 = lshr i32 %0, 18
%106 = trunc i32 %105 to i8
%107 = and i8 %106, 63
%108 = or i8 %107, -128
%109 = getelementptr inbounds i8, i8* %1, i64 3
store i8 %108, i8* %104
%110 = lshr i32 %0, 12
%111 = trunc i32 %110 to i8
%112 = and i8 %111, 63
%113 = or i8 %112, -128
%114 = getelementptr inbounds i8, i8* %1, i64 4
store i8 %113, i8* %109
%115 = lshr i32 %0, 6
%116 = trunc i32 %115 to i8
%117 = and i8 %116, 63
%118 = or i8 %117, -128
%119 = getelementptr inbounds i8, i8* %1, i64 5
store i8 %118, i8* %114
%120 = trunc i32 %0 to i8
%121 = and i8 %120, 63
%122 = or i8 %121, -128
%123 = getelementptr inbounds i8, i8* %1, i64 6
store i8 %122, i8* %119
br label %126
124: ; preds = %91
%125 = tail call i32 @assert(i32 0)
br label %126
126: ; preds = %13, %44, %95, %124, %67, %26, %6
%127 = phi i8* [ %8, %6 ], [ %21, %13 ], [ %39, %26 ], [ %62, %44 ], [ %90, %67 ], [ %123, %95 ], [ %1, %124 ]
%128 = ptrtoint i8* %127 to i64
%129 = ptrtoint i8* %1 to i64
%130 = sub i64 %128, %129
%131 = trunc i64 %130 to i32
br label %132
132: ; preds = %93, %65, %42, %24, %11, %4, %126
%133 = phi i32 [ %131, %126 ], [ 1, %4 ], [ 2, %11 ], [ 3, %24 ], [ 4, %42 ], [ 5, %65 ], [ 6, %93 ]
ret i32 %133
}