char *__utf8_get_char(const char *in, int *chr) {
  if ((in[0] & 0xe0) == 0xc0 && ((in[1] & 0xc0) == 0x80)) {
    *chr = ((in[0] & 0x1f) << 6) | ((in[1] & 0x3f) << 0);
    return (char *)in + 2;
  }
  if ((in[0] & 0xf0) == 0xe0 && ((in[1] & 0xc0) == 0x80) &&
      ((in[2] & 0xc0) == 0x80)) {
    *chr =
        ((in[0] & 0xf) << 12) | ((in[1] & 0x3f) << 6) | ((in[2] & 0x3f) << 0);
    return (char *)in + 3;
  }
  if ((in[0] & 0xf8) == 0xf0 && ((in[1] & 0xc0) == 0x80) &&
      ((in[2] & 0xc0) == 0x80) && ((in[3] & 0xc0) == 0x80)) {
    *chr = ((in[0] & 0x7) << 18) | ((in[1] & 0x3f) << 12) |
           ((in[2] & 0x3f) << 6) | ((in[3] & 0x3f) << 0);
    return (char *)in + 4;
  }
  if ((in[0] & 0xfc) == 0xf8 && ((in[1] & 0xc0) == 0x80) &&
      ((in[2] & 0xc0) == 0x80) && ((in[3] & 0xc0) == 0x80) &&
      ((in[4] & 0xc0) == 0x80)) {
    *chr = ((in[0] & 0x3) << 24) | ((in[1] & 0x3f) << 18) |
           ((in[2] & 0x3f) << 12) | ((in[3] & 0x3f) << 6) |
           ((in[4] & 0x3f) << 0);
    return (char *)in + 5;
  }
  if ((in[0] & 0xf8) == 0xf0 && ((in[1] & 0xc0) == 0x80) &&
      ((in[2] & 0xc0) == 0x80) && ((in[3] & 0xc0) == 0x80) &&
      ((in[4] & 0xc0) == 0x80) && ((in[5] & 0xc0) == 0x80)) {
    *chr = ((in[0] & 0x1) << 30) | ((in[1] & 0x3f) << 24) |
           ((in[2] & 0x3f) << 18) | ((in[3] & 0x3f) << 12) |
           ((in[4] & 0x3f) << 6) | ((in[5] & 0x3f) << 0);
    return (char *)in + 4;
  }
  *chr = *in;
  return (char *)in + 1;
}


x86 assembly (clang, -O0):
<__utf8_get_char>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
and    $0xe0,%eax
cmp    $0xc0,%eax
jne    116f <__utf8_get_char+0x6f>
mov    -0x10(%rbp),%rax
movsbl 0x1(%rax),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    116f <__utf8_get_char+0x6f>
mov    -0x10(%rbp),%rax
movsbl (%rax),%ecx
and    $0x1f,%ecx
shl    $0x6,%ecx
mov    -0x10(%rbp),%rax
movsbl 0x1(%rax),%eax
and    $0x3f,%eax
shl    $0x0,%eax
or     %eax,%ecx
mov    -0x18(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x10(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x8(%rbp)
jmp    14a4 <__utf8_get_char+0x3a4>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
and    $0xf0,%eax
cmp    $0xe0,%eax
jne    11fa <__utf8_get_char+0xfa>
mov    -0x10(%rbp),%rax
movsbl 0x1(%rax),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    11fa <__utf8_get_char+0xfa>
mov    -0x10(%rbp),%rax
movsbl 0x2(%rax),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    11fa <__utf8_get_char+0xfa>
mov    -0x10(%rbp),%rax
movsbl (%rax),%ecx
and    $0xf,%ecx
shl    $0xc,%ecx
mov    -0x10(%rbp),%rax
movsbl 0x1(%rax),%eax
and    $0x3f,%eax
shl    $0x6,%eax
or     %eax,%ecx
mov    -0x10(%rbp),%rax
movsbl 0x2(%rax),%eax
and    $0x3f,%eax
shl    $0x0,%eax
or     %eax,%ecx
mov    -0x18(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x10(%rbp),%rax
add    $0x3,%rax
mov    %rax,-0x8(%rbp)
jmp    14a4 <__utf8_get_char+0x3a4>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
and    $0xf8,%eax
cmp    $0xf0,%eax
jne    12ad <__utf8_get_char+0x1ad>
mov    -0x10(%rbp),%rax
movsbl 0x1(%rax),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    12ad <__utf8_get_char+0x1ad>
mov    -0x10(%rbp),%rax
movsbl 0x2(%rax),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    12ad <__utf8_get_char+0x1ad>
mov    -0x10(%rbp),%rax
movsbl 0x3(%rax),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    12ad <__utf8_get_char+0x1ad>
mov    -0x10(%rbp),%rax
movsbl (%rax),%ecx
and    $0x7,%ecx
shl    $0x12,%ecx
mov    -0x10(%rbp),%rax
movsbl 0x1(%rax),%eax
and    $0x3f,%eax
shl    $0xc,%eax
or     %eax,%ecx
mov    -0x10(%rbp),%rax
movsbl 0x2(%rax),%eax
and    $0x3f,%eax
shl    $0x6,%eax
or     %eax,%ecx
mov    -0x10(%rbp),%rax
movsbl 0x3(%rax),%eax
and    $0x3f,%eax
shl    $0x0,%eax
or     %eax,%ecx
mov    -0x18(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x10(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x8(%rbp)
jmp    14a4 <__utf8_get_char+0x3a4>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
and    $0xfc,%eax
cmp    $0xf8,%eax
jne    1388 <__utf8_get_char+0x288>
mov    -0x10(%rbp),%rax
movsbl 0x1(%rax),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    1388 <__utf8_get_char+0x288>
mov    -0x10(%rbp),%rax
movsbl 0x2(%rax),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    1388 <__utf8_get_char+0x288>
mov    -0x10(%rbp),%rax
movsbl 0x3(%rax),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    1388 <__utf8_get_char+0x288>
mov    -0x10(%rbp),%rax
movsbl 0x4(%rax),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    1388 <__utf8_get_char+0x288>
mov    -0x10(%rbp),%rax
movsbl (%rax),%ecx
and    $0x3,%ecx
shl    $0x18,%ecx
mov    -0x10(%rbp),%rax
movsbl 0x1(%rax),%eax
and    $0x3f,%eax
shl    $0x12,%eax
or     %eax,%ecx
mov    -0x10(%rbp),%rax
movsbl 0x2(%rax),%eax
and    $0x3f,%eax
shl    $0xc,%eax
or     %eax,%ecx
mov    -0x10(%rbp),%rax
movsbl 0x3(%rax),%eax
and    $0x3f,%eax
shl    $0x6,%eax
or     %eax,%ecx
mov    -0x10(%rbp),%rax
movsbl 0x4(%rax),%eax
and    $0x3f,%eax
shl    $0x0,%eax
or     %eax,%ecx
mov    -0x18(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x10(%rbp),%rax
add    $0x5,%rax
mov    %rax,-0x8(%rbp)
jmp    14a4 <__utf8_get_char+0x3a4>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
and    $0xf8,%eax
cmp    $0xf0,%eax
jne    148b <__utf8_get_char+0x38b>
mov    -0x10(%rbp),%rax
movsbl 0x1(%rax),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    148b <__utf8_get_char+0x38b>
mov    -0x10(%rbp),%rax
movsbl 0x2(%rax),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    148b <__utf8_get_char+0x38b>
mov    -0x10(%rbp),%rax
movsbl 0x3(%rax),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    148b <__utf8_get_char+0x38b>
mov    -0x10(%rbp),%rax
movsbl 0x4(%rax),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    148b <__utf8_get_char+0x38b>
mov    -0x10(%rbp),%rax
movsbl 0x5(%rax),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    148b <__utf8_get_char+0x38b>
mov    -0x10(%rbp),%rax
movsbl (%rax),%ecx
and    $0x1,%ecx
shl    $0x1e,%ecx
mov    -0x10(%rbp),%rax
movsbl 0x1(%rax),%eax
and    $0x3f,%eax
shl    $0x18,%eax
or     %eax,%ecx
mov    -0x10(%rbp),%rax
movsbl 0x2(%rax),%eax
and    $0x3f,%eax
shl    $0x12,%eax
or     %eax,%ecx
mov    -0x10(%rbp),%rax
movsbl 0x3(%rax),%eax
and    $0x3f,%eax
shl    $0xc,%eax
or     %eax,%ecx
mov    -0x10(%rbp),%rax
movsbl 0x4(%rax),%eax
and    $0x3f,%eax
shl    $0x6,%eax
or     %eax,%ecx
mov    -0x10(%rbp),%rax
movsbl 0x5(%rax),%eax
and    $0x3f,%eax
shl    $0x0,%eax
or     %eax,%ecx
mov    -0x18(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x10(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x8(%rbp)
jmp    14a4 <__utf8_get_char+0x3a4>
mov    -0x10(%rbp),%rax
movsbl (%rax),%ecx
mov    -0x18(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<__utf8_get_char>:
mov    %rdi,%rax
movsbl (%rdi),%ecx
mov    %ecx,%edx
and    $0xe0,%edx
cmp    $0xc0,%edx
jne    1139 <__utf8_get_char+0x39>
movzbl 0x1(%rax),%edx
mov    %edx,%edi
and    $0xffffffc0,%edi
cmp    $0x80,%edi
jne    1139 <__utf8_get_char+0x39>
and    $0x1f,%ecx
shl    $0x6,%ecx
and    $0x3f,%edx
or     %ecx,%edx
mov    %edx,(%rsi)
add    $0x2,%rax
ret
mov    %ecx,%edx
and    $0xf0,%edx
cmp    $0xe0,%edx
jne    118d <__utf8_get_char+0x8d>
movsbl 0x1(%rax),%edx
mov    %edx,%edi
and    $0xc0,%edi
cmp    $0x80,%edi
jne    118d <__utf8_get_char+0x8d>
movzbl 0x2(%rax),%r8d
mov    %r8d,%edi
and    $0xffffffc0,%edi
cmp    $0x80,%edi
jne    118d <__utf8_get_char+0x8d>
shl    $0xc,%ecx
movzwl %cx,%ecx
and    $0x3f,%edx
shl    $0x6,%edx
or     %ecx,%edx
and    $0x3f,%r8d
or     %edx,%r8d
mov    %r8d,(%rsi)
add    $0x3,%rax
ret
mov    %ecx,%edx
and    $0xf8,%edx
cmp    $0xf0,%edx
jne    1207 <__utf8_get_char+0x107>
movsbl 0x1(%rax),%r10d
mov    %r10d,%edi
and    $0xc0,%edi
cmp    $0x80,%edi
jne    1207 <__utf8_get_char+0x107>
movsbl 0x2(%rax),%r8d
mov    %r8d,%edi
and    $0xc0,%edi
cmp    $0x80,%edi
jne    1207 <__utf8_get_char+0x107>
movzbl 0x3(%rax),%r9d
mov    %r9d,%edi
and    $0xffffffc0,%edi
cmp    $0x80,%edi
jne    1207 <__utf8_get_char+0x107>
and    $0x7,%ecx
shl    $0x12,%ecx
and    $0x3f,%r10d
shl    $0xc,%r10d
or     %ecx,%r10d
and    $0x3f,%r8d
shl    $0x6,%r8d
or     %r10d,%r8d
and    $0x3f,%r9d
or     %r8d,%r9d
mov    %r9d,(%rsi)
add    $0x4,%rax
ret
mov    %ecx,%edi
and    $0xfc,%edi
cmp    $0xf8,%edi
jne    12a6 <__utf8_get_char+0x1a6>
movsbl 0x1(%rax),%r11d
mov    %r11d,%edi
and    $0xc0,%edi
cmp    $0x80,%edi
jne    12a6 <__utf8_get_char+0x1a6>
movsbl 0x2(%rax),%r8d
mov    %r8d,%edi
and    $0xc0,%edi
cmp    $0x80,%edi
jne    12a6 <__utf8_get_char+0x1a6>
movsbl 0x3(%rax),%r9d
mov    %r9d,%edi
and    $0xc0,%edi
cmp    $0x80,%edi
jne    12a6 <__utf8_get_char+0x1a6>
movzbl 0x4(%rax),%r10d
mov    %r10d,%edi
and    $0xffffffc0,%edi
cmp    $0x80,%edi
jne    12a6 <__utf8_get_char+0x1a6>
and    $0x3,%ecx
shl    $0x18,%ecx
and    $0x3f,%r11d
shl    $0x12,%r11d
or     %ecx,%r11d
and    $0x3f,%r8d
shl    $0xc,%r8d
or     %r11d,%r8d
and    $0x3f,%r9d
shl    $0x6,%r9d
or     %r8d,%r9d
and    $0x3f,%r10d
or     %r9d,%r10d
mov    %r10d,(%rsi)
add    $0x5,%rax
ret
cmp    $0xf0,%edx
jne    135d <__utf8_get_char+0x25d>
movsbl 0x1(%rax),%edx
mov    %edx,%edi
and    $0xc0,%edi
cmp    $0x80,%edi
jne    135d <__utf8_get_char+0x25d>
movsbl 0x2(%rax),%r11d
mov    %r11d,%edi
and    $0xc0,%edi
cmp    $0x80,%edi
jne    135d <__utf8_get_char+0x25d>
movsbl 0x3(%rax),%r8d
mov    %r8d,%edi
and    $0xc0,%edi
cmp    $0x80,%edi
jne    135d <__utf8_get_char+0x25d>
movsbl 0x4(%rax),%r9d
mov    %r9d,%edi
and    $0xc0,%edi
cmp    $0x80,%edi
jne    135d <__utf8_get_char+0x25d>
movzbl 0x5(%rax),%r10d
mov    %r10d,%edi
and    $0xffffffc0,%edi
cmp    $0x80,%edi
jne    135d <__utf8_get_char+0x25d>
add    $0x4,%rax
and    $0x1,%ecx
shl    $0x1e,%ecx
and    $0x3f,%edx
shl    $0x18,%edx
or     %ecx,%edx
and    $0x3f,%r11d
shl    $0x12,%r11d
or     %edx,%r11d
and    $0x3f,%r8d
shl    $0xc,%r8d
or     %r11d,%r8d
and    $0x3f,%r9d
shl    $0x6,%r9d
or     %r8d,%r9d
and    $0x3f,%r10d
or     %r9d,%r10d
mov    %r10d,(%rsi)
ret
mov    %ecx,(%rsi)
add    $0x1,%rax
ret

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

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