unsigned long ILUTF8ReadChar(const void *_str, int len, int *posn) {
  const char *str = (const char *)_str;
  char ch = str[*posn];
  unsigned long result;
  if ((ch & 0x80) == 0) {
    ++(*posn);
    return (unsigned long)ch;
  } else if ((ch & (char)0xE0) == (char)0xC0 && (*posn + 2) <= len) {
    result = ((((unsigned long)(ch & 0x1F)) << 6) |
              ((unsigned long)(str[(*posn) + 1] & 0x3F)));
    (*posn) += 2;
    return result;
  } else if ((ch & (char)0xF0) == (char)0xE0 && (*posn + 3) <= len) {
    result = ((((unsigned long)(ch & 0x0F)) << 12) |
              (((unsigned long)(str[(*posn) + 1] & 0x3F)) << 6) |
              ((unsigned long)(str[(*posn) + 2] & 0x3F)));
    (*posn) += 3;
    return result;
  } else if ((ch & (char)0xF8) == (char)0xF0 && (*posn + 4) <= len) {
    result = ((((unsigned long)(ch & 0x07)) << 18) |
              (((unsigned long)(str[(*posn) + 1] & 0x3F)) << 12) |
              (((unsigned long)(str[(*posn) + 2] & 0x3F)) << 6) |
              ((unsigned long)(str[(*posn) + 3] & 0x3F)));
    (*posn) += 4;
    return result;
  } else if ((ch & (char)0xFC) == (char)0xF8 && (*posn + 5) <= len) {
    result = ((((unsigned long)(ch & 0x03)) << 24) |
              (((unsigned long)(str[(*posn) + 1] & 0x3F)) << 18) |
              (((unsigned long)(str[(*posn) + 2] & 0x3F)) << 12) |
              (((unsigned long)(str[(*posn) + 3] & 0x3F)) << 6) |
              ((unsigned long)(str[(*posn) + 4] & 0x3F)));
    (*posn) += 5;
    return result;
  } else if ((ch & (char)0xFC) == (char)0xFC && (*posn + 6) <= len) {
    result = ((((unsigned long)(ch & 0x03)) << 30) |
              (((unsigned long)(str[(*posn) + 1] & 0x3F)) << 24) |
              (((unsigned long)(str[(*posn) + 2] & 0x3F)) << 18) |
              (((unsigned long)(str[(*posn) + 3] & 0x3F)) << 12) |
              (((unsigned long)(str[(*posn) + 4] & 0x3F)) << 6) |
              ((unsigned long)(str[(*posn) + 5] & 0x3F)));
    (*posn) += 6;
    return result;
  } else {
    ++(*posn);
    return (((unsigned long)ch) & 0xFF);
  }
}


x86 assembly (clang, -O0):
<ILUTF8ReadChar>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    %rdx,-0x20(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rax
mov    -0x20(%rbp),%rcx
movslq (%rcx),%rcx
mov    (%rax,%rcx,1),%al
mov    %al,-0x29(%rbp)
movsbl -0x29(%rbp),%eax
and    $0x80,%eax
cmp    $0x0,%eax
jne    1153 <ILUTF8ReadChar+0x53>
mov    -0x20(%rbp),%rax
mov    (%rax),%ecx
add    $0x1,%ecx
mov    %ecx,(%rax)
movsbq -0x29(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    14bf <ILUTF8ReadChar+0x3bf>
movsbl -0x29(%rbp),%eax
and    $0xffffffe0,%eax
cmp    $0xffffffc0,%eax
jne    11bb <ILUTF8ReadChar+0xbb>
mov    -0x20(%rbp),%rax
mov    (%rax),%eax
add    $0x2,%eax
cmp    -0x14(%rbp),%eax
jg     11bb <ILUTF8ReadChar+0xbb>
movsbl -0x29(%rbp),%eax
and    $0x1f,%eax
cltq
shl    $0x6,%rax
mov    -0x28(%rbp),%rcx
mov    -0x20(%rbp),%rdx
mov    (%rdx),%edx
add    $0x1,%edx
movslq %edx,%rdx
movsbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
movslq %ecx,%rcx
or     %rcx,%rax
mov    %rax,-0x38(%rbp)
mov    -0x20(%rbp),%rax
mov    (%rax),%ecx
add    $0x2,%ecx
mov    %ecx,(%rax)
mov    -0x38(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    14bf <ILUTF8ReadChar+0x3bf>
movsbl -0x29(%rbp),%eax
and    $0xfffffff0,%eax
cmp    $0xffffffe0,%eax
jne    1244 <ILUTF8ReadChar+0x144>
mov    -0x20(%rbp),%rax
mov    (%rax),%eax
add    $0x3,%eax
cmp    -0x14(%rbp),%eax
jg     1244 <ILUTF8ReadChar+0x144>
movsbl -0x29(%rbp),%eax
and    $0xf,%eax
cltq
shl    $0xc,%rax
mov    -0x28(%rbp),%rcx
mov    -0x20(%rbp),%rdx
mov    (%rdx),%edx
add    $0x1,%edx
movslq %edx,%rdx
movsbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
movslq %ecx,%rcx
shl    $0x6,%rcx
or     %rcx,%rax
mov    -0x28(%rbp),%rcx
mov    -0x20(%rbp),%rdx
mov    (%rdx),%edx
add    $0x2,%edx
movslq %edx,%rdx
movsbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
movslq %ecx,%rcx
or     %rcx,%rax
mov    %rax,-0x38(%rbp)
mov    -0x20(%rbp),%rax
mov    (%rax),%ecx
add    $0x3,%ecx
mov    %ecx,(%rax)
mov    -0x38(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    14bf <ILUTF8ReadChar+0x3bf>
movsbl -0x29(%rbp),%eax
and    $0xfffffff8,%eax
cmp    $0xfffffff0,%eax
jne    12ee <ILUTF8ReadChar+0x1ee>
mov    -0x20(%rbp),%rax
mov    (%rax),%eax
add    $0x4,%eax
cmp    -0x14(%rbp),%eax
jg     12ee <ILUTF8ReadChar+0x1ee>
movsbl -0x29(%rbp),%eax
and    $0x7,%eax
cltq
shl    $0x12,%rax
mov    -0x28(%rbp),%rcx
mov    -0x20(%rbp),%rdx
mov    (%rdx),%edx
add    $0x1,%edx
movslq %edx,%rdx
movsbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
movslq %ecx,%rcx
shl    $0xc,%rcx
or     %rcx,%rax
mov    -0x28(%rbp),%rcx
mov    -0x20(%rbp),%rdx
mov    (%rdx),%edx
add    $0x2,%edx
movslq %edx,%rdx
movsbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
movslq %ecx,%rcx
shl    $0x6,%rcx
or     %rcx,%rax
mov    -0x28(%rbp),%rcx
mov    -0x20(%rbp),%rdx
mov    (%rdx),%edx
add    $0x3,%edx
movslq %edx,%rdx
movsbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
movslq %ecx,%rcx
or     %rcx,%rax
mov    %rax,-0x38(%rbp)
mov    -0x20(%rbp),%rax
mov    (%rax),%ecx
add    $0x4,%ecx
mov    %ecx,(%rax)
mov    -0x38(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    14bf <ILUTF8ReadChar+0x3bf>
movsbl -0x29(%rbp),%eax
and    $0xfffffffc,%eax
cmp    $0xfffffff8,%eax
jne    13b9 <ILUTF8ReadChar+0x2b9>
mov    -0x20(%rbp),%rax
mov    (%rax),%eax
add    $0x5,%eax
cmp    -0x14(%rbp),%eax
jg     13b9 <ILUTF8ReadChar+0x2b9>
movsbl -0x29(%rbp),%eax
and    $0x3,%eax
cltq
shl    $0x18,%rax
mov    -0x28(%rbp),%rcx
mov    -0x20(%rbp),%rdx
mov    (%rdx),%edx
add    $0x1,%edx
movslq %edx,%rdx
movsbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
movslq %ecx,%rcx
shl    $0x12,%rcx
or     %rcx,%rax
mov    -0x28(%rbp),%rcx
mov    -0x20(%rbp),%rdx
mov    (%rdx),%edx
add    $0x2,%edx
movslq %edx,%rdx
movsbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
movslq %ecx,%rcx
shl    $0xc,%rcx
or     %rcx,%rax
mov    -0x28(%rbp),%rcx
mov    -0x20(%rbp),%rdx
mov    (%rdx),%edx
add    $0x3,%edx
movslq %edx,%rdx
movsbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
movslq %ecx,%rcx
shl    $0x6,%rcx
or     %rcx,%rax
mov    -0x28(%rbp),%rcx
mov    -0x20(%rbp),%rdx
mov    (%rdx),%edx
add    $0x4,%edx
movslq %edx,%rdx
movsbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
movslq %ecx,%rcx
or     %rcx,%rax
mov    %rax,-0x38(%rbp)
mov    -0x20(%rbp),%rax
mov    (%rax),%ecx
add    $0x5,%ecx
mov    %ecx,(%rax)
mov    -0x38(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    14bf <ILUTF8ReadChar+0x3bf>
movsbl -0x29(%rbp),%eax
and    $0xfffffffc,%eax
cmp    $0xfffffffc,%eax
jne    14a5 <ILUTF8ReadChar+0x3a5>
mov    -0x20(%rbp),%rax
mov    (%rax),%eax
add    $0x6,%eax
cmp    -0x14(%rbp),%eax
jg     14a5 <ILUTF8ReadChar+0x3a5>
movsbl -0x29(%rbp),%eax
and    $0x3,%eax
cltq
shl    $0x1e,%rax
mov    -0x28(%rbp),%rcx
mov    -0x20(%rbp),%rdx
mov    (%rdx),%edx
add    $0x1,%edx
movslq %edx,%rdx
movsbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
movslq %ecx,%rcx
shl    $0x18,%rcx
or     %rcx,%rax
mov    -0x28(%rbp),%rcx
mov    -0x20(%rbp),%rdx
mov    (%rdx),%edx
add    $0x2,%edx
movslq %edx,%rdx
movsbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
movslq %ecx,%rcx
shl    $0x12,%rcx
or     %rcx,%rax
mov    -0x28(%rbp),%rcx
mov    -0x20(%rbp),%rdx
mov    (%rdx),%edx
add    $0x3,%edx
movslq %edx,%rdx
movsbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
movslq %ecx,%rcx
shl    $0xc,%rcx
or     %rcx,%rax
mov    -0x28(%rbp),%rcx
mov    -0x20(%rbp),%rdx
mov    (%rdx),%edx
add    $0x4,%edx
movslq %edx,%rdx
movsbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
movslq %ecx,%rcx
shl    $0x6,%rcx
or     %rcx,%rax
mov    -0x28(%rbp),%rcx
mov    -0x20(%rbp),%rdx
mov    (%rdx),%edx
add    $0x5,%edx
movslq %edx,%rdx
movsbl (%rcx,%rdx,1),%ecx
and    $0x3f,%ecx
movslq %ecx,%rcx
or     %rcx,%rax
mov    %rax,-0x38(%rbp)
mov    -0x20(%rbp),%rax
mov    (%rax),%ecx
add    $0x6,%ecx
mov    %ecx,(%rax)
mov    -0x38(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    14bf <ILUTF8ReadChar+0x3bf>
mov    -0x20(%rbp),%rax
mov    (%rax),%ecx
add    $0x1,%ecx
mov    %ecx,(%rax)
movsbq -0x29(%rbp),%rax
and    $0xff,%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<ILUTF8ReadChar>:
movslq (%rdx),%r8
movsbl (%rdi,%r8,1),%r10d
movslq %r10d,%rax
test   $0x80,%al
jne    1116 <ILUTF8ReadChar+0x16>
lea    0x1(%r8),%ecx
mov    %ecx,(%rdx)
ret
mov    %r10d,%ecx
and    $0xffffffe0,%ecx
cmp    $0xffffffc0,%ecx
jne    112a <ILUTF8ReadChar+0x2a>
lea    0x2(%r8),%r9d
cmp    %esi,%r9d
jle    1186 <ILUTF8ReadChar+0x86>
mov    %r10d,%ecx
and    $0xfffffff0,%ecx
cmp    $0xffffffe0,%ecx
jne    113e <ILUTF8ReadChar+0x3e>
lea    0x3(%r8),%r9d
cmp    %esi,%r9d
jle    119e <ILUTF8ReadChar+0x9e>
mov    %r10d,%ecx
and    $0xfffffff8,%ecx
cmp    $0xfffffff0,%ecx
jne    1152 <ILUTF8ReadChar+0x52>
lea    0x4(%r8),%r9d
cmp    %esi,%r9d
jle    11c1 <ILUTF8ReadChar+0xc1>
mov    %r10d,%ecx
and    $0xfffffffc,%ecx
cmp    $0xfffffff8,%ecx
jne    116a <ILUTF8ReadChar+0x6a>
lea    0x5(%r8),%r9d
cmp    %esi,%r9d
jle    11f4 <ILUTF8ReadChar+0xf4>
cmp    $0xfc,%al
jb     117b <ILUTF8ReadChar+0x7b>
lea    0x6(%r8),%r9d
cmp    %esi,%r9d
jle    123c <ILUTF8ReadChar+0x13c>
lea    0x1(%r8),%eax
mov    %eax,(%rdx)
movzbl %r10b,%eax
ret
and    $0x1f,%r10d
shl    $0x6,%r10d
movzbl 0x1(%r8,%rdi,1),%eax
and    $0x3f,%eax
or     %r10,%rax
mov    %r9d,(%rdx)
ret
shl    $0xc,%r10d
movzwl %r10w,%eax
movzbl 0x1(%r8,%rdi,1),%ecx
and    $0x3f,%ecx
shl    $0x6,%rcx
or     %rax,%rcx
movzbl 0x2(%r8,%rdi,1),%eax
jmp    1286 <ILUTF8ReadChar+0x186>
and    $0x7,%r10d
shl    $0x12,%r10d
movzbl 0x1(%r8,%rdi,1),%eax
and    $0x3f,%eax
shl    $0xc,%rax
or     %r10,%rax
movzbl 0x2(%r8,%rdi,1),%ecx
and    $0x3f,%ecx
shl    $0x6,%rcx
or     %rax,%rcx
movzbl 0x3(%r8,%rdi,1),%eax
jmp    1286 <ILUTF8ReadChar+0x186>
and    $0x3,%r10d
shl    $0x18,%r10d
movzbl 0x1(%r8,%rdi,1),%eax
and    $0x3f,%eax
shl    $0x12,%rax
or     %r10,%rax
movzbl 0x2(%r8,%rdi,1),%ecx
and    $0x3f,%ecx
shl    $0xc,%rcx
or     %rax,%rcx
movzbl 0x3(%r8,%rdi,1),%esi
and    $0x3f,%esi
shl    $0x6,%rsi
or     %rcx,%rsi
movzbl 0x4(%r8,%rdi,1),%eax
and    $0x3f,%eax
or     %rsi,%rax
mov    %r9d,(%rdx)
ret
shl    $0x1e,%r10d
movzbl 0x1(%r8,%rdi,1),%eax
and    $0x3f,%eax
shl    $0x18,%rax
or     %r10,%rax
movzbl 0x2(%r8,%rdi,1),%ecx
and    $0x3f,%ecx
shl    $0x12,%rcx
or     %rax,%rcx
movzbl 0x3(%r8,%rdi,1),%eax
and    $0x3f,%eax
shl    $0xc,%rax
or     %rcx,%rax
movzbl 0x4(%r8,%rdi,1),%ecx
and    $0x3f,%ecx
shl    $0x6,%rcx
or     %rax,%rcx
movzbl 0x5(%r8,%rdi,1),%eax
and    $0x3f,%eax
or     %rcx,%rax
mov    %r9d,(%rdx)
ret

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

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