int UTF8_getc(const unsigned char *str, int len, unsigned long *val) {
  const unsigned char *p;
  unsigned long value;
  int ret;
  if (len <= 0)
    return 0;
  p = str;
  if ((*p & 0x80) == 0) {
    value = *p++ & 0x7f;
    ret = 1;
  } else if ((*p & 0xe0) == 0xc0) {
    if (*p < 0xc2)
      return -2;
    if (len < 2)
      return -1;
    if ((p[1] & 0xc0) != 0x80)
      return -3;
    value = (*p++ & 0x1f) << 6;
    value |= *p++ & 0x3f;
    if (value < 0x80)
      return -4;
    ret = 2;
  } else if ((*p & 0xf0) == 0xe0) {
    if (len < 3)
      return -1;
    if (((p[1] & 0xc0) != 0x80) || ((p[2] & 0xc0) != 0x80))
      return -3;
    value = (*p++ & 0xf) << 12;
    value |= (*p++ & 0x3f) << 6;
    value |= *p++ & 0x3f;
    if (value < 0x800)
      return -4;
    if (value >= 0xd800 && value < 0xe000)
      return -2;
    ret = 3;
  } else if ((*p & 0xf8) == 0xf0 && (*p < 0xf5)) {
    if (len < 4)
      return -1;
    if (((p[1] & 0xc0) != 0x80) || ((p[2] & 0xc0) != 0x80) ||
        ((p[3] & 0xc0) != 0x80))
      return -3;
    value = ((unsigned long)(*p++ & 0x7)) << 18;
    value |= (*p++ & 0x3f) << 12;
    value |= (*p++ & 0x3f) << 6;
    value |= *p++ & 0x3f;
    if (value < 0x10000)
      return -4;
    if (value > 0x10FFFF)
      return -2;
    ret = 4;
  } else
    return -2;
  *val = value;
  return ret;
}


x86 assembly (clang, -O0):
<UTF8_getc>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    %rdx,-0x20(%rbp)
cmpl   $0x0,-0x14(%rbp)
jg     1125 <UTF8_getc+0x25>
movl   $0x0,-0x4(%rbp)
jmp    14d2 <UTF8_getc+0x3d2>
mov    -0x10(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rax
movzbl (%rax),%eax
and    $0x80,%eax
cmp    $0x0,%eax
jne    1169 <UTF8_getc+0x69>
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x28(%rbp)
movzbl (%rax),%eax
and    $0x7f,%eax
cltq
mov    %rax,-0x30(%rbp)
movl   $0x1,-0x34(%rbp)
jmp    14c1 <UTF8_getc+0x3c1>
mov    -0x28(%rbp),%rax
movzbl (%rax),%eax
and    $0xe0,%eax
cmp    $0xc0,%eax
jne    123b <UTF8_getc+0x13b>
mov    -0x28(%rbp),%rax
movzbl (%rax),%eax
cmp    $0xc2,%eax
jge    119e <UTF8_getc+0x9e>
movl   $0xfffffffe,-0x4(%rbp)
jmp    14d2 <UTF8_getc+0x3d2>
cmpl   $0x2,-0x14(%rbp)
jge    11b4 <UTF8_getc+0xb4>
movl   $0xffffffff,-0x4(%rbp)
jmp    14d2 <UTF8_getc+0x3d2>
mov    -0x28(%rbp),%rax
movzbl 0x1(%rax),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
je     11d8 <UTF8_getc+0xd8>
movl   $0xfffffffd,-0x4(%rbp)
jmp    14d2 <UTF8_getc+0x3d2>
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x28(%rbp)
movzbl (%rax),%eax
and    $0x1f,%eax
shl    $0x6,%eax
cltq
mov    %rax,-0x30(%rbp)
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x28(%rbp)
movzbl (%rax),%eax
and    $0x3f,%eax
cltq
or     -0x30(%rbp),%rax
mov    %rax,-0x30(%rbp)
cmpq   $0x80,-0x30(%rbp)
jae    122f <UTF8_getc+0x12f>
movl   $0xfffffffc,-0x4(%rbp)
jmp    14d2 <UTF8_getc+0x3d2>
movl   $0x2,-0x34(%rbp)
jmp    14bc <UTF8_getc+0x3bc>
mov    -0x28(%rbp),%rax
movzbl (%rax),%eax
and    $0xf0,%eax
cmp    $0xe0,%eax
jne    1351 <UTF8_getc+0x251>
cmpl   $0x3,-0x14(%rbp)
jge    1268 <UTF8_getc+0x168>
movl   $0xffffffff,-0x4(%rbp)
jmp    14d2 <UTF8_getc+0x3d2>
mov    -0x28(%rbp),%rax
movzbl 0x1(%rax),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    1298 <UTF8_getc+0x198>
mov    -0x28(%rbp),%rax
movzbl 0x2(%rax),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
je     12a4 <UTF8_getc+0x1a4>
movl   $0xfffffffd,-0x4(%rbp)
jmp    14d2 <UTF8_getc+0x3d2>
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x28(%rbp)
movzbl (%rax),%eax
and    $0xf,%eax
shl    $0xc,%eax
cltq
mov    %rax,-0x30(%rbp)
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x28(%rbp)
movzbl (%rax),%eax
and    $0x3f,%eax
shl    $0x6,%eax
cltq
or     -0x30(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x28(%rbp)
movzbl (%rax),%eax
and    $0x3f,%eax
cltq
or     -0x30(%rbp),%rax
mov    %rax,-0x30(%rbp)
cmpq   $0x800,-0x30(%rbp)
jae    131d <UTF8_getc+0x21d>
movl   $0xfffffffc,-0x4(%rbp)
jmp    14d2 <UTF8_getc+0x3d2>
cmpq   $0xd800,-0x30(%rbp)
jb     1345 <UTF8_getc+0x245>
cmpq   $0xe000,-0x30(%rbp)
jae    1345 <UTF8_getc+0x245>
movl   $0xfffffffe,-0x4(%rbp)
jmp    14d2 <UTF8_getc+0x3d2>
movl   $0x3,-0x34(%rbp)
jmp    14b7 <UTF8_getc+0x3b7>
mov    -0x28(%rbp),%rax
movzbl (%rax),%eax
and    $0xf8,%eax
cmp    $0xf0,%eax
jne    14a6 <UTF8_getc+0x3a6>
mov    -0x28(%rbp),%rax
movzbl (%rax),%eax
cmp    $0xf5,%eax
jge    14a6 <UTF8_getc+0x3a6>
cmpl   $0x4,-0x14(%rbp)
jge    1390 <UTF8_getc+0x290>
movl   $0xffffffff,-0x4(%rbp)
jmp    14d2 <UTF8_getc+0x3d2>
mov    -0x28(%rbp),%rax
movzbl 0x1(%rax),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    13d8 <UTF8_getc+0x2d8>
mov    -0x28(%rbp),%rax
movzbl 0x2(%rax),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    13d8 <UTF8_getc+0x2d8>
mov    -0x28(%rbp),%rax
movzbl 0x3(%rax),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
je     13e4 <UTF8_getc+0x2e4>
movl   $0xfffffffd,-0x4(%rbp)
jmp    14d2 <UTF8_getc+0x3d2>
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x28(%rbp)
movzbl (%rax),%eax
and    $0x7,%eax
cltq
shl    $0x12,%rax
mov    %rax,-0x30(%rbp)
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x28(%rbp)
movzbl (%rax),%eax
and    $0x3f,%eax
shl    $0xc,%eax
cltq
or     -0x30(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x28(%rbp)
movzbl (%rax),%eax
and    $0x3f,%eax
shl    $0x6,%eax
cltq
or     -0x30(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x28(%rbp)
movzbl (%rax),%eax
and    $0x3f,%eax
cltq
or     -0x30(%rbp),%rax
mov    %rax,-0x30(%rbp)
cmpq   $0x10000,-0x30(%rbp)
jae    1480 <UTF8_getc+0x380>
movl   $0xfffffffc,-0x4(%rbp)
jmp    14d2 <UTF8_getc+0x3d2>
cmpq   $0x10ffff,-0x30(%rbp)
jbe    149a <UTF8_getc+0x39a>
movl   $0xfffffffe,-0x4(%rbp)
jmp    14d2 <UTF8_getc+0x3d2>
movl   $0x4,-0x34(%rbp)
jmp    14b2 <UTF8_getc+0x3b2>
movl   $0xfffffffe,-0x4(%rbp)
jmp    14d2 <UTF8_getc+0x3d2>
jmp    14b7 <UTF8_getc+0x3b7>
jmp    14bc <UTF8_getc+0x3bc>
jmp    14c1 <UTF8_getc+0x3c1>
mov    -0x30(%rbp),%rcx
mov    -0x20(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x34(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<UTF8_getc>:
test   %esi,%esi
jle    1120 <UTF8_getc+0x20>
movzbl (%rdi),%r10d
test   $0x80,%r10b
jne    1123 <UTF8_getc+0x23>
and    $0x7f,%r10d
mov    $0x1,%edi
mov    %r10,%rsi
mov    %rsi,(%rdx)
mov    %edi,%eax
ret
xor    %eax,%eax
ret
mov    %r10d,%eax
and    $0xffffffe0,%eax
cmp    $0xc0,%eax
jne    117d <UTF8_getc+0x7d>
mov    $0xfffffffe,%eax
cmp    $0xc2,%r10b
jb     111f <UTF8_getc+0x1f>
mov    $0xffffffff,%eax
cmp    $0x2,%esi
jb     111f <UTF8_getc+0x1f>
movzbl 0x1(%rdi),%esi
mov    %esi,%edi
and    $0xc0,%dil
mov    $0xfffffffd,%eax
cmp    $0x80,%dil
jne    111f <UTF8_getc+0x1f>
and    $0x1f,%r10d
shl    $0x6,%r10
and    $0x3f,%esi
or     %r10,%rsi
mov    $0x2,%edi
mov    $0xfffffffc,%eax
cmp    $0x80,%rsi
jae    111a <UTF8_getc+0x1a>
jmp    111f <UTF8_getc+0x1f>
mov    %r10d,%eax
and    $0xfffffff0,%eax
cmp    $0xe0,%eax
jne    1213 <UTF8_getc+0x113>
mov    $0xffffffff,%eax
cmp    $0x3,%esi
jb     111f <UTF8_getc+0x1f>
movzbl 0x1(%rdi),%r8d
mov    %r8d,%esi
and    $0xc0,%sil
mov    $0xfffffffd,%eax
cmp    $0x80,%sil
jne    111f <UTF8_getc+0x1f>
movzbl 0x2(%rdi),%esi
mov    %esi,%ecx
and    $0xc0,%cl
cmp    $0x80,%cl
jne    111f <UTF8_getc+0x1f>
shl    $0xc,%r10d
movzwl %r10w,%eax
and    $0x3f,%r8d
shl    $0x6,%r8
or     %rax,%r8
and    $0x3f,%esi
or     %r8,%rsi
mov    $0xfffffffc,%eax
cmp    $0x800,%rsi
jb     111f <UTF8_getc+0x1f>
and    $0xf800,%r8d
mov    $0x3,%edi
mov    $0xfffffffe,%eax
cmp    $0xd800,%r8d
jne    111a <UTF8_getc+0x1a>
jmp    111f <UTF8_getc+0x1f>
mov    %r10d,%ecx
and    $0xfffffff8,%ecx
mov    $0xfffffffe,%eax
cmp    $0xf0,%ecx
jne    111f <UTF8_getc+0x1f>
cmp    $0xf4,%r10b
ja     111f <UTF8_getc+0x1f>
mov    $0xffffffff,%eax
cmp    $0x4,%esi
jb     111f <UTF8_getc+0x1f>
movzbl 0x1(%rdi),%r8d
mov    %r8d,%ecx
and    $0xc0,%cl
mov    $0xfffffffd,%eax
cmp    $0x80,%cl
jne    111f <UTF8_getc+0x1f>
movzbl 0x2(%rdi),%r9d
mov    %r9d,%ecx
and    $0xc0,%cl
cmp    $0x80,%cl
jne    111f <UTF8_getc+0x1f>
movzbl 0x3(%rdi),%esi
mov    %esi,%ecx
and    $0xc0,%cl
cmp    $0x80,%cl
jne    111f <UTF8_getc+0x1f>
and    $0x7,%r10d
shl    $0x12,%r10
and    $0x3f,%r8d
shl    $0xc,%r8
or     %r10,%r8
and    $0x3f,%r9d
shl    $0x6,%r9
or     %r8,%r9
and    $0x3f,%esi
or     %r9,%rsi
mov    $0xfffffffc,%eax
cmp    $0x10000,%rsi
jb     111f <UTF8_getc+0x1f>
mov    $0x4,%edi
mov    $0xfffffffe,%eax
cmp    $0x10ffff,%esi
jbe    111a <UTF8_getc+0x1a>
jmp    111f <UTF8_getc+0x1f>

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

LLVM IR (-O2):
define i32 @UTF8_getc(i8* nocapture %0, i32 %1, i64* nocapture writeonly %2) {
%4 = icmp slt i32 %1, 1
br i1 %4, label %106, label %5
5: ; preds = %3
%6 = load i8, i8* %0
%7 = zext i8 %6 to i32
%8 = and i32 %7, 128
%9 = icmp eq i32 %8, 0
br i1 %9, label %10, label %13
10: ; preds = %5
%11 = and i32 %7, 127
%12 = zext i32 %11 to i64
br label %103
13: ; preds = %5
%14 = and i32 %7, 224
%15 = icmp eq i32 %14, 192
br i1 %15, label %16, label %33
16: ; preds = %13
%17 = icmp ult i8 %6, -62
br i1 %17, label %106, label %18
18: ; preds = %16
%19 = icmp ult i32 %1, 2
br i1 %19, label %106, label %20
20: ; preds = %18
%21 = getelementptr inbounds i8, i8* %0, i64 1
%22 = load i8, i8* %21
%23 = and i8 %22, -64
%24 = icmp eq i8 %23, -128
br i1 %24, label %25, label %106
25: ; preds = %20
%26 = shl nuw nsw i32 %7, 6
%27 = and i32 %26, 1984
%28 = zext i32 %27 to i64
%29 = and i8 %22, 63
%30 = zext i8 %29 to i64
%31 = or i64 %30, %28
%32 = icmp ult i64 %31, 128
br i1 %32, label %106, label %103
33: ; preds = %13
%34 = and i32 %7, 240
%35 = icmp eq i32 %34, 224
br i1 %35, label %36, label %63
36: ; preds = %33
%37 = icmp ult i32 %1, 3
br i1 %37, label %106, label %38
38: ; preds = %36
%39 = getelementptr inbounds i8, i8* %0, i64 1
%40 = load i8, i8* %39
%41 = and i8 %40, -64
%42 = icmp eq i8 %41, -128
br i1 %42, label %43, label %106
43: ; preds = %38
%44 = getelementptr inbounds i8, i8* %0, i64 2
%45 = load i8, i8* %44
%46 = and i8 %45, -64
%47 = icmp eq i8 %46, -128
br i1 %47, label %48, label %106
48: ; preds = %43
%49 = shl nuw nsw i32 %7, 12
%50 = and i32 %49, 61440
%51 = zext i32 %50 to i64
%52 = and i8 %40, 63
%53 = zext i8 %52 to i64
%54 = shl nuw nsw i64 %53, 6
%55 = or i64 %54, %51
%56 = and i8 %45, 63
%57 = zext i8 %56 to i64
%58 = or i64 %55, %57
%59 = icmp ult i64 %58, 2048
br i1 %59, label %106, label %60
60: ; preds = %48
%61 = and i64 %55, 63488
%62 = icmp eq i64 %61, 55296
br i1 %62, label %106, label %103
63: ; preds = %33
%64 = and i32 %7, 248
%65 = icmp eq i32 %64, 240
%66 = icmp ult i8 %6, -11
%67 = select i1 %65, i1 %66, i1 false
br i1 %67, label %68, label %106
68: ; preds = %63
%69 = icmp ult i32 %1, 4
br i1 %69, label %106, label %70
70: ; preds = %68
%71 = getelementptr inbounds i8, i8* %0, i64 1
%72 = load i8, i8* %71
%73 = and i8 %72, -64
%74 = icmp eq i8 %73, -128
br i1 %74, label %75, label %106
75: ; preds = %70
%76 = getelementptr inbounds i8, i8* %0, i64 2
%77 = load i8, i8* %76
%78 = and i8 %77, -64
%79 = icmp eq i8 %78, -128
br i1 %79, label %80, label %106
80: ; preds = %75
%81 = getelementptr inbounds i8, i8* %0, i64 3
%82 = load i8, i8* %81
%83 = and i8 %82, -64
%84 = icmp eq i8 %83, -128
br i1 %84, label %85, label %106
85: ; preds = %80
%86 = shl nuw nsw i32 %7, 18
%87 = and i32 %86, 1835008
%88 = zext i32 %87 to i64
%89 = and i8 %72, 63
%90 = zext i8 %89 to i64
%91 = shl nuw nsw i64 %90, 12
%92 = or i64 %91, %88
%93 = and i8 %77, 63
%94 = zext i8 %93 to i64
%95 = shl nuw nsw i64 %94, 6
%96 = or i64 %95, %92
%97 = and i8 %82, 63
%98 = zext i8 %97 to i64
%99 = or i64 %96, %98
%100 = icmp ult i64 %99, 65536
br i1 %100, label %106, label %101
101: ; preds = %85
%102 = icmp ugt i64 %99, 1114111
br i1 %102, label %106, label %103
103: ; preds = %101, %60, %25, %10
%104 = phi i64 [ %12, %10 ], [ %31, %25 ], [ %58, %60 ], [ %99, %101 ]
%105 = phi i32 [ 1, %10 ], [ 2, %25 ], [ 3, %60 ], [ 4, %101 ]
store i64 %104, i64* %2
br label %106
106: ; preds = %63, %101, %85, %70, %75, %80, %68, %60, %48, %38, %43, %36, %25, %20, %18, %16, %3, %103
%107 = phi i32 [ %105, %103 ], [ 0, %3 ], [ -2, %16 ], [ -1, %18 ], [ -3, %20 ], [ -4, %25 ], [ -1, %36 ], [ -3, %43 ], [ -3, %38 ], [ -4, %48 ], [ -2, %60 ], [ -1, %68 ], [ -3, %80 ], [ -3, %75 ], [ -3, %70 ], [ -4, %85 ], [ -2, %101 ], [ -2, %63 ]
ret i32 %107
}