#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 wchar_t;

/* Variables and functions */
int strlen(char *);
unsigned char *xcalloc(int, int);
unsigned char *xrealloc(unsigned char *, int);
wchar_t *utf8_to_wchar(const unsigned char *utf, size_t *memsize) {
  int i = 0;
  int j = 0;
  int len = strlen((char *)utf);
  wchar_t *mem = xcalloc(len + 1, sizeof(wchar_t));
  while (i < len) {
    if (utf[i] < 0x80)
      mem[j++] = utf[i++];
    else if (utf[i] < 0xE0) {
      mem[j++] = ((utf[i] & 0x1F) << 6) | (utf[i + 1] & 0x3F);
      i += 2;
    } else if (utf[i] < 0xF0) {
      mem[j++] = ((utf[i] & 0x0F) << 12) | ((utf[i + 1] & 0x3F) << 6) |
                 (utf[i + 2] & 0x3F);
      i += 3;
    } else if (utf[i] < 0xF8) {
      mem[j++] = ((utf[i] & 0x07) << 18) | ((utf[i + 1] & 0x3F) << 12) |
                 ((utf[i + 2] & 0x3F) << 6) | (utf[i + 2] & 0x3F);
      i += 4;
    } else if (utf[i] < 0xFC) {
      mem[j++] = ((utf[i] & 0x03) << 24) | ((utf[i + 1] & 0x3F) << 18) |
                 ((utf[i + 2] & 0x3F) << 12) | ((utf[i + 3] & 0x3F) << 6) |
                 (utf[i + 4] & 0x3F);
      i += 5;
    } else if (utf[i] >= 0xFC) {
      mem[j++] = ((utf[i] & 0x01) << 30) | ((utf[i + 1] & 0x3F) << 24) |
                 ((utf[i + 2] & 0x3F) << 18) | ((utf[i + 3] & 0x3F) << 12) |
                 ((utf[i + 4] & 0x3F) << 6) | (utf[i + 5] & 0x3F);
      i += 6;
    }
  }
  mem = xrealloc(mem, sizeof(wchar_t) * (j + 1));
  *memsize = j;
  return mem;
}


x86 assembly (clang, -O0):
<utf8_to_wchar>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movl   $0x0,-0x14(%rbp)
movl   $0x0,-0x18(%rbp)
mov    -0x8(%rbp),%rdi
call   1030 <strlen@plt>
mov    %eax,-0x1c(%rbp)
mov    -0x1c(%rbp),%edi
add    $0x1,%edi
mov    $0x1,%esi
call   1050 <xcalloc@plt>
mov    %rax,-0x28(%rbp)
mov    -0x14(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jge    14c7 <utf8_to_wchar+0x397>
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
cmp    $0x80,%eax
jge    11c0 <utf8_to_wchar+0x90>
mov    -0x8(%rbp),%rax
mov    -0x14(%rbp),%ecx
mov    %ecx,%edx
add    $0x1,%edx
mov    %edx,-0x14(%rbp)
movslq %ecx,%rcx
mov    (%rax,%rcx,1),%dl
mov    -0x28(%rbp),%rax
mov    -0x18(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x18(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
jmp    14c2 <utf8_to_wchar+0x392>
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
cmp    $0xe0,%eax
jge    1224 <utf8_to_wchar+0xf4>
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
and    $0x1f,%eax
shl    $0x6,%eax
mov    -0x8(%rbp),%rcx
mov    -0x14(%rbp),%edx
add    $0x1,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
or     %ecx,%eax
mov    %al,%dl
mov    -0x28(%rbp),%rax
mov    -0x18(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x18(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x14(%rbp),%eax
add    $0x2,%eax
mov    %eax,-0x14(%rbp)
jmp    14bd <utf8_to_wchar+0x38d>
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
cmp    $0xf0,%eax
jge    12a1 <utf8_to_wchar+0x171>
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
and    $0xf,%eax
shl    $0xc,%eax
mov    -0x8(%rbp),%rcx
mov    -0x14(%rbp),%edx
add    $0x1,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
shl    $0x6,%ecx
or     %ecx,%eax
mov    -0x8(%rbp),%rcx
mov    -0x14(%rbp),%edx
add    $0x2,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
or     %ecx,%eax
mov    %al,%dl
mov    -0x28(%rbp),%rax
mov    -0x18(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x18(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x14(%rbp),%eax
add    $0x3,%eax
mov    %eax,-0x14(%rbp)
jmp    14b8 <utf8_to_wchar+0x388>
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
cmp    $0xf8,%eax
jge    1337 <utf8_to_wchar+0x207>
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
and    $0x7,%eax
shl    $0x12,%eax
mov    -0x8(%rbp),%rcx
mov    -0x14(%rbp),%edx
add    $0x1,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
shl    $0xc,%ecx
or     %ecx,%eax
mov    -0x8(%rbp),%rcx
mov    -0x14(%rbp),%edx
add    $0x2,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
shl    $0x6,%ecx
or     %ecx,%eax
mov    -0x8(%rbp),%rcx
mov    -0x14(%rbp),%edx
add    $0x2,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
or     %ecx,%eax
mov    %al,%dl
mov    -0x28(%rbp),%rax
mov    -0x18(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x18(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x14(%rbp),%eax
add    $0x4,%eax
mov    %eax,-0x14(%rbp)
jmp    14b3 <utf8_to_wchar+0x383>
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
cmp    $0xfc,%eax
jge    13e6 <utf8_to_wchar+0x2b6>
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
and    $0x3,%eax
shl    $0x18,%eax
mov    -0x8(%rbp),%rcx
mov    -0x14(%rbp),%edx
add    $0x1,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
shl    $0x12,%ecx
or     %ecx,%eax
mov    -0x8(%rbp),%rcx
mov    -0x14(%rbp),%edx
add    $0x2,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
shl    $0xc,%ecx
or     %ecx,%eax
mov    -0x8(%rbp),%rcx
mov    -0x14(%rbp),%edx
add    $0x3,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
shl    $0x6,%ecx
or     %ecx,%eax
mov    -0x8(%rbp),%rcx
mov    -0x14(%rbp),%edx
add    $0x4,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
or     %ecx,%eax
mov    %al,%dl
mov    -0x28(%rbp),%rax
mov    -0x18(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x18(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x14(%rbp),%eax
add    $0x5,%eax
mov    %eax,-0x14(%rbp)
jmp    14ae <utf8_to_wchar+0x37e>
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
cmp    $0xfc,%eax
jl     14a9 <utf8_to_wchar+0x379>
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
and    $0x1,%eax
shl    $0x1e,%eax
mov    -0x8(%rbp),%rcx
mov    -0x14(%rbp),%edx
add    $0x1,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
shl    $0x18,%ecx
or     %ecx,%eax
mov    -0x8(%rbp),%rcx
mov    -0x14(%rbp),%edx
add    $0x2,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
shl    $0x12,%ecx
or     %ecx,%eax
mov    -0x8(%rbp),%rcx
mov    -0x14(%rbp),%edx
add    $0x3,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
shl    $0xc,%ecx
or     %ecx,%eax
mov    -0x8(%rbp),%rcx
mov    -0x14(%rbp),%edx
add    $0x4,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
shl    $0x6,%ecx
or     %ecx,%eax
mov    -0x8(%rbp),%rcx
mov    -0x14(%rbp),%edx
add    $0x5,%edx
movslq %edx,%rdx
movzbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
or     %ecx,%eax
mov    %al,%dl
mov    -0x28(%rbp),%rax
mov    -0x18(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x18(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x14(%rbp),%eax
add    $0x6,%eax
mov    %eax,-0x14(%rbp)
jmp    14ae <utf8_to_wchar+0x37e>
jmp    14b3 <utf8_to_wchar+0x383>
jmp    14b8 <utf8_to_wchar+0x388>
jmp    14bd <utf8_to_wchar+0x38d>
jmp    14c2 <utf8_to_wchar+0x392>
jmp    116e <utf8_to_wchar+0x3e>
mov    -0x28(%rbp),%rdi
mov    -0x18(%rbp),%eax
add    $0x1,%eax
cltq
shl    $0x0,%rax
mov    %eax,%esi
call   1040 <xrealloc@plt>
mov    %rax,-0x28(%rbp)
movslq -0x18(%rbp),%rcx
mov    -0x10(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x28(%rbp),%rax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<utf8_to_wchar>:
push   %r15
push   %r14
push   %r12
push   %rbx
push   %rax
mov    %rsi,%r14
mov    %rdi,%r12
call   1030 <strlen@plt>
mov    %eax,%r15d
lea    0x1(%r15),%edi
mov    $0x1,%esi
call   1050 <xcalloc@plt>
xor    %ebx,%ebx
test   %r15d,%r15d
jle    1237 <utf8_to_wchar+0x107>
xor    %edx,%edx
jmp    1183 <utf8_to_wchar+0x53>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
add    $0x1,%edx
mov    %cl,(%rax,%rbx,1)
add    $0x1,%rbx
cmp    %r15d,%edx
jge    1237 <utf8_to_wchar+0x107>
movslq %edx,%rsi
movzbl (%r12,%rsi,1),%ecx
test   %cl,%cl
jns    1170 <utf8_to_wchar+0x40>
cmp    $0xdf,%cl
ja     11ad <utf8_to_wchar+0x7d>
shl    $0x6,%cl
movzbl 0x1(%rsi,%r12,1),%edx
and    $0x3f,%dl
or     %cl,%dl
mov    %dl,(%rax,%rbx,1)
add    $0x2,%esi
jmp    1230 <utf8_to_wchar+0x100>
cmp    $0xef,%cl
ja     11ce <utf8_to_wchar+0x9e>
movzbl 0x1(%rsi,%r12,1),%ecx
movzbl 0x2(%rsi,%r12,1),%edx
shl    $0x6,%cl
and    $0x3f,%dl
or     %cl,%dl
mov    %dl,(%rax,%rbx,1)
add    $0x3,%esi
jmp    1230 <utf8_to_wchar+0x100>
cmp    $0xf7,%cl
ja     11eb <utf8_to_wchar+0xbb>
movzbl 0x2(%rsi,%r12,1),%ecx
mov    %ecx,%edx
and    $0x3f,%dl
shl    $0x6,%cl
or     %dl,%cl
mov    %cl,(%rax,%rbx,1)
add    $0x4,%esi
jmp    1230 <utf8_to_wchar+0x100>
cmp    $0xfb,%cl
ja     120c <utf8_to_wchar+0xdc>
movzbl 0x3(%rsi,%r12,1),%ecx
movzbl 0x4(%rsi,%r12,1),%edx
shl    $0x6,%cl
and    $0x3f,%dl
or     %cl,%dl
mov    %dl,(%rax,%rbx,1)
add    $0x5,%esi
jmp    1230 <utf8_to_wchar+0x100>
movzbl 0x4(%rsi,%r12,1),%ecx
movzbl 0x5(%rsi,%r12,1),%edx
shl    $0x6,%cl
and    $0x3f,%dl
or     %cl,%dl
mov    %dl,(%rax,%rbx,1)
add    $0x6,%esi
cs nopw 0x0(%rax,%rax,1)
mov    %esi,%edx
jmp    1176 <utf8_to_wchar+0x46>
lea    0x1(%rbx),%esi
mov    %rax,%rdi
call   1040 <xrealloc@plt>
mov    %ebx,%ecx
mov    %rcx,(%r14)
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
ret

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

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